diff --git a/.dockerignore b/.dockerignore index 4a19eb9c3f..1f261adf30 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,6 +16,9 @@ *.so *.a +venv/ +.venv/ + notebooks phone massivemap diff --git a/.github/workflows/badges.yaml b/.github/workflows/badges.yaml index 16edb45c21..581c88be15 100644 --- a/.github/workflows/badges.yaml +++ b/.github/workflows/badges.yaml @@ -7,7 +7,7 @@ on: env: BASE_IMAGE: openpilot-base DOCKER_REGISTRY: ghcr.io/commaai - RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/sh -c + RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v ~/scons_cache:/tmp/scons_cache -v ~/comma_download_cache:/tmp/comma_download_cache -v ~/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/sh -c jobs: badges: diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index c45ebd1bee..65e10e61ed 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -11,6 +11,8 @@ concurrency: cancel-in-progress: true env: + PYTHONWARNINGS: error + BASE_IMAGE: openpilot-base CL_BASE_IMAGE: openpilot-base-cl DOCKER_REGISTRY: ghcr.io/commaai @@ -20,11 +22,11 @@ env: BUILD: | DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . - RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c + RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v ~/scons_cache:/tmp/scons_cache -v ~/comma_download_cache:/tmp/comma_download_cache -v ~/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c BUILD_CL: | DOCKER_BUILDKIT=1 docker build --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $CL_BASE_IMAGE:latest -f Dockerfile.openpilot_base_cl . - RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c + RUN_CL: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONWARNINGS=error -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v ~/scons_cache:/tmp/scons_cache -v ~/comma_download_cache:/tmp/comma_download_cache -v ~/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c UNIT_TEST: coverage run --append -m unittest discover @@ -47,7 +49,7 @@ jobs: timeout-minutes: 1 run: release/check-submodules.sh - name: Build openpilot and run checks - timeout-minutes: 10 + timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache run: | cd $STRIPPED_DIR ${{ env.RUN }} "CI=1 python selfdrive/manager/build.py" @@ -66,7 +68,7 @@ jobs: cp pyproject.toml $STRIPPED_DIR cp poetry.lock $STRIPPED_DIR cd $STRIPPED_DIR - ${{ env.RUN }} "pre-commit run --all" + ${{ env.RUN }} "unset PYTHONWARNINGS && pre-commit run --all" build_all: name: build all @@ -76,16 +78,20 @@ jobs: with: submodules: true - uses: ./.github/workflows/setup - with: - save-cache: true - name: Build openpilot with all flags - timeout-minutes: 12 + timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 12 || 30) }} # allow more time when we missed the scons cache run: ${{ env.RUN }} "scons -j$(nproc) --extras && release/check-dirty.sh" - - name: Cleanup scons cache - timeout-minutes: 2 + - name: Cleanup scons cache and rebuild + timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 2 || 30) }} # allow more time when we missed the scons cache run: | ${{ env.RUN }} "rm -rf /tmp/scons_cache/* && \ scons -j$(nproc) --cache-populate" + - name: Save scons cache + uses: actions/cache/save@v3 + if: github.ref == 'refs/heads/master' + with: + path: ~/scons_cache + key: scons-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} build_mac: name: build macos @@ -122,7 +128,7 @@ jobs: /opt/homebrew/opt /opt/homebrew/Caskroom/gcc-arm-* /Applications/ArmGNUToolchain/*/*/* - key: macos_deps-${{ hashFiles('tools/mac_setup.sh', 'update_requirements.sh', 'poetry.lock') }} + key: macos_deps-${{ hashFiles('tools/mac_setup.sh', 'tools/install_python_dependencies.sh', 'poetry.lock') }} restore-keys: macos_deps- - name: Brew link restored dependencies run: | @@ -138,6 +144,9 @@ jobs: - name: Install dependencies if: steps.dependency-cache.outputs.cache-hit != 'true' run: ./tools/mac_setup.sh + env: + # package install has DeprecationWarnings + PYTHONWARNINGS: default - name: Build openpilot run: | source tools/openpilot_env.sh @@ -164,8 +173,9 @@ jobs: if: steps.dependency-cache.outputs.cache-hit != 'true' run: | new_cellar=$(brew list --formula -1) + exceptions="zstd lz4 xz" # caching step needs zstd comm -12 <(echo "$EXISTING_CELLAR") <(echo "$new_cellar") | while read pkg; do - if [[ $pkg != "zstd" ]]; then # caching step needs zstd + if [[ " $exceptions " != *" $pkg "* ]]; then rm -rf "$(brew --cellar)/$pkg" fi done @@ -210,7 +220,7 @@ jobs: run: eval "$BUILD" - name: pre-commit timeout-minutes: 4 - run: ${{ env.RUN }} "pre-commit run --all" + run: ${{ env.RUN }} "unset PYTHONWARNINGS && pre-commit run --all" valgrind: name: valgrind @@ -239,7 +249,7 @@ jobs: submodules: true - uses: ./.github/workflows/setup - name: Build openpilot - timeout-minutes: 10 + timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache run: ${{ env.RUN }} "scons -j$(nproc)" - name: Run unit tests timeout-minutes: 40 @@ -290,7 +300,7 @@ jobs: id: dependency-cache uses: actions/cache@v3 with: - path: /tmp/comma_download_cache + path: ~/comma_download_cache key: proc-replay-${{ hashFiles('.github/workflows/selfdrive_tests.yaml', 'selfdrive/test/process_replay/ref_commit') }} - name: Build openpilot run: | @@ -333,15 +343,18 @@ jobs: - name: Build openpilot run: | ${{ env.RUN }} "scons -j$(nproc)" + # PYTHONWARNINGS triggers a SyntaxError in onnxruntime - name: Run model replay with ONNX timeout-minutes: 2 run: | - ${{ env.RUN_CL }} "ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \ + ${{ env.RUN_CL }} "unset PYTHONWARNINGS && \ + ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \ coverage xml" - name: Run unit tests timeout-minutes: 4 run: | - ${{ env.RUN_CL }} "$UNIT_TEST selfdrive/modeld && \ + ${{ env.RUN_CL }} "unset PYTHONWARNINGS && \ + $UNIT_TEST selfdrive/modeld && \ coverage xml" - name: "Upload coverage to Codecov" uses: codecov/codecov-action@v3 @@ -362,7 +375,7 @@ jobs: id: dependency-cache uses: actions/cache@v3 with: - path: /tmp/comma_download_cache + path: ~/comma_download_cache key: car_models-${{ hashFiles('selfdrive/car/tests/test_models.py', 'selfdrive/car/tests/routes.py') }}-${{ matrix.job }} - name: Build openpilot run: ${{ env.RUN }} "scons -j$(nproc)" diff --git a/.github/workflows/setup/action.yaml b/.github/workflows/setup/action.yaml index 186a9d9095..a6c58aae08 100644 --- a/.github/workflows/setup/action.yaml +++ b/.github/workflows/setup/action.yaml @@ -1,15 +1,17 @@ name: 'openpilot env setup' inputs: - save-cache: - default: false + git_lfs: + description: 'Whether or not to pull the git lfs' required: false + default: 'true' runs: using: "composite" steps: # do this after checkout to ensure our custom LFS config is used to pull from GitLab - shell: bash + if: ${{ inputs.git_lfs == 'true' }} run: git lfs pull # build cache @@ -18,15 +20,10 @@ runs: run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV - shell: bash run: echo "$CACHE_COMMIT_DATE" - - shell: bash - run: echo "CACHE_SKIP_SAVE=true" >> $GITHUB_ENV - if: github.ref != 'refs/heads/master' || inputs.save-cache == 'false' - - id: scons-cache - # TODO: change the version to the released version - # when https://github.com/actions/cache/pull/489 (or 571) is merged. - uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b + - id: restore-scons-cache + uses: actions/cache/restore@v3 with: - path: /tmp/scons_cache + path: ~/scons_cache key: scons-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }} restore-keys: | scons-${{ env.CACHE_COMMIT_DATE }}- diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index e1311db87c..e0d471882f 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -19,11 +19,11 @@ env: BUILD: | DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $DOCKER_REGISTRY/$BASE_IMAGE:latest -t $BASE_IMAGE:latest -f Dockerfile.openpilot_base . - RUN: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c + RUN: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v ~/scons_cache:/tmp/scons_cache -v ~/comma_download_cache:/tmp/comma_download_cache -v ~/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/sh -c BUILD_CL: | DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $DOCKER_REGISTRY/$CL_BASE_IMAGE:latest -t $CL_BASE_IMAGE:latest -f Dockerfile.openpilot_base_cl . - RUN_CL: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v /tmp/scons_cache:/tmp/scons_cache -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c + RUN_CL: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v ~/scons_cache:/tmp/scons_cache -v ~/comma_download_cache:/tmp/comma_download_cache -v ~/openpilot_cache:/tmp/openpilot_cache $CL_BASE_IMAGE /bin/sh -c jobs: @@ -57,10 +57,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: true - - name: Pull LFS - run: git lfs pull - - name: Build base image - run: eval "$BUILD" + - uses: ./.github/workflows/setup - name: Build base cl image run: eval "$BUILD_CL" - name: Build simulator image @@ -75,15 +72,20 @@ jobs: name: build docs runs-on: ubuntu-20.04 timeout-minutes: 45 + env: + BUILD: | + DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/openpilot-docs-base:latest -t $DOCKER_REGISTRY/openpilot-docs-base:latest -f docs/docker/Dockerfile --target openpilot-docs-base . + DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/openpilot-docs-base:latest --cache-from $DOCKER_REGISTRY/openpilot-docs:latest -t $DOCKER_REGISTRY/openpilot-docs:latest -f docs/docker/Dockerfile . steps: - uses: actions/checkout@v3 with: submodules: true - - name: Build docker container - run: | - DOCKER_BUILDKIT=1 docker build --pull --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $DOCKER_REGISTRY/openpilot-docs:latest -t $DOCKER_REGISTRY/openpilot-docs:latest -f docs/docker/Dockerfile . + - uses: ./.github/workflows/setup + with: + git_lfs: false - name: Push docker container if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot' run: | $DOCKER_LOGIN - docker push $DOCKER_REGISTRY/openpilot-docs:latest + docker push $DOCKER_REGISTRY/openpilot-docs-base:latest + docker push $DOCKER_REGISTRY/openpilot-docs:latest \ No newline at end of file diff --git a/.gitignore b/.gitignore index 91aecd9a72..004c0a6441 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ venv/ +.venv/ .env .clang-format .DS_Store .tags .ipynb_checkpoints .idea +.moc_files .overlay_init .overlay_consistent .sconsign.dblite @@ -56,7 +58,6 @@ selfdrive/modeld/_dmonitoringmodeld /src/ one -openpilot notebooks xx yy @@ -85,3 +86,4 @@ build/ !**/.gitkeep poetry.toml +Pipfile diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e1891372ac..b777bc4368 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,7 +35,7 @@ repos: args: ['--explicit-package-bases'] exclude: '^(third_party/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)' - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.282 + rev: v0.0.284 hooks: - id: ruff exclude: '^(third_party/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)' diff --git a/Dockerfile.openpilot_base b/Dockerfile.openpilot_base index 9af628bd4c..f8b20be351 100644 --- a/Dockerfile.openpilot_base +++ b/Dockerfile.openpilot_base @@ -17,8 +17,8 @@ ENV PYENV_VERSION=3.11.4 ENV PYENV_ROOT="/root/.pyenv" ENV PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH" -COPY pyproject.toml poetry.lock .python-version update_requirements.sh /tmp/ -COPY tools/ubuntu_setup.sh /tmp/tools/ +COPY pyproject.toml poetry.lock .python-version /tmp/ +COPY tools/ubuntu_setup.sh tools/install_python_dependencies.sh /tmp/tools/ RUN cd /tmp && \ tools/ubuntu_setup.sh && \ rm -rf /var/lib/apt/lists/* && \ diff --git a/Jenkinsfile b/Jenkinsfile index 6a834288c2..a698cc68cc 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,6 +6,7 @@ ssh -tt -o StrictHostKeyChecking=no -i ${key_file} 'comma@${ip}' /usr/bin/bash < set -e export CI=1 +export PYTHONWARNINGS=error export LOGPRINT=debug export TEST_DIR=${env.TEST_DIR} export SOURCE_DIR=${env.SOURCE_DIR} @@ -65,6 +66,7 @@ pipeline { agent none environment { CI = "1" + PYTHONWARNINGS = "error" TEST_DIR = "/data/openpilot" SOURCE_DIR = "/data/openpilot_source/" AZURE_TOKEN = credentials('azure_token') @@ -154,9 +156,10 @@ pipeline { sh "git config --global --add safe.directory '*'" sh "git submodule update --init --depth=1 --recursive" sh "git lfs pull" - sh "scons --clean && scons --no-cache -j42" + // tests that our build system's dependencies are configured properly, needs a machine with lots of cores sh "scons --clean && scons --no-cache --random -j42" - sh "INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt FILEREADER_CACHE=1 pytest -n42 --dist=loadscope selfdrive/car/tests/test_models.py" + sh "INTERNAL_SEG_CNT=500 INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt FILEREADER_CACHE=1 \ + pytest -n42 --dist=loadscope selfdrive/car/tests/test_models.py" } post { @@ -217,7 +220,6 @@ pipeline { ["build", "cd selfdrive/manager && ./build.py"], ["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], ["test power draw", "pytest system/hardware/tici/tests/test_power_draw.py"], - ["test loggerd", "pytest system/loggerd/tests/test_loggerd.py"], ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], ["test pigeond", "pytest system/sensord/tests/test_pigeond.py"], ["test manager", "pytest selfdrive/manager/test/test_manager.py"], diff --git a/SConstruct b/SConstruct index accfcab564..e384e31d94 100644 --- a/SConstruct +++ b/SConstruct @@ -1,4 +1,5 @@ import os +import shutil import subprocess import sys import sysconfig @@ -80,7 +81,7 @@ assert arch in ["larch64", "aarch64", "x86_64", "Darwin"] lenv = { "PATH": os.environ['PATH'], "LD_LIBRARY_PATH": [Dir(f"#third_party/acados/{arch}/lib").abspath], - "PYTHONPATH": Dir("#").abspath, + "PYTHONPATH": Dir("#").abspath + ':' + Dir(f"#third_party/acados").abspath, "ACADOS_SOURCE_DIR": Dir("#third_party/acados").abspath, "ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath, @@ -334,7 +335,18 @@ qt_flags = [ qt_env['CXXFLAGS'] += qt_flags qt_env['LIBPATH'] += ['#selfdrive/ui'] qt_env['LIBS'] = qt_libs -qt_env['QT_MOCHPREFIX'] = cache_dir + '/moc_files/moc_' + +# Have to respect cache-readonly +if GetOption('cache_readonly'): + local_moc_files_dir = Dir("#.moc_files").abspath + cache_moc_files_dir = cache_dir + "/moc_files" + if os.path.exists(local_moc_files_dir): + shutil.rmtree(local_moc_files_dir) + if os.path.exists(cache_moc_files_dir): + shutil.copytree(cache_moc_files_dir, local_moc_files_dir) + qt_env['QT3_MOCHPREFIX'] = local_moc_files_dir + "/moc_" +else: + qt_env['QT3_MOCHPREFIX'] = cache_dir + '/moc_files/moc_' if GetOption("clazy"): checks = [ @@ -437,7 +449,7 @@ SConscript(['selfdrive/navd/SConscript']) SConscript(['selfdrive/modeld/SConscript']) SConscript(['selfdrive/ui/SConscript']) -if (arch in ['x86_64', 'Darwin'] and Dir('#tools/cabana/').exists()) or GetOption('extras'): +if (arch in ['x86_64', 'aarch64', 'Darwin'] and Dir('#tools/cabana/').exists()) or GetOption('extras'): SConscript(['tools/replay/SConscript']) SConscript(['tools/cabana/SConscript']) diff --git a/cereal b/cereal index f01d677e1d..1ee48e0110 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit f01d677e1d919bf5e33ec2dd209605943fe4914c +Subproject commit 1ee48e0110a46fbdd9db50ed89a38bb5a748cfcb diff --git a/common/gpio.py b/common/gpio.py index 5ec23bf7b1..88a9479a60 100644 --- a/common/gpio.py +++ b/common/gpio.py @@ -1,3 +1,4 @@ +import os from functools import lru_cache from typing import Optional, List @@ -26,6 +27,9 @@ def gpio_read(pin: int) -> Optional[bool]: return val def gpio_export(pin: int) -> None: + if os.path.isdir(f"/sys/class/gpio/gpio{pin}"): + return + try: with open("/sys/class/gpio/export", 'w') as f: f.write(str(pin)) diff --git a/common/spinner.py b/common/spinner.py index 57242d644d..34fd720ee9 100644 --- a/common/spinner.py +++ b/common/spinner.py @@ -29,11 +29,11 @@ class Spinner(): def close(self): if self.spinner_proc is not None: + self.spinner_proc.kill() try: - self.spinner_proc.stdin.close() - except BrokenPipeError: - pass - self.spinner_proc.terminate() + self.spinner_proc.communicate(timeout=2.) + except subprocess.TimeoutExpired: + print("WARNING: failed to kill spinner") self.spinner_proc = None def __del__(self): diff --git a/common/transformations/camera.py b/common/transformations/camera.py index b20ed5c64b..eaed0e7afe 100644 --- a/common/transformations/camera.py +++ b/common/transformations/camera.py @@ -61,14 +61,6 @@ device_frame_from_view_frame = np.array([ view_frame_from_device_frame = device_frame_from_view_frame.T -def get_calib_from_vp(vp): - vp_norm = normalize(vp) - yaw_calib = np.arctan(vp_norm[0]) - pitch_calib = -np.arctan(vp_norm[1]*np.cos(yaw_calib)) - roll_calib = 0 - return roll_calib, pitch_calib, yaw_calib - - # aka 'extrinsic_matrix' # road : x->forward, y -> left, z->up def get_view_frame_from_road_frame(roll, pitch, yaw, height): @@ -131,6 +123,14 @@ def denormalize(img_pts, intrinsics=fcam_intrinsics, width=np.inf, height=np.inf return img_pts_denormalized[:, :2].reshape(input_shape) +def get_calib_from_vp(vp, intrinsics=fcam_intrinsics): + vp_norm = normalize(vp, intrinsics) + yaw_calib = np.arctan(vp_norm[0]) + pitch_calib = -np.arctan(vp_norm[1]*np.cos(yaw_calib)) + roll_calib = 0 + return roll_calib, pitch_calib, yaw_calib + + def device_from_ecef(pos_ecef, orientation_ecef, pt_ecef): # device from ecef frame # device frame is x -> forward, y-> right, z -> down diff --git a/common/util.cc b/common/util.cc index 2914f6bcbc..6ad619c35c 100644 --- a/common/util.cc +++ b/common/util.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -60,6 +61,20 @@ int set_core_affinity(std::vector cores) { #endif } +int set_file_descriptor_limit(uint64_t limit_val) { + struct rlimit limit; + int status; + + if ((status = getrlimit(RLIMIT_NOFILE, &limit)) < 0) + return status; + + limit.rlim_cur = limit_val; + if ((status = setrlimit(RLIMIT_NOFILE, &limit)) < 0) + return status; + + return 0; +} + std::string read_file(const std::string& fn) { std::ifstream f(fn, std::ios::binary | std::ios::in); if (f.is_open()) { @@ -213,6 +228,13 @@ std::string hexdump(const uint8_t* in, const size_t size) { return ss.str(); } +int random_int(int min, int max) { + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(min, max); + return dist(rng); +} + std::string random_string(std::string::size_type length) { const std::string chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; std::mt19937 rg{std::random_device{}()}; diff --git a/common/util.h b/common/util.h index 34721700e7..aaa54d52a2 100644 --- a/common/util.h +++ b/common/util.h @@ -44,6 +44,7 @@ namespace util { void set_thread_name(const char* name); int set_realtime_priority(int level); int set_core_affinity(std::vector cores); +int set_file_descriptor_limit(uint64_t limit); // ***** Time helpers ***** struct tm get_time(); @@ -75,10 +76,13 @@ int getenv(const char* key, int default_val); float getenv(const char* key, float default_val); std::string hexdump(const uint8_t* in, const size_t size); -std::string random_string(std::string::size_type length); std::string dir_name(std::string const& path); -// **** file fhelpers ***** +// ***** random helpers ***** +int random_int(int min, int max); +std::string random_string(std::string::size_type length); + +// **** file helpers ***** std::string read_file(const std::string& fn); std::map read_files_in_dir(const std::string& path); int write_file(const char* path, const void* data, size_t size, int flags = O_WRONLY, mode_t mode = 0664); diff --git a/docs/conf.py b/docs/conf.py index 345d27f6ad..beb5924496 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -100,7 +100,7 @@ breathe_projects_source = {} # only document files that have accompanying .cc files next to them print("searching for c_docs...") -for root, dirs, files in os.walk(BASEDIR): +for root, _, files in os.walk(BASEDIR): found = False breath_src = {} breathe_srcs_list = [] diff --git a/docs/docker/Dockerfile b/docs/docker/Dockerfile index 08b318a59a..63564a6fff 100644 --- a/docs/docker/Dockerfile +++ b/docs/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/commaai/openpilot-base:latest +FROM ghcr.io/commaai/openpilot-base:latest as openpilot-docs-base ENV PYTHONUNBUFFERED 1 diff --git a/openpilot/__init__.py b/openpilot/__init__.py new file mode 100644 index 0000000000..b28b04f643 --- /dev/null +++ b/openpilot/__init__.py @@ -0,0 +1,3 @@ + + + diff --git a/openpilot/common b/openpilot/common new file mode 120000 index 0000000000..60d3b0a6a8 --- /dev/null +++ b/openpilot/common @@ -0,0 +1 @@ +../common \ No newline at end of file diff --git a/openpilot/selfdrive b/openpilot/selfdrive new file mode 120000 index 0000000000..e005fd0d04 --- /dev/null +++ b/openpilot/selfdrive @@ -0,0 +1 @@ +../selfdrive/ \ No newline at end of file diff --git a/openpilot/system b/openpilot/system new file mode 120000 index 0000000000..16f8cc2b23 --- /dev/null +++ b/openpilot/system @@ -0,0 +1 @@ +../system/ \ No newline at end of file diff --git a/openpilot/third_party b/openpilot/third_party new file mode 120000 index 0000000000..d838c05a86 --- /dev/null +++ b/openpilot/third_party @@ -0,0 +1 @@ +../third_party \ No newline at end of file diff --git a/openpilot/tools b/openpilot/tools new file mode 120000 index 0000000000..4887d6e0c9 --- /dev/null +++ b/openpilot/tools @@ -0,0 +1 @@ +../tools \ No newline at end of file diff --git a/panda b/panda index a09ca7de34..c15f8ff6ad 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit a09ca7de347993bd85bd477e08c3caa9f64f4eea +Subproject commit c15f8ff6adc82619273820e2505074a05e38f41c diff --git a/poetry.lock b/poetry.lock index 3ce2cd0ec2..16bfe6f375 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,34 +1,5 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. -[[package]] -name = "adal" -version = "1.2.7" -description = "Note: This library is already replaced by MSAL Python, available here: https://pypi.org/project/msal/ .ADAL Python remains available here as a legacy. The ADAL for Python library makes it easy for python application to authenticate to Azure Active Directory (AAD) in order to access AAD protected web resources." -optional = false -python-versions = "*" -files = [ - {file = "adal-1.2.7-py2.py3-none-any.whl", hash = "sha256:2a7451ed7441ddbc57703042204a3e30ef747478eea022c70f789fc7f084bc3d"}, - {file = "adal-1.2.7.tar.gz", hash = "sha256:d74f45b81317454d96e982fd1c50e6fb5c99ac2223728aea8764433a39f566f1"}, -] - -[package.dependencies] -cryptography = ">=1.1.0" -PyJWT = ">=1.0.0,<3" -python-dateutil = ">=2.1.0,<3" -requests = ">=2.0.0,<3" - -[[package]] -name = "aenum" -version = "3.1.15" -description = "Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants" -optional = false -python-versions = "*" -files = [ - {file = "aenum-3.1.15-py2-none-any.whl", hash = "sha256:27b1710b9d084de6e2e695dab78fe9f269de924b51ae2850170ee7e1ca6288a5"}, - {file = "aenum-3.1.15-py3-none-any.whl", hash = "sha256:e0dfaeea4c2bd362144b87377e2c61d91958c5ed0b4daf89cb6f45ae23af6288"}, - {file = "aenum-3.1.15.tar.gz", hash = "sha256:8cbd76cd18c4f870ff39b24284d3ea028fbe8731a58df3aa581e434c575b9559"}, -] - [[package]] name = "aiohttp" version = "3.8.5" @@ -249,246 +220,15 @@ files = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] -[[package]] -name = "albumentations" -version = "1.3.1" -description = "Fast image augmentation library and easy to use wrapper around other libraries" -optional = false -python-versions = ">=3.7" -files = [ - {file = "albumentations-1.3.1-py3-none-any.whl", hash = "sha256:6b641d13733181d9ecdc29550e6ad580d1bfa9d25e2213a66940062f25e291bd"}, - {file = "albumentations-1.3.1.tar.gz", hash = "sha256:a6a38388fe546c568071e8c82f414498e86c9ed03c08b58e7a88b31cf7a244c6"}, -] - -[package.dependencies] -numpy = ">=1.11.1" -opencv-python-headless = ">=4.1.1" -PyYAML = "*" -qudida = ">=0.0.4" -scikit-image = ">=0.16.1" -scipy = ">=1.1.0" - -[package.extras] -develop = ["imgaug (>=0.4.0)", "pytest"] -imgaug = ["imgaug (>=0.4.0)"] -tests = ["pytest"] - -[[package]] -name = "antlr4-python3-runtime" -version = "4.9.3" -description = "ANTLR 4.9.3 runtime for Python 3.7" -optional = false -python-versions = "*" -files = [ - {file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"}, -] - -[[package]] -name = "anyio" -version = "3.7.1" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, -] - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] - -[[package]] -name = "apex" -version = "0.1" -description = "PyTorch Extensions written by NVIDIA" -optional = false -python-versions = "*" -files = [ - {file = "apex-0.1-cp311-cp311-linux_x86_64.whl", hash = "sha256:2f47d44ca8823491b32d1cfd51d1aa57e2be3ae61661597aa9730d05c22815a7"}, -] - -[package.dependencies] -packaging = ">20.6" - -[package.source] -type = "url" -url = "https://github.com/commaai/apex/releases/download/pytorch2.0.1%2Bcu11.8/apex-0.1-cp311-cp311-linux_x86_64.whl" - -[[package]] -name = "appdirs" -version = "1.4.4" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = "*" -files = [ - {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, -] - -[[package]] -name = "applicationinsights" -version = "0.11.10" -description = "This project extends the Application Insights API surface to support Python." -optional = false -python-versions = "*" -files = [ - {file = "applicationinsights-0.11.10-py2.py3-none-any.whl", hash = "sha256:e89a890db1c6906b6a7d0bcfd617dac83974773c64573147c8d6654f9cf2a6ea"}, - {file = "applicationinsights-0.11.10.tar.gz", hash = "sha256:0b761f3ef0680acf4731906dfc1807faa6f2a57168ae74592db0084a6099f7b3"}, -] - -[[package]] -name = "appnope" -version = "0.1.3" -description = "Disable App Nap on macOS >= 10.9" -optional = false -python-versions = "*" -files = [ - {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, - {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, -] - -[[package]] -name = "argcomplete" -version = "3.1.1" -description = "Bash tab completion for argparse" -optional = false -python-versions = ">=3.6" -files = [ - {file = "argcomplete-3.1.1-py3-none-any.whl", hash = "sha256:35fa893a88deea85ea7b20d241100e64516d6af6d7b0ae2bed1d263d26f70948"}, - {file = "argcomplete-3.1.1.tar.gz", hash = "sha256:6c4c563f14f01440aaffa3eae13441c5db2357b5eec639abe7c0b15334627dff"}, -] - -[package.extras] -test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] - -[[package]] -name = "argon2-cffi" -version = "21.3.0" -description = "The secure Argon2 password hashing algorithm." -optional = false -python-versions = ">=3.6" -files = [ - {file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"}, - {file = "argon2_cffi-21.3.0-py3-none-any.whl", hash = "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80"}, -] - -[package.dependencies] -argon2-cffi-bindings = "*" - -[package.extras] -dev = ["cogapp", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "pre-commit", "pytest", "sphinx", "sphinx-notfound-page", "tomli"] -docs = ["furo", "sphinx", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] - -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -optional = false -python-versions = ">=3.6" -files = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["cogapp", "pre-commit", "pytest", "wheel"] -tests = ["pytest"] - -[[package]] -name = "arrow" -version = "1.2.3" -description = "Better dates & times for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, - {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, -] - -[package.dependencies] -python-dateutil = ">=2.7.0" - -[[package]] -name = "astroid" -version = "2.15.6" -description = "An abstract syntax tree for Python with inference support." -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"}, - {file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"}, -] - -[package.dependencies] -lazy-object-proxy = ">=1.4.0" -wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} - -[[package]] -name = "asttokens" -version = "2.2.1" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = "*" -files = [ - {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, - {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, -] - -[package.dependencies] -six = "*" - -[package.extras] -test = ["astroid", "pytest"] - -[[package]] -name = "async-lru" -version = "2.0.4" -description = "Simple LRU cache for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627"}, - {file = "async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224"}, -] - [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] [[package]] @@ -572,52 +312,6 @@ files = [ {file = "av-10.0.0.tar.gz", hash = "sha256:8afd3d5610e1086f3b2d8389d66672ea78624516912c93612de64dcaa4c67e05"}, ] -[[package]] -name = "azure-cli-core" -version = "2.51.0" -description = "Microsoft Azure Command-Line Tools Core Module" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "azure-cli-core-2.51.0.tar.gz", hash = "sha256:dfcd62ffb77a9fb32447fc85af9e3aaeffc0e95bb1d9e373f61b5c3a40974a29"}, - {file = "azure_cli_core-2.51.0-py3-none-any.whl", hash = "sha256:180ddddaefe12dac7b9a7775f25c2898f785230ca43352f61cba8dc5722d4cef"}, -] - -[package.dependencies] -argcomplete = ">=3.1.1,<3.2.0" -azure-cli-telemetry = "==1.1.0.*" -azure-mgmt-core = ">=1.2.0,<2" -cryptography = "*" -distro = {version = "*", markers = "sys_platform == \"linux\""} -humanfriendly = ">=10.0,<11.0" -jmespath = "*" -knack = ">=0.11.0,<0.12.0" -msal = {version = "1.24.0b1", extras = ["broker"]} -msal-extensions = ">=1.0.0,<1.1.0" -msrestazure = ">=0.6.4,<0.7.0" -packaging = ">=20.9" -paramiko = ">=2.0.8,<4.0.0" -pkginfo = ">=1.5.0.1" -psutil = {version = ">=5.9,<6.0", markers = "sys_platform != \"cygwin\""} -PyJWT = ">=2.1.0" -pyopenssl = ">=17.1.0" -requests = {version = "*", extras = ["socks"]} - -[[package]] -name = "azure-cli-telemetry" -version = "1.1.0" -description = "Microsoft Azure CLI Telemetry Package" -optional = false -python-versions = "*" -files = [ - {file = "azure-cli-telemetry-1.1.0.tar.gz", hash = "sha256:d922379cda1b48952be75fb3bd2ac5e7ceecf569492a6088bab77894c624a278"}, - {file = "azure_cli_telemetry-1.1.0-py3-none-any.whl", hash = "sha256:2fc12608c0cf0ea6e69b392af9cab92f1249340b8caff7e9674cf91b3becb337"}, -] - -[package.dependencies] -applicationinsights = ">=0.11.1,<0.12" -portalocker = ">=1.6,<3" - [[package]] name = "azure-common" version = "1.1.28" @@ -629,51 +323,6 @@ files = [ {file = "azure_common-1.1.28-py2.py3-none-any.whl", hash = "sha256:5c12d3dcf4ec20599ca6b0d3e09e86e146353d443e7fcc050c9a19c1f9df20ad"}, ] -[[package]] -name = "azure-core" -version = "1.29.1" -description = "Microsoft Azure Core Library for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "azure-core-1.29.1.zip", hash = "sha256:68e5bb6e3a3230ec202001cc5cb88e57f11c441c8345e921a9ffb8c370abf936"}, - {file = "azure_core-1.29.1-py3-none-any.whl", hash = "sha256:6bcefa1f70ff7bf3c39c07c73d8a21df73288eff7e6a1031eb8cfae71cc7bed4"}, -] - -[package.dependencies] -requests = ">=2.18.4" -six = ">=1.11.0" -typing-extensions = ">=4.3.0" - -[package.extras] -aio = ["aiohttp (>=3.0)"] - -[[package]] -name = "azure-mgmt-core" -version = "1.4.0" -description = "Microsoft Azure Management Core Library for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "azure-mgmt-core-1.4.0.zip", hash = "sha256:d195208340094f98e5a6661b781cde6f6a051e79ce317caabd8ff97030a9b3ae"}, - {file = "azure_mgmt_core-1.4.0-py3-none-any.whl", hash = "sha256:81071675f186a585555ef01816f2774d49c1c9024cb76e5720c3c0f6b337bb7d"}, -] - -[package.dependencies] -azure-core = ">=1.26.2,<2.0.0" - -[[package]] -name = "azure-nspkg" -version = "3.0.2" -description = "Microsoft Azure Namespace Package [Internal]" -optional = false -python-versions = "*" -files = [ - {file = "azure-nspkg-3.0.2.zip", hash = "sha256:e7d3cea6af63e667d87ba1ca4f8cd7cb4dfca678e4c55fc1cedb320760e39dd0"}, - {file = "azure_nspkg-3.0.2-py2-none-any.whl", hash = "sha256:1d0bbb2157cf57b1bef6c8c8e5b41133957364456c43b0a43599890023cca0a8"}, - {file = "azure_nspkg-3.0.2-py3-none-any.whl", hash = "sha256:31a060caca00ed1ebd369fc7fe01a56768c927e404ebc92268f4d9d636435e28"}, -] - [[package]] name = "azure-storage-blob" version = "2.1.0" @@ -706,20 +355,6 @@ cryptography = "*" python-dateutil = "*" requests = "*" -[[package]] -name = "azure-storage-nspkg" -version = "3.1.0" -description = "Microsoft Azure Storage Namespace Package [Internal]" -optional = false -python-versions = "*" -files = [ - {file = "azure-storage-nspkg-3.1.0.tar.gz", hash = "sha256:6f3bbe8652d5f542767d8433e7f96b8df7f518774055ac7c92ed7ca85f653811"}, - {file = "azure_storage_nspkg-3.1.0-py2.py3-none-any.whl", hash = "sha256:7da3bd6c73b8c464a57f53ae9af8328490d2267c66430d8a7621997e52a9703e"}, -] - -[package.dependencies] -azure-nspkg = ">=2.0.0" - [[package]] name = "babel" version = "2.12.1" @@ -731,124 +366,6 @@ files = [ {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, ] -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] - -[[package]] -name = "bcrypt" -version = "4.0.1" -description = "Modern password hashing for your software and your servers" -optional = false -python-versions = ">=3.6" -files = [ - {file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"}, - {file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"}, - {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"}, - {file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"}, - {file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"}, - {file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"}, - {file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"}, - {file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"}, - {file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"}, - {file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"}, -] - -[package.extras] -tests = ["pytest (>=3.2.1,!=3.3.0)"] -typecheck = ["mypy"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.2" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "bidict" -version = "0.22.1" -description = "The bidirectional mapping library for Python." -optional = false -python-versions = ">=3.7" -files = [ - {file = "bidict-0.22.1-py3-none-any.whl", hash = "sha256:6ef212238eb884b664f28da76f33f1d28b260f665fc737b413b287d5487d1e7b"}, - {file = "bidict-0.22.1.tar.gz", hash = "sha256:1e0f7f74e4860e6d0943a05d4134c63a2fad86f3d4732fb265bd79e4e856d81d"}, -] - -[package.extras] -docs = ["furo", "sphinx", "sphinx-copybutton"] -lint = ["pre-commit"] -test = ["hypothesis", "pytest", "pytest-benchmark[histogram]", "pytest-cov", "pytest-xdist", "sortedcollections", "sortedcontainers", "sphinx"] - -[[package]] -name = "bleach" -version = "6.0.0" -description = "An easy safelist-based HTML-sanitizing tool." -optional = false -python-versions = ">=3.7" -files = [ - {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, - {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, -] - -[package.dependencies] -six = ">=1.9.0" -webencodings = "*" - -[package.extras] -css = ["tinycss2 (>=1.1.0,<1.2)"] - -[[package]] -name = "blinker" -version = "1.6.2" -description = "Fast, simple object-to-object and broadcast signaling" -optional = false -python-versions = ">=3.7" -files = [ - {file = "blinker-1.6.2-py3-none-any.whl", hash = "sha256:c3d739772abb7bc2860abf5f2ec284223d9ad5c76da018234f6f50d6f31ab1f0"}, - {file = "blinker-1.6.2.tar.gz", hash = "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213"}, -] - -[[package]] -name = "blosc" -version = "1.9.2" -description = "Blosc data compressor" -optional = false -python-versions = "*" -files = [ - {file = "blosc-1.9.2.tar.gz", hash = "sha256:89196a2112035836f027a29835ee247b0c7a45cece4cd9e4b740a1428aa174bf"}, -] - [[package]] name = "breathe" version = "4.35.0" @@ -864,139 +381,6 @@ files = [ docutils = ">=0.12" Sphinx = ">=4.0,<5.0.0 || >5.0.0" -[[package]] -name = "brotli" -version = "1.0.9" -description = "Python bindings for the Brotli compression library" -optional = false -python-versions = "*" -files = [ - {file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"}, - {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"}, - {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"}, - {file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"}, - {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"}, - {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"}, - {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"}, - {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"}, - {file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"}, - {file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"}, - {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cc0283a406774f465fb45ec7efb66857c09ffefbe49ec20b7882eff6d3c86d3a"}, - {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11d3283d89af7033236fa4e73ec2cbe743d4f6a81d41bd234f24bf63dde979df"}, - {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1306004d49b84bd0c4f90457c6f57ad109f5cc6067a9664e12b7b79a9948ad"}, - {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1375b5d17d6145c798661b67e4ae9d5496920d9265e2f00f1c2c0b5ae91fbde"}, - {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cab1b5964b39607a66adbba01f1c12df2e55ac36c81ec6ed44f2fca44178bf1a"}, - {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ed6a5b3d23ecc00ea02e1ed8e0ff9a08f4fc87a1f58a2530e71c0f48adf882f"}, - {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cb02ed34557afde2d2da68194d12f5719ee96cfb2eacc886352cb73e3808fc5d"}, - {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3523f51818e8f16599613edddb1ff924eeb4b53ab7e7197f85cbc321cdca32f"}, - {file = "Brotli-1.0.9-cp311-cp311-win32.whl", hash = "sha256:ba72d37e2a924717990f4d7482e8ac88e2ef43fb95491eb6e0d124d77d2a150d"}, - {file = "Brotli-1.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:3ffaadcaeafe9d30a7e4e1e97ad727e4f5610b9fa2f7551998471e3736738679"}, - {file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"}, - {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"}, - {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"}, - {file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"}, - {file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"}, - {file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"}, - {file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"}, - {file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"}, - {file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"}, - {file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"}, - {file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"}, - {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"}, - {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"}, - {file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"}, - {file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"}, - {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"}, - {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"}, - {file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"}, - {file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73fd30d4ce0ea48010564ccee1a26bfe39323fde05cb34b5863455629db61dc7"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02177603aaca36e1fd21b091cb742bb3b305a569e2402f1ca38af471777fb019"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, - {file = "Brotli-1.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b43775532a5904bc938f9c15b77c613cb6ad6fb30990f3b0afaea82797a402d8"}, - {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5bf37a08493232fbb0f8229f1824b366c2fc1d02d64e7e918af40acd15f3e337"}, - {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:330e3f10cd01da535c70d09c4283ba2df5fb78e915bea0a28becad6e2ac010be"}, - {file = "Brotli-1.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e1abbeef02962596548382e393f56e4c94acd286bd0c5afba756cffc33670e8a"}, - {file = "Brotli-1.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3148362937217b7072cf80a2dcc007f09bb5ecb96dae4617316638194113d5be"}, - {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336b40348269f9b91268378de5ff44dc6fbaa2268194f85177b53463d313842a"}, - {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b09a16a1950b9ef495a0f8b9d0a87599a9d1f179e2d4ac014b2ec831f87e7"}, - {file = "Brotli-1.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c8e521a0ce7cf690ca84b8cc2272ddaf9d8a50294fd086da67e517439614c755"}, - {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, -] - -[[package]] -name = "build" -version = "0.10.0" -description = "A simple, correct Python build frontend" -optional = false -python-versions = ">= 3.7" -files = [ - {file = "build-0.10.0-py3-none-any.whl", hash = "sha256:af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171"}, - {file = "build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "os_name == \"nt\""} -packaging = ">=19.0" -pyproject_hooks = "*" - -[package.extras] -docs = ["furo (>=2021.08.31)", "sphinx (>=4.0,<5.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)"] -test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "toml (>=0.10.0)", "wheel (>=0.36.0)"] -typing = ["importlib-metadata (>=5.1)", "mypy (==0.991)", "tomli", "typing-extensions (>=3.7.4.3)"] -virtualenv = ["virtualenv (>=20.0.35)"] - -[[package]] -name = "cachecontrol" -version = "0.12.14" -description = "httplib2 caching for requests" -optional = false -python-versions = ">=3.6" -files = [ - {file = "CacheControl-0.12.14-py2.py3-none-any.whl", hash = "sha256:1c2939be362a70c4e5f02c6249462b3b7a24441e4f1ced5e9ef028172edf356a"}, - {file = "CacheControl-0.12.14.tar.gz", hash = "sha256:d1087f45781c0e00616479bfd282c78504371ca71da017b49df9f5365a95feba"}, -] - -[package.dependencies] -lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""} -msgpack = ">=0.5.2" -requests = "*" - -[package.extras] -filecache = ["lockfile (>=0.9)"] -redis = ["redis (>=2.10.5)"] - [[package]] name = "carla" version = "0.9.14" @@ -1155,13 +539,13 @@ pycparser = "*" [[package]] name = "cfgv" -version = "3.3.1" +version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.8" files = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] [[package]] @@ -1248,21 +632,6 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] -[[package]] -name = "cleo" -version = "2.0.1" -description = "Cleo allows you to create beautiful and testable command-line interfaces." -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, - {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, -] - -[package.dependencies] -crashtest = ">=0.4.1,<0.5.0" -rapidfuzz = ">=2.2.0,<3.0.0" - [[package]] name = "click" version = "8.1.6" @@ -1277,80 +646,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[[package]] -name = "click-plugins" -version = "1.1.1" -description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -optional = false -python-versions = "*" -files = [ - {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, - {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, -] - -[package.dependencies] -click = ">=4.0" - -[package.extras] -dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] - -[[package]] -name = "cligj" -version = "0.7.2" -description = "Click params for commmand line interfaces to GeoJSON" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4" -files = [ - {file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"}, - {file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"}, -] - -[package.dependencies] -click = ">=4.0" - -[package.extras] -test = ["pytest-cov"] - -[[package]] -name = "cloudpickle" -version = "2.2.1" -description = "Extended pickling support for Python objects" -optional = false -python-versions = ">=3.6" -files = [ - {file = "cloudpickle-2.2.1-py3-none-any.whl", hash = "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f"}, - {file = "cloudpickle-2.2.1.tar.gz", hash = "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5"}, -] - -[[package]] -name = "cmake" -version = "3.27.1" -description = "CMake is an open-source, cross-platform family of tools designed to build, test and package software" -optional = false -python-versions = "*" -files = [ - {file = "cmake-3.27.1-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl", hash = "sha256:c62c5a6d42e68eb955fc321f7bc84290e4c4771ee7e5301c2eaa9586c874fd8e"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2010_i686.manylinux_2_12_i686.whl", hash = "sha256:18ef1c579cb4c94ece6bbb7c7f3e0170b078bf787f0a372194f0921e79f6098c"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:ad3aca0d94abe6313a7b1c65b8b3d7eb3158786fd1dd6a9f8c42f82850fb974c"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:50bfe69d369a61eb63e5b8af76a2383cf312d1e8449bd797d563f6c62809d317"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:7fb6d9183b90d4cc4db7b022aa7c9ef3431d281aea29ca259de7199bc75b7e09"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:2583464302ecc287619578627e26962386a41a98bbf1fb4c8c90d600ec1a1be5"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:7a5431c7ca0b7145b857dd0eab26f4f9ec42661bb67afa6d437b3e48532b8e3a"}, - {file = "cmake-3.27.1-py2.py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1fb6d882bbd7e77fad206dfdbcaf880f4bcd7e8d0c23b37058ee155715bd19ed"}, - {file = "cmake-3.27.1-py2.py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:cee7dd0bcc5bd14d94ecdbbf9883b17f3001adc5f696b7d8eba0482354e5e017"}, - {file = "cmake-3.27.1-py2.py3-none-musllinux_1_1_i686.whl", hash = "sha256:82a6f57449e7bf9b510ed82b29982e4eec8b5c5e80a51208368dc1aa58b8181b"}, - {file = "cmake-3.27.1-py2.py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:7052bb12c3492083169269fee7c7a11c053cae35949346b12d2998b971602b78"}, - {file = "cmake-3.27.1-py2.py3-none-musllinux_1_1_s390x.whl", hash = "sha256:482e7018fc8d9bc98e7f30b5071c021ca0e27b131dd61900395abfd768c3fe29"}, - {file = "cmake-3.27.1-py2.py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:a112dd298b8ac598fef3653dff1592ba4c0f9bf7fe75b77ab44a6edfcceb96d4"}, - {file = "cmake-3.27.1-py2.py3-none-win32.whl", hash = "sha256:b9d68783ea01775d6d4ea220d3b4e90d5e287cf9a1db09c5a9b78c7748e1c3d0"}, - {file = "cmake-3.27.1-py2.py3-none-win_amd64.whl", hash = "sha256:628f75286475b89d6566db62c0869de5f0a07ad9bba10bebe6a48012fa1ee777"}, - {file = "cmake-3.27.1-py2.py3-none-win_arm64.whl", hash = "sha256:ee7a47e37a29b8124d9125a8c390fb94822a2695d80151560004d4f4f78c0ad7"}, - {file = "cmake-3.27.1.tar.gz", hash = "sha256:7ee6af09b2b575a491483b72927ee7e4beb59e7fb86e6d905a7027607a3f367e"}, -] - -[package.extras] -test = ["coverage (>=4.2)", "flake8 (>=3.0.4)", "path.py (>=11.5.0)", "pytest (>=3.0.3)", "pytest-cov (>=2.4.0)", "pytest-runner (>=2.9)", "pytest-virtualenv (>=1.7.0)", "scikit-build (>=0.10.0)", "setuptools (>=28.0.0)", "virtualenv (>=15.0.3)", "wheel"] - [[package]] name = "colorama" version = "0.4.6" @@ -1379,40 +674,6 @@ humanfriendly = ">=9.1" [package.extras] cron = ["capturer (>=2.4)"] -[[package]] -name = "comm" -version = "0.1.4" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = false -python-versions = ">=3.6" -files = [ - {file = "comm-0.1.4-py3-none-any.whl", hash = "sha256:6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a"}, - {file = "comm-0.1.4.tar.gz", hash = "sha256:354e40a59c9dd6db50c5cc6b4acc887d82e9603787f83b68c01a80a923984d15"}, -] - -[package.dependencies] -traitlets = ">=4" - -[package.extras] -lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] -test = ["pytest"] -typing = ["mypy (>=0.990)"] - -[[package]] -name = "configargparse" -version = "1.7" -description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." -optional = false -python-versions = ">=3.5" -files = [ - {file = "ConfigArgParse-1.7-py3-none-any.whl", hash = "sha256:d249da6591465c6c26df64a9f73d2536e743be2f244eb3ebe61114af2f94f86b"}, - {file = "ConfigArgParse-1.7.tar.gz", hash = "sha256:e7067471884de5478c58a511e529f0f9bd1c66bfef1dea90935438d6c23306d1"}, -] - -[package.extras] -test = ["PyYAML", "mock", "pytest"] -yaml = ["PyYAML"] - [[package]] name = "contourpy" version = "1.1.0" @@ -1472,109 +733,69 @@ test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] test-no-images = ["pytest", "pytest-cov", "wurlitzer"] [[package]] -name = "control" -version = "0.9.4" -description = "Python Control Systems Library" +name = "coverage" +version = "7.3.0" +description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "control-0.9.4-py3-none-any.whl", hash = "sha256:ab68980abd8d35ae5015ffa090865cbbd926deea7e66d0b9a41cfd12577e63ff"}, - {file = "control-0.9.4.tar.gz", hash = "sha256:0fa57d2216b7ac4e9339c09eab6827660318a641779335864feee940bd19c9ce"}, -] - -[package.dependencies] -matplotlib = "*" -numpy = "*" -scipy = ">=1.3" - -[package.extras] -cvxopt = ["cvxopt (>=1.2.0)"] -slycot = ["slycot (>=0.4.0)"] -test = ["pytest", "pytest-timeout"] - -[[package]] -name = "coverage" -version = "7.2.7" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, + {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, + {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, + {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, + {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, + {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, + {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, + {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, + {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, + {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, + {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, + {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, + {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, ] [package.extras] toml = ["tomli"] -[[package]] -name = "crashtest" -version = "0.4.1" -description = "Manage Python errors with ease" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, - {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, -] - [[package]] name = "crcmod" version = "1.7" @@ -1630,36 +851,6 @@ ssh = ["bcrypt (>=3.1.5)"] test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -[[package]] -name = "cupy-cuda11x" -version = "12.2.0" -description = "CuPy: NumPy & SciPy for GPU" -optional = false -python-versions = ">=3.8" -files = [ - {file = "cupy_cuda11x-12.2.0-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f3b1991e4e25f52581f79b88c8d19c3e31fa739260b7080c813d7fb287ae8e7f"}, - {file = "cupy_cuda11x-12.2.0-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:ac52fd24ca5769d903bd531826d0525dbeaba66c49911ae021b9702386c8b96b"}, - {file = "cupy_cuda11x-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:8ed1fbf14230691df3f58f841e9ca5717b4175c4276fbf88948a5bc3c6392f58"}, - {file = "cupy_cuda11x-12.2.0-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:28eace420c9f58fa5739294d604f8aab9118b1c764f64a3ce0691f00193b11ff"}, - {file = "cupy_cuda11x-12.2.0-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:fb3294a694ee40b6e22ba3345b04b2a35db8a19fac74f59dc7757ea87ab5b289"}, - {file = "cupy_cuda11x-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:2e502cea9d21fefd1d8fd3747c6b46d1f916550e54d859f9083b6327a8f7ff5b"}, - {file = "cupy_cuda11x-12.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2fd425be7ae8f82ff68d2e8eeb37132fc9b9dfea6d3f0708419d6b9843983e42"}, - {file = "cupy_cuda11x-12.2.0-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:fcdfe993f87c5499898692d35d3c1f30cdd249778d6102132b5bc4a6f8a867fd"}, - {file = "cupy_cuda11x-12.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:66491d9c1ed93d4ee5b390ece92ed76a885c61859b403e3a6fd6f5b3a9ded116"}, - {file = "cupy_cuda11x-12.2.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:ededad28104d9e0c2cb02876fd2fc5c0dfec4cc66e600b7120bb4e655857c5e3"}, - {file = "cupy_cuda11x-12.2.0-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ba4403d94e9eb2578f8f2667d37ef3ec8be4fbc2c7fd1ba498004d6399d0f3b6"}, - {file = "cupy_cuda11x-12.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:d01138eb7cf51583b6d67281bd39f3f241d664f2d1c65af2399ed304a609dadb"}, -] - -[package.dependencies] -fastrlock = ">=0.5" -numpy = ">=1.20,<1.27" - -[package.extras] -all = ["Cython (>=0.29.22,<3)", "optuna (>=2.0)", "scipy (>=1.6,<1.13)"] -stylecheck = ["autopep8 (==1.5.5)", "flake8 (==3.8.4)", "mypy (==1.4.1)", "pbr (==5.5.1)", "pycodestyle (==2.6.0)", "types-setuptools (==57.4.14)"] -test = ["hypothesis (>=6.37.2,<6.55.0)", "pytest (>=7.2)"] - [[package]] name = "cycler" version = "0.11.0" @@ -1738,69 +929,6 @@ files = [ {file = "Cython-3.0.0.tar.gz", hash = "sha256:350b18f9673e63101dbbfcf774ee2f57c20ac4636d255741d76ca79016b1bd82"}, ] -[[package]] -name = "datadog" -version = "0.46.0" -description = "The Datadog Python library" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "datadog-0.46.0-py2.py3-none-any.whl", hash = "sha256:3d7bcda6177b43be4cdb52e16b4bdd4f9005716c0dd7cfea009e018c36bb7a3d"}, - {file = "datadog-0.46.0.tar.gz", hash = "sha256:e4fbc92a85e2b0919a226896ae45fc5e4b356c0c57f1c2659659dfbe0789c674"}, -] - -[package.dependencies] -requests = ">=2.6.0" - -[[package]] -name = "debugpy" -version = "1.6.7.post1" -description = "An implementation of the Debug Adapter Protocol for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "debugpy-1.6.7.post1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:903bd61d5eb433b6c25b48eae5e23821d4c1a19e25c9610205f5aeaccae64e32"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d16882030860081e7dd5aa619f30dec3c2f9a421e69861125f83cc372c94e57d"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win32.whl", hash = "sha256:eea8d8cfb9965ac41b99a61f8e755a8f50e9a20330938ad8271530210f54e09c"}, - {file = "debugpy-1.6.7.post1-cp310-cp310-win_amd64.whl", hash = "sha256:85969d864c45f70c3996067cfa76a319bae749b04171f2cdeceebe4add316155"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:890f7ab9a683886a0f185786ffbda3b46495c4b929dab083b8c79d6825832a52"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4ac7a4dba28801d184b7fc0e024da2635ca87d8b0a825c6087bb5168e3c0d28"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win32.whl", hash = "sha256:3370ef1b9951d15799ef7af41f8174194f3482ee689988379763ef61a5456426"}, - {file = "debugpy-1.6.7.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:65b28435a17cba4c09e739621173ff90c515f7b9e8ea469b92e3c28ef8e5cdfb"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:92b6dae8bfbd497c90596bbb69089acf7954164aea3228a99d7e43e5267f5b36"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72f5d2ecead8125cf669e62784ef1e6300f4067b0f14d9f95ee00ae06fc7c4f7"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win32.whl", hash = "sha256:f0851403030f3975d6e2eaa4abf73232ab90b98f041e3c09ba33be2beda43fcf"}, - {file = "debugpy-1.6.7.post1-cp38-cp38-win_amd64.whl", hash = "sha256:3de5d0f97c425dc49bce4293df6a04494309eedadd2b52c22e58d95107e178d9"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:38651c3639a4e8bbf0ca7e52d799f6abd07d622a193c406be375da4d510d968d"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:038c51268367c9c935905a90b1c2d2dbfe304037c27ba9d19fe7409f8cdc710c"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win32.whl", hash = "sha256:4b9eba71c290852f959d2cf8a03af28afd3ca639ad374d393d53d367f7f685b2"}, - {file = "debugpy-1.6.7.post1-cp39-cp39-win_amd64.whl", hash = "sha256:973a97ed3b434eab0f792719a484566c35328196540676685c975651266fccf9"}, - {file = "debugpy-1.6.7.post1-py2.py3-none-any.whl", hash = "sha256:1093a5c541af079c13ac8c70ab8b24d1d35c8cacb676306cf11e57f699c02926"}, - {file = "debugpy-1.6.7.post1.zip", hash = "sha256:fe87ec0182ef624855d05e6ed7e0b7cb1359d2ffa2a925f8ec2d22e98b75d0ca"}, -] - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - [[package]] name = "dictdiffer" version = "0.9.0" @@ -1818,20 +946,6 @@ docs = ["Sphinx (>=3)", "sphinx-rtd-theme (>=0.2)"] numpy = ["numpy (>=1.13.0)", "numpy (>=1.15.0)", "numpy (>=1.18.0)", "numpy (>=1.20.0)"] tests = ["check-manifest (>=0.42)", "mock (>=1.3.0)", "pytest (==5.4.3)", "pytest (>=6)", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "pytest-pycodestyle (>=2)", "pytest-pycodestyle (>=2.2.0)", "pytest-pydocstyle (>=2)", "pytest-pydocstyle (>=2.2.0)", "sphinx (>=3)", "tox (>=3.7.0)"] -[[package]] -name = "dill" -version = "0.3.7" -description = "serialize all of Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"}, - {file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"}, -] - -[package.extras] -graph = ["objgraph (>=1.7.2)"] - [[package]] name = "distlib" version = "0.3.7" @@ -1843,17 +957,6 @@ files = [ {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, ] -[[package]] -name = "distro" -version = "1.8.0" -description = "Distro - an OS platform information API" -optional = false -python-versions = ">=3.6" -files = [ - {file = "distro-1.8.0-py3-none-any.whl", hash = "sha256:99522ca3e365cac527b44bde033f64c6945d90eb9f769703caaec52b09bbd3ff"}, - {file = "distro-1.8.0.tar.gz", hash = "sha256:02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8"}, -] - [[package]] name = "dnspython" version = "2.4.2" @@ -1884,151 +987,6 @@ files = [ {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"}, ] -[[package]] -name = "dotmap" -version = "1.3.30" -description = "ordered, dynamically-expandable dot-access dictionary" -optional = false -python-versions = "*" -files = [ - {file = "dotmap-1.3.30-py3-none-any.whl", hash = "sha256:bd9fa15286ea2ad899a4d1dc2445ed85a1ae884a42effb87c89a6ecce71243c6"}, - {file = "dotmap-1.3.30.tar.gz", hash = "sha256:5821a7933f075fb47563417c0e92e0b7c031158b4c9a6a7e56163479b658b368"}, -] - -[[package]] -name = "dulwich" -version = "0.21.5" -description = "Python Git Library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "dulwich-0.21.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8864719bc176cdd27847332a2059127e2f7bab7db2ff99a999873cb7fff54116"}, - {file = "dulwich-0.21.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3800cdc17d144c1f7e114972293bd6c46688f5bcc2c9228ed0537ded72394082"}, - {file = "dulwich-0.21.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2f676bfed8146966fe934ee734969d7d81548fbd250a8308582973670a9dab1"}, - {file = "dulwich-0.21.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db330fb59fe3b9d253bdf0e49a521739db83689520c4921ab1c5242aaf77b82"}, - {file = "dulwich-0.21.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e8f6d4f4f4d01dd1d3c968e486d4cd77f96f772da7265941bc506de0944ddb9"}, - {file = "dulwich-0.21.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1cc0c9ba19ac1b2372598802bc9201a9c45e5d6f1f7a80ec40deeb10acc4e9ae"}, - {file = "dulwich-0.21.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61e10242b5a7a82faa8996b2c76239cfb633620b02cdd2946e8af6e7eb31d651"}, - {file = "dulwich-0.21.5-cp310-cp310-win32.whl", hash = "sha256:7f357639b56146a396f48e5e0bc9bbaca3d6d51c8340bd825299272b588fff5f"}, - {file = "dulwich-0.21.5-cp310-cp310-win_amd64.whl", hash = "sha256:891d5c73e2b66d05dbb502e44f027dc0dbbd8f6198bc90dae348152e69d0befc"}, - {file = "dulwich-0.21.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45d6198e804b539708b73a003419e48fb42ff2c3c6dd93f63f3b134dff6dd259"}, - {file = "dulwich-0.21.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c2a565d4e704d7f784cdf9637097141f6d47129c8fffc2fac699d57cb075a169"}, - {file = "dulwich-0.21.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:823091d6b6a1ea07dc4839c9752198fb39193213d103ac189c7669736be2eaff"}, - {file = "dulwich-0.21.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2c9931b657f2206abec0964ec2355ee2c1e04d05f8864e823ffa23c548c4548"}, - {file = "dulwich-0.21.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dc358c2ee727322a09b7c6da43d47a1026049dbd3ad8d612eddca1f9074b298"}, - {file = "dulwich-0.21.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6155ab7388ee01c670f7c5d8003d4e133eebebc7085a856c007989f0ba921b36"}, - {file = "dulwich-0.21.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a605e10d72f90a39ea2e634fbfd80f866fc4df29a02ea6db52ae92e5fd4a2003"}, - {file = "dulwich-0.21.5-cp311-cp311-win32.whl", hash = "sha256:daa607370722c3dce99a0022397c141caefb5ed32032a4f72506f4817ea6405b"}, - {file = "dulwich-0.21.5-cp311-cp311-win_amd64.whl", hash = "sha256:5e56b2c1911c344527edb2bf1a4356e2fb7e086b1ba309666e1e5c2224cdca8a"}, - {file = "dulwich-0.21.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:85d3401d08b1ec78c7d58ae987c4bb7b768a438f3daa74aeb8372bebc7fb16fa"}, - {file = "dulwich-0.21.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90479608e49db93d8c9e4323bc0ec5496678b535446e29d8fd67dc5bbb5d51bf"}, - {file = "dulwich-0.21.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9a6bf99f57bcac4c77fc60a58f1b322c91cc4d8c65dc341f76bf402622f89cb"}, - {file = "dulwich-0.21.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3e68b162af2aae995355e7920f89d50d72b53d56021e5ac0a546d493b17cbf7e"}, - {file = "dulwich-0.21.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0ab86d6d42e385bf3438e70f3c9b16de68018bd88929379e3484c0ef7990bd3c"}, - {file = "dulwich-0.21.5-cp37-cp37m-win32.whl", hash = "sha256:f2eeca6d61366cf5ee8aef45bed4245a67d4c0f0d731dc2383eabb80fa695683"}, - {file = "dulwich-0.21.5-cp37-cp37m-win_amd64.whl", hash = "sha256:1b20a3656b48c941d49c536824e1e5278a695560e8de1a83b53a630143c4552e"}, - {file = "dulwich-0.21.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3932b5e17503b265a85f1eda77ede647681c3bab53bc9572955b6b282abd26ea"}, - {file = "dulwich-0.21.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6616132d219234580de88ceb85dd51480dc43b1bdc05887214b8dd9cfd4a9d40"}, - {file = "dulwich-0.21.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:eaf6c7fb6b13495c19c9aace88821c2ade3c8c55b4e216cd7cc55d3e3807d7fa"}, - {file = "dulwich-0.21.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be12a46f73023970125808a4a78f610c055373096c1ecea3280edee41613eba8"}, - {file = "dulwich-0.21.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baecef0d8b9199822c7912876a03a1af17833f6c0d461efb62decebd45897e49"}, - {file = "dulwich-0.21.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:82f632afb9c7c341a875d46aaa3e6c5e586c7a64ce36c9544fa400f7e4f29754"}, - {file = "dulwich-0.21.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82cdf482f8f51fcc965ffad66180b54a9abaea9b1e985a32e1acbfedf6e0e363"}, - {file = "dulwich-0.21.5-cp38-cp38-win32.whl", hash = "sha256:c8ded43dc0bd2e65420eb01e778034be5ca7f72e397a839167eda7dcb87c4248"}, - {file = "dulwich-0.21.5-cp38-cp38-win_amd64.whl", hash = "sha256:2aba0fdad2a19bd5bb3aad6882580cb33359c67b48412ccd4cfccd932012b35e"}, - {file = "dulwich-0.21.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd4ad079758514375f11469e081723ba8831ce4eaa1a64b41f06a3a866d5ac34"}, - {file = "dulwich-0.21.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fe62685bf356bfb4d0738f84a3fcf0d1fc9e11fee152e488a20b8c66a52429e"}, - {file = "dulwich-0.21.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aae448da7d80306dda4fc46292fed7efaa466294571ab3448be16714305076f1"}, - {file = "dulwich-0.21.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b24cb1fad0525dba4872e9381bc576ea2a6dcdf06b0ed98f8e953e3b1d719b89"}, - {file = "dulwich-0.21.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e39b7c2c9bda6acae83b25054650a8bb7e373e886e2334721d384e1479bf04b"}, - {file = "dulwich-0.21.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26456dba39d1209fca17187db06967130e27eeecad2b3c2bbbe63467b0bf09d6"}, - {file = "dulwich-0.21.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:281310644e02e3aa6d76bcaffe2063b9031213c4916b5f1a6e68c25bdecfaba4"}, - {file = "dulwich-0.21.5-cp39-cp39-win32.whl", hash = "sha256:4814ca3209dabe0fe7719e9545fbdad7f8bb250c5a225964fe2a31069940c4cf"}, - {file = "dulwich-0.21.5-cp39-cp39-win_amd64.whl", hash = "sha256:c922a4573267486be0ef85216f2da103fb38075b8465dc0e90457843884e4860"}, - {file = "dulwich-0.21.5-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e52b20c4368171b7d32bd3ab0f1d2402e76ad4f2ea915ff9aa73bc9fa2b54d6d"}, - {file = "dulwich-0.21.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeb736d777ee21f2117a90fc453ee181aa7eedb9e255b5ef07c51733f3fe5cb6"}, - {file = "dulwich-0.21.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e8a79c1ed7166f32ad21974fa98d11bf6fd74e94a47e754c777c320e01257c6"}, - {file = "dulwich-0.21.5-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b943517e30bd651fbc275a892bb96774f3893d95fe5a4dedd84496a98eaaa8ab"}, - {file = "dulwich-0.21.5-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:32493a456358a3a6c15bbda07106fc3d4cc50834ee18bc7717968d18be59b223"}, - {file = "dulwich-0.21.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0aa44b812d978fc22a04531f5090c3c369d5facd03fa6e0501d460a661800c7f"}, - {file = "dulwich-0.21.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f46bcb6777e5f9f4af24a2bd029e88b77316269d24ce66be590e546a0d8f7b7"}, - {file = "dulwich-0.21.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a917fd3b4493db3716da2260f16f6b18f68d46fbe491d851d154fc0c2d984ae4"}, - {file = "dulwich-0.21.5-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:684c52cff867d10c75a7238151ca307582b3d251bbcd6db9e9cffbc998ef804e"}, - {file = "dulwich-0.21.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9019189d7a8f7394df6a22cd5b484238c5776e42282ad5d6d6c626b4c5f43597"}, - {file = "dulwich-0.21.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:494024f74c2eef9988adb4352b3651ac1b6c0466176ec62b69d3d3672167ba68"}, - {file = "dulwich-0.21.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f9b6ac1b1c67fc6083c42b7b6cd3b211292c8a6517216c733caf23e8b103ab6d"}, - {file = "dulwich-0.21.5.tar.gz", hash = "sha256:70955e4e249ddda6e34a4636b90f74e931e558f993b17c52570fa6144b993103"}, -] - -[package.dependencies] -urllib3 = ">=1.25" - -[package.extras] -fastimport = ["fastimport"] -https = ["urllib3 (>=1.24.1)"] -paramiko = ["paramiko"] -pgp = ["gpg"] - -[[package]] -name = "efficientnet-pytorch" -version = "0.7.1" -description = "EfficientNet implemented in PyTorch." -optional = false -python-versions = ">=3.5.0" -files = [ - {file = "efficientnet_pytorch-0.7.1.tar.gz", hash = "sha256:00b9b261effce59d2d47aae2ad238c29a2a65175470f41ada7ecac439b7c1ee1"}, -] - -[package.dependencies] -torch = "*" - -[[package]] -name = "einops" -version = "0.6.1" -description = "A new flavour of deep learning operations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "einops-0.6.1-py3-none-any.whl", hash = "sha256:99149e46cc808956b174932fe563d920db4d6e5dadb8c6ecdaa7483b7ef7cfc3"}, - {file = "einops-0.6.1.tar.gz", hash = "sha256:f95f8d00f4ded90dbc4b19b6f98b177332614b0357dde66997f3ae5d474dc8c8"}, -] - -[[package]] -name = "elastic-transport" -version = "8.4.0" -description = "Transport classes and utilities shared among Python Elastic client libraries" -optional = false -python-versions = ">=3.6" -files = [ - {file = "elastic-transport-8.4.0.tar.gz", hash = "sha256:b9ad708ceb7fcdbc6b30a96f886609a109f042c0b9d9f2e44403b3133ba7ff10"}, - {file = "elastic_transport-8.4.0-py3-none-any.whl", hash = "sha256:19db271ab79c9f70f8c43f8f5b5111408781a6176b54ab2e54d713b6d9ceb815"}, -] - -[package.dependencies] -certifi = "*" -urllib3 = ">=1.26.2,<2" - -[package.extras] -develop = ["aiohttp", "mock", "pytest", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests", "trustme"] - -[[package]] -name = "elasticsearch" -version = "8.9.0" -description = "Python client for Elasticsearch" -optional = false -python-versions = ">=3.6, <4" -files = [ - {file = "elasticsearch-8.9.0-py3-none-any.whl", hash = "sha256:0795cbf0f61482070741c09ba02ac8fdf18f5984912fbd08b248fadd8a8c9952"}, - {file = "elasticsearch-8.9.0.tar.gz", hash = "sha256:d3367fc013e04fc7aad349a6de9fad1ee04fb6d627b0e7896aa505c12fde5e04"}, -] - -[package.dependencies] -elastic-transport = ">=8,<9" - -[package.extras] -async = ["aiohttp (>=3,<4)"] -requests = ["requests (>=2.4.0,<3.0.0)"] - [[package]] name = "execnet" version = "2.0.2" @@ -2043,162 +1001,6 @@ files = [ [package.extras] testing = ["hatch", "pre-commit", "pytest", "tox"] -[[package]] -name = "executing" -version = "1.2.0" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = "*" -files = [ - {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, - {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, -] - -[package.extras] -tests = ["asttokens", "littleutils", "pytest", "rich"] - -[[package]] -name = "fastcluster" -version = "1.2.6" -description = "Fast hierarchical clustering routines for R and Python." -optional = false -python-versions = ">=3" -files = [ - {file = "fastcluster-1.2.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d0e8faef0437a25fd083df70fb86cc65ce3c9c9780d4ae377cbe6521e7746ce0"}, - {file = "fastcluster-1.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8be01f97bc2bf11a9188537864f8e520e1103cdc6007aa2c5d7979b1363b121"}, - {file = "fastcluster-1.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:855ab2b7e6fa9b05f19c4f3023dedfb1a35a88d831933d65d0d9e10a070a9e85"}, - {file = "fastcluster-1.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72503e727887a61a15f9aaa13178798d3994dfec58aa7a943e42dcfda07c0149"}, - {file = "fastcluster-1.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fcb0973ca0e6978e3242046338c350cbed1493108929231fae9bd35ad05a6d6"}, - {file = "fastcluster-1.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9020899b67fe492d0ed87a3e993ec9962c5a0b51ea2df71d86b1766f065f1cef"}, - {file = "fastcluster-1.2.6-cp310-cp310-win32.whl", hash = "sha256:6cf156d4203708348522393c523c2e61c81f5a6a500e0411dcba2b064551ea2f"}, - {file = "fastcluster-1.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:1801c9daa9aa5bbbb0830efe8bd3034b4b7a417e4b8dd353683999be29797df2"}, - {file = "fastcluster-1.2.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ce70c743490f6778b463524d1767a9ecccd31c8bd2dbb5739bb2174168c15d39"}, - {file = "fastcluster-1.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac1b84d4b28456a379a71451d13995eb3242143452ce9c861f8913360de842a3"}, - {file = "fastcluster-1.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:55b49f6033c45a28f93540847b495ed0f718b5c3f4fef446cf77e3726662e1d5"}, - {file = "fastcluster-1.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1c776a4ec7594f47cd2e1e2da73a30134f1d402d7c93a81e3cb7c3d8e191173"}, - {file = "fastcluster-1.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aca61d16435bb7aea3901939d7d7d7e36aff9bb538123e649166a3014b280054"}, - {file = "fastcluster-1.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04ea4a68e0675072ca761bad33322a0e998cb43693fd41165bc420d7db40429a"}, - {file = "fastcluster-1.2.6-cp311-cp311-win32.whl", hash = "sha256:773043d5db2790e1ff2a4e1eae0b6a60afb2a93ad2c74897a56c80bc800db04f"}, - {file = "fastcluster-1.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:841d128daa6597d13781793eb482b0b566bbd58d2a9d1e2cf1b58838773beb14"}, - {file = "fastcluster-1.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cf5acfe1156849279ebd44a8d1fbcbe8b8e21334f7538eda782ae31e7dade9e2"}, - {file = "fastcluster-1.2.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb27c13225f5f77f3c5986a27ca27277cce7db12844330cf535019cd38021257"}, - {file = "fastcluster-1.2.6-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fe543b6d45da27e84e5af6248722475b88943d8ef40d835cbabbb0ba5ee786b"}, - {file = "fastcluster-1.2.6-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c12224da0b1f2f9d2b3d715dc82ecb1a3a33b990606f97da075cc46bc6d9576f"}, - {file = "fastcluster-1.2.6-cp36-cp36m-win32.whl", hash = "sha256:86a1ad972e83ba48144884fa849f87626346308b650002157123aee67d3b16fe"}, - {file = "fastcluster-1.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:8d3c9eab8e69cb36dcdd64c8b3200e008aedf88e34d39e01ae6af98a9605ad18"}, - {file = "fastcluster-1.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c61be0bad81a21ee3e5bef91469fdd11968f33d41d142c656accba9b2992babe"}, - {file = "fastcluster-1.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06df1d97edca68b2ffa43d81c3b5f4e4147bc12ab241c6585fadcdeb0bfa23ca"}, - {file = "fastcluster-1.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab9337b0a6a9b07b6f86fc724972d1ad729c890e2f539c1b33271c2f1f00af8b"}, - {file = "fastcluster-1.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4093d5454bcbe48b30e32da5db43056a08889480a96e4555f28c1f7004fc5323"}, - {file = "fastcluster-1.2.6-cp37-cp37m-win32.whl", hash = "sha256:58958a0333e3dfbad198394e9b7dd6254de0a3e622019b057288405b2a4a6bba"}, - {file = "fastcluster-1.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:03f8efe6435a7b947fa4a420676942d0267dac0d323ec5ead50f1856cc7cf96f"}, - {file = "fastcluster-1.2.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a5ceb39379327316d34613f7c16c06d7a3816aa38f4437b5e8433aa1bf149e2c"}, - {file = "fastcluster-1.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0bb54283b4d5ec96f167c7fd31921f169226c1261637434fdae7a69ee3c69573"}, - {file = "fastcluster-1.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6e51db0067e65687a5c46f00a11843d0bb15ca759e8a1767eebac8c4f6e3f4df"}, - {file = "fastcluster-1.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11748a4e245c745030e9ddd8c2c37e378f8ad8bd8e869d954c84ff674495499f"}, - {file = "fastcluster-1.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7254f81dc71cd29ef6f2d9747cf97ff907b569c9ef9d9760352391be5b57118c"}, - {file = "fastcluster-1.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa4a4c01c5fbec3623e92bc33a9f712ca416ce93255c402f5c904ac4b890ac3c"}, - {file = "fastcluster-1.2.6-cp38-cp38-win32.whl", hash = "sha256:ffdb00782cd63bbf2c45bb048897531e868326dff5081ab9b752d294b0426c1d"}, - {file = "fastcluster-1.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:a952a84453123db0c2336b9a9c86162e99ad0b897bae8213107c055a64effd41"}, - {file = "fastcluster-1.2.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a085e7e13f1afc517358981b2b7ed774dc9abf95f2be0da9a495d9e6b58c4409"}, - {file = "fastcluster-1.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a7c7f51a6d2f5ab58b1d85e9d0af2af9600ec13bb43bc6aafc9085d2c4ccd93"}, - {file = "fastcluster-1.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8bac5cf64691060cf86b0752dd385ef1eccff6d24bdb8b60691cf8cbf0e4f9ef"}, - {file = "fastcluster-1.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060c1cb3c84942d8d3618385e2c25998ba690c46ec8c73d64477f808abfac3f2"}, - {file = "fastcluster-1.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03a228e018457842eb81de85be7af0b5fe8065d666dd093193e3bdcf1f13d2e"}, - {file = "fastcluster-1.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6f8da329c0032f2acaf4beaef958a2db0dae43d3f946f592dad5c29aa82c832"}, - {file = "fastcluster-1.2.6-cp39-cp39-win32.whl", hash = "sha256:eb3f98791427d5d5d02d023b66bcef61e48954edfadae6527ef72d70cf32ec86"}, - {file = "fastcluster-1.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:4b9cfd426966b8037bec2fc03a0d7a9c87313482c699b36ffa1432b49f84ed2e"}, - {file = "fastcluster-1.2.6.tar.gz", hash = "sha256:aab886efa7b6bba7ac124f4498153d053e5a08b822d2254926b7206cdf5a8aa6"}, -] - -[package.dependencies] -numpy = ">=1.9" - -[package.extras] -test = ["scipy (>=1.6.3)"] - -[[package]] -name = "fastjsonschema" -version = "2.18.0" -description = "Fastest Python implementation of JSON schema" -optional = false -python-versions = "*" -files = [ - {file = "fastjsonschema-2.18.0-py3-none-any.whl", hash = "sha256:128039912a11a807068a7c87d0da36660afbfd7202780db26c4aa7153cfdc799"}, - {file = "fastjsonschema-2.18.0.tar.gz", hash = "sha256:e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd"}, -] - -[package.extras] -devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] - -[[package]] -name = "fastrlock" -version = "0.8.1" -description = "Fast, re-entrant optimistic lock implemented in Cython" -optional = false -python-versions = "*" -files = [ - {file = "fastrlock-0.8.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:e88ad64610f709daf6763fcb73b1640489d6cc3065761f0a9a42e83e0a0ce8da"}, - {file = "fastrlock-0.8.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:54bcea11203dd0af2b4d783487f12f4f977c098be74a56c4c4d7b60ec793e7b7"}, - {file = "fastrlock-0.8.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3068a7497bf3e58c71835c79c27b05b1726f45a1c5c8c333be56ce6643285e31"}, - {file = "fastrlock-0.8.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:62168061441c2656e440f401f6d8ebd0af94fac3e662782d12ade08b4c11e8e9"}, - {file = "fastrlock-0.8.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8d4e59933a81a62ed85e7df62991120eace969ea15e4ca3321264b4ab320b76a"}, - {file = "fastrlock-0.8.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:cf3e5703e60f88a85d615e36212e411f1fce6cabfad9cc84fe3b9877b133b3c2"}, - {file = "fastrlock-0.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b84fb655c281bdd35376fc7bd35ff9eba647fe1d0fe770f62f6e64522f894f72"}, - {file = "fastrlock-0.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:f836adcdfe3d825e303aca6d26f6c58620fe6d50e86568df741ba96892c37a09"}, - {file = "fastrlock-0.8.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d6c53abeae3f9a55b5c65824cec9df59159fa50e8fa800a5c6e8de42b2219c28"}, - {file = "fastrlock-0.8.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:77dd26848251efdf216779eb7581f7bdf99893b34f6e7e8989cc92b580f20189"}, - {file = "fastrlock-0.8.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0055ba81eb3c4c18345cd229eee9952315e4ecedd9d41793c077892a7823be8f"}, - {file = "fastrlock-0.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:b3c7738911053b418046b57fdc034a67d104fbc597b2391bee663a24f4299314"}, - {file = "fastrlock-0.8.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:fc92b5de2a5c1da603e545056b816f7b3db3d46beccfcffe8dc0d8f0df7cfc6e"}, - {file = "fastrlock-0.8.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5c59b5de879bb2890a644dbe24c592467219bcf7c5c7388fb200e0022e3b741a"}, - {file = "fastrlock-0.8.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:d19841bf61a4ff671a761040815917880a153e8543d1f147537389af5cbc604a"}, - {file = "fastrlock-0.8.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e7c416807063cadaf9f3f64debf5791d943dcde9089ac71016e8ca010dabaa7f"}, - {file = "fastrlock-0.8.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:30311e09594ac0806aad517da6e0c06510f2c2fc3f8b3b2c1ae6172460fd4f6a"}, - {file = "fastrlock-0.8.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4d1322aa0ffe702e1cc3c002e302edea5f6b8a3af096a7b340b7f719a577669c"}, - {file = "fastrlock-0.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:e683e2eb35058d4ba8576f9180f133b2367723d6ea4c3d1a3559894c8b7c9f33"}, - {file = "fastrlock-0.8.1-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:826b7dbf89c4157134bc96c9df0ef2cc99f8fe2abb38bd080a0acc34172bf7df"}, - {file = "fastrlock-0.8.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e6acadda18125c972b73c4787adbf688c5aa140015ea3632f38d9119cf09214"}, - {file = "fastrlock-0.8.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:65d77bfca60672e6ccafcac7b6533d275b626a060fefa6e297cf3430b8357427"}, - {file = "fastrlock-0.8.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:a2671b4c6fe6dff7eb83da7cf510894c83d88e4f5ca9a7515f70bc2daff31c4c"}, - {file = "fastrlock-0.8.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:551b70cd6aad03094f977f87c1ea5b19b6036eae340c2181164d15e5602e5fcb"}, - {file = "fastrlock-0.8.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:d0c97035aca21c4b56b4ecb15d006adc0e9277ee8479fe3d709bbc261ff7c8a9"}, - {file = "fastrlock-0.8.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:af58fc057de699dfcd9a3e16c3204696b5155ed931ccc2ec3e8e9123e56343f9"}, - {file = "fastrlock-0.8.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:bb7dfe068b9925cadabf14539e4201c3391da255a6bb2d7a42e2d8b6bb167329"}, - {file = "fastrlock-0.8.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cdba150ab6334f94055e54e3ebda03b9804fb09ad8ebd453af4bc47ad9ddfc17"}, - {file = "fastrlock-0.8.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:51c3200a11797986c85c48102c0ce35f6c53b709ef123b9ac1d07c3617307125"}, - {file = "fastrlock-0.8.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ec258de18ad41b9e251173d64afe70da83f852b612cf5fc51e64ad0408a0a973"}, - {file = "fastrlock-0.8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ed84c5d813abf02c809513fe286dac8a21cace71c0a4b6cb344b1aab0571a403"}, - {file = "fastrlock-0.8.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:3a7888ce976a6d0ad699c2bdca6571beec482f460cb917978abb8c60f8150219"}, - {file = "fastrlock-0.8.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d67418209ed0f3a0ff5ca79a8b4a05d4d5711cedd99a45223858bd0826c9112d"}, - {file = "fastrlock-0.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:713158684a3c20134b55ee2442616dfba3e6bab9817dd7a8b230afecb331176e"}, - {file = "fastrlock-0.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a422bfdaaf896d8e7be6e082d7c59bfca56daa6fdd85023f4f63bfa088f7fd3f"}, - {file = "fastrlock-0.8.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f5b32366e63b5f150ce58efd0d64754310960b4cae81a2c45bf956284188271e"}, - {file = "fastrlock-0.8.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e88260af5a94afe3516e8819a3f77fe604fa4c71e7d4d7c96ae92f84408146e2"}, - {file = "fastrlock-0.8.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2d7bcbd5258d7d2dbe1c8719c3faf6b2f62e609b51c0c80216ea624d2c423357"}, - {file = "fastrlock-0.8.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:537423c21e3f582b044d6aa2da7a813785e80328054099a6913545f68474b088"}, - {file = "fastrlock-0.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cd55b2669a62f2a0eb3fa7bedc4bcca0663440ffa5401f3dc1bd2a3394fca766"}, - {file = "fastrlock-0.8.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:252cd40c2d8a412e238213d494e920d74439ae2d480ff83d72b23270cc218497"}, - {file = "fastrlock-0.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b9bea96dfb18fd1fbd7e18f9e2ee6868691e1c99a3dc111c267a97e49acbecba"}, - {file = "fastrlock-0.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:4459f0743af5b4ad5ace4bbb65162e60ed320437dcf473bf60a9f4a9a188b5cd"}, - {file = "fastrlock-0.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1bccd6d2ae63995f3f0cd25770f39858f0802e45b95325f406d3fce19c41834d"}, - {file = "fastrlock-0.8.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:3e4c0ada1ce907a5616046eb219eb40ea0ff2bb27f4da703925c32af1537f43a"}, - {file = "fastrlock-0.8.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b864db14be48ff32d37aee0dcd61910274742f84fcced17a0f291f985e0abdca"}, - {file = "fastrlock-0.8.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2db49fd0166fb61ab00e8d3fe55ae5cbb9d566df42ccf188ab482401fc7ac5d"}, - {file = "fastrlock-0.8.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d38943c3e015bd92ea6b8f155eb829000fc291edad21fc58ca0acbb8dd06788f"}, - {file = "fastrlock-0.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:c00c4e090ff5204830e49cccebb41372f800970466725b184089a40ca332c897"}, - {file = "fastrlock-0.8.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:187786a0bdb8c5c59d8ed6f82846306e63169c3c5437c847c548dfaf548ee958"}, - {file = "fastrlock-0.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:801bee6ef607c2020818d006677704e20997d61524cfa1f338e141a6f017b7dd"}, - {file = "fastrlock-0.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:73f1df1d1e141b0e2cedc40536ee745247f0bf968526535eb9e2e7acd85e7535"}, - {file = "fastrlock-0.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eb5bb4187880f6944b6213728e3e8617a4613fa9d1303fea84d0227cd81943af"}, - {file = "fastrlock-0.8.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:294b60ed41b746e99189260f7dc42a8c280c59c9aa9e152f89752fc102f2eefa"}, - {file = "fastrlock-0.8.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e5122103f38c9ebdb597304b2bed3b4c3b9f2c372d649eff2f7c3be70f8f7fc1"}, - {file = "fastrlock-0.8.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:625372f1e19c80fc90b83a167bedc785855ea63c0deb2e66aab922e346dd9517"}, - {file = "fastrlock-0.8.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:36fdc86df2cfa7f1692cdb035338dd7f952fa50e5ea8e39569e15ff4269a8e1a"}, - {file = "fastrlock-0.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6e97a68d67bd4b19948bc119252dc2b473dbcb301aa319ae98246d86281d2b9d"}, - {file = "fastrlock-0.8.1.tar.gz", hash = "sha256:8a5f2f00021c4ac72e4dab910dc1863c0e008a2e7fb5c843933ae9bcfc3d0802"}, -] - [[package]] name = "filelock" version = "3.12.2" @@ -2214,119 +1016,6 @@ files = [ docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] -[[package]] -name = "fiona" -version = "1.9.4.post1" -description = "Fiona reads and writes spatial data files" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Fiona-1.9.4.post1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:d6483a20037db2209c8e9a0c6f1e552f807d03c8f42ed0c865ab500945a37c4d"}, - {file = "Fiona-1.9.4.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dbe158947099a83ad16f9acd3a21f50ff01114c64e2de67805e382e6b6e0083a"}, - {file = "Fiona-1.9.4.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2c7b09eecee3bb074ef8aa518cd6ab30eb663c6fdd0eff3c88d454a9746eaa"}, - {file = "Fiona-1.9.4.post1-cp310-cp310-win_amd64.whl", hash = "sha256:1da8b954f6f222c3c782bc285586ea8dd9d7e55e1bc7861da9cd772bca671660"}, - {file = "Fiona-1.9.4.post1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c671d8832287cda397621d79c5a635d52e4631f33a8f0e6fdc732a79a93cb96c"}, - {file = "Fiona-1.9.4.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b633a2e550e083805c638d2ab8059c283ca112aaea8241e170c012d2ee0aa905"}, - {file = "Fiona-1.9.4.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1faa625d5202b8403471bbc9f9c96b1bf9099cfcb0ee02a80a3641d3d02383e"}, - {file = "Fiona-1.9.4.post1-cp311-cp311-win_amd64.whl", hash = "sha256:39baf11ff0e4318397e2b2197de427b4eebdc49d4a9a7c1366f8a7ed682978a4"}, - {file = "Fiona-1.9.4.post1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d93c993265f6378b23f47708c83bddb3377ca6814a1f0b5a0ae0bee9c8d72cf8"}, - {file = "Fiona-1.9.4.post1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:b0387cae39e27f338fd948b3b50b6e6ce198cc4cec257fc91660849697c69dc3"}, - {file = "Fiona-1.9.4.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:450561d308d3ce7c7e30294822b1de3f4f942033b703ddd4a91a7f7f5f506ca0"}, - {file = "Fiona-1.9.4.post1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71b023ef5248ebfa5524e7a875033f7db3bbfaf634b1b5c1ae36958d1eb82083"}, - {file = "Fiona-1.9.4.post1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74511d3755695d75cea0f4ff6f5e0c6c5d5be8e0d46dafff124c6a219e99b1eb"}, - {file = "Fiona-1.9.4.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:285f3dd4f96aa0a3955ed469f0543375b20989731b2dddc85124453f11ac62bc"}, - {file = "Fiona-1.9.4.post1-cp38-cp38-win_amd64.whl", hash = "sha256:a670ea4262cb9140445bcfc97cbfd2f508a058be342f4a97e966b8ce7696601f"}, - {file = "Fiona-1.9.4.post1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:ea7c44c15b3a653452b9b3173181490b7afc5f153b0473c145c43c0fbf90448b"}, - {file = "Fiona-1.9.4.post1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7bfb1f49e0e53f6cd7ad64ae809d72646266b37a7b9881205977408b443a8d79"}, - {file = "Fiona-1.9.4.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a585002a6385cc8ab0f66ddf3caf18711f531901906abd011a67a0cc89ab7b0"}, - {file = "Fiona-1.9.4.post1-cp39-cp39-win_amd64.whl", hash = "sha256:f5da66b723a876142937e683431bbaa5c3d81bb2ed3ec98941271bc99b7f8cd0"}, - {file = "Fiona-1.9.4.post1.tar.gz", hash = "sha256:5679d3f7e0d513035eb72e59527bb90486859af4405755dfc739138633106120"}, -] - -[package.dependencies] -attrs = ">=19.2.0" -certifi = "*" -click = ">=8.0,<9.0" -click-plugins = ">=1.0" -cligj = ">=0.5" -six = "*" - -[package.extras] -all = ["Fiona[calc,s3,test]"] -calc = ["shapely"] -s3 = ["boto3 (>=1.3.1)"] -test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] - -[[package]] -name = "flake8" -version = "6.1.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, - {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.1.0,<3.2.0" - -[[package]] -name = "flask" -version = "2.3.2" -description = "A simple framework for building complex web applications." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Flask-2.3.2-py3-none-any.whl", hash = "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0"}, - {file = "Flask-2.3.2.tar.gz", hash = "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef"}, -] - -[package.dependencies] -blinker = ">=1.6.2" -click = ">=8.1.3" -itsdangerous = ">=2.1.2" -Jinja2 = ">=3.1.2" -Werkzeug = ">=2.3.3" - -[package.extras] -async = ["asgiref (>=3.2)"] -dotenv = ["python-dotenv"] - -[[package]] -name = "flask-cors" -version = "4.0.0" -description = "A Flask extension adding a decorator for CORS support" -optional = false -python-versions = "*" -files = [ - {file = "Flask-Cors-4.0.0.tar.gz", hash = "sha256:f268522fcb2f73e2ecdde1ef45e2fd5c71cc48fe03cffb4b441c6d1b40684eb0"}, - {file = "Flask_Cors-4.0.0-py2.py3-none-any.whl", hash = "sha256:bc3492bfd6368d27cfe79c7821df5a8a319e1a6d5eab277a3794be19bdc51783"}, -] - -[package.dependencies] -Flask = ">=0.9" - -[[package]] -name = "flask-socketio" -version = "5.3.5" -description = "Socket.IO integration for Flask applications" -optional = false -python-versions = ">=3.6" -files = [ - {file = "Flask-SocketIO-5.3.5.tar.gz", hash = "sha256:5f01158d10db71aa78c969b631ce3b9148b47ab0de1995158f9577f85b004d25"}, - {file = "Flask_SocketIO-5.3.5-py3-none-any.whl", hash = "sha256:04d42f2b7c2c3bdfea83b62e53f999374c573c698eddb53c468fca2bf75c1d3c"}, -] - -[package.dependencies] -Flask = ">=0.9" -python-socketio = ">=5.0.2" - -[package.extras] -docs = ["sphinx"] - [[package]] name = "flatbuffers" version = "23.5.26" @@ -2395,17 +1084,6 @@ ufo = ["fs (>=2.2.0,<3)"] unicode = ["unicodedata2 (>=15.0.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] -[[package]] -name = "fqdn" -version = "1.5.1" -description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -optional = false -python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" -files = [ - {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, - {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, -] - [[package]] name = "frozenlist" version = "1.4.0" @@ -2476,41 +1154,6 @@ files = [ {file = "frozenlist-1.4.0.tar.gz", hash = "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251"}, ] -[[package]] -name = "fsspec" -version = "2023.6.0" -description = "File-system specification" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fsspec-2023.6.0-py3-none-any.whl", hash = "sha256:1cbad1faef3e391fba6dc005ae9b5bdcbf43005c9167ce78c915549c352c869a"}, - {file = "fsspec-2023.6.0.tar.gz", hash = "sha256:d0b2f935446169753e7a5c5c55681c54ea91996cc67be93c39a154fb3a2742af"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -devel = ["pytest", "pytest-cov"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -tqdm = ["tqdm"] - [[package]] name = "ft4222" version = "1.8.1" @@ -2549,16 +1192,6 @@ files = [ {file = "ft4222-1.8.1.tar.gz", hash = "sha256:6532ae1265e4b81416c51def060c2a3bf26494a83b644ec7db5cc273756e03c6"}, ] -[[package]] -name = "future" -version = "0.18.3" -description = "Clean single-source support for Python 3 and 2" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "future-0.18.3.tar.gz", hash = "sha256:34a17436ed1e96697a86f9de3d15a3b0be01d8bc8de9c1dffd59fb8234ed5307"}, -] - [[package]] name = "future-fstrings" version = "1.2.0" @@ -2573,188 +1206,6 @@ files = [ [package.extras] rewrite = ["tokenize-rt (>=3)"] -[[package]] -name = "geoalchemy2" -version = "0.14.1" -description = "Using SQLAlchemy with Spatial Databases" -optional = false -python-versions = ">=3.7" -files = [ - {file = "GeoAlchemy2-0.14.1-py3-none-any.whl", hash = "sha256:0830c98f83d6b1706e62b5544793d304e2853493d6e70ac18444c13748c3d1c7"}, - {file = "GeoAlchemy2-0.14.1.tar.gz", hash = "sha256:620b31cbf97a368b2486dbcfcd36da2081827e933d4163bcb942043b79b545e8"}, -] - -[package.dependencies] -packaging = "*" -SQLAlchemy = ">=1.4" - -[package.extras] -shapely = ["Shapely (>=1.7)"] - -[[package]] -name = "geopandas" -version = "0.13.2" -description = "Geographic pandas extensions" -optional = false -python-versions = ">=3.8" -files = [ - {file = "geopandas-0.13.2-py3-none-any.whl", hash = "sha256:101cfd0de54bcf9e287a55b5ea17ebe0db53a5e25a28bacf100143d0507cabd9"}, - {file = "geopandas-0.13.2.tar.gz", hash = "sha256:e5b56d9c20800c77bcc0c914db3f27447a37b23b2cd892be543f5001a694a968"}, -] - -[package.dependencies] -fiona = ">=1.8.19" -packaging = "*" -pandas = ">=1.1.0" -pyproj = ">=3.0.1" -shapely = ">=1.7.1" - -[[package]] -name = "gevent" -version = "23.7.0" -description = "Coroutine-based network library" -optional = false -python-versions = ">=3.8" -files = [ - {file = "gevent-23.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:add904a7ef960cd4e133e61eb7413982c5e4203928160be1c09752ac06a25e71"}, - {file = "gevent-23.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bd9ea1b5fbdc7e5921a9e515f34a450eb3927a902253a33caedcce2d19d7d96"}, - {file = "gevent-23.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c7c349aa23d67cf5cc3b2c87aaedcfead976d0577b1cfcd07ffeba63baba79c"}, - {file = "gevent-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c92b837b60e850c50fc6d723d1e363e786d37fd9d51e564e07df52ad5e8a86d4"}, - {file = "gevent-23.7.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6a51a8e3cdaa6901e47d56f84cb5f92b1bf3deea920bce69cf7a245df16159ac"}, - {file = "gevent-23.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1dba07207b15b371e50372369edf256a142cb5cdf8599849cbf8660327efa06"}, - {file = "gevent-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:34086bcc1252ae41e1cb81cf13c4a7678031595c12f4e9a1c3d0ab433f20826a"}, - {file = "gevent-23.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5da07d65dfa23fe419c37cea110bf951b42af6bf3a1fff244043a75c9185dbd5"}, - {file = "gevent-23.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df4d7be3352126458cc818309ca6a3b678c209b1ae33e56b6975c6a8309f2068"}, - {file = "gevent-23.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76ca6f893953ab898ebbff5d772103318a85044e55d0bad401d6b49d71bb76e7"}, - {file = "gevent-23.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aeb1511cf0786152af741c47ee462dac81b57bbd1fbbe08ab562b6c8c9ad75ed"}, - {file = "gevent-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919423e803939726c99ab2d29ea46b8676af549cee72d263f2b24758ec607b2c"}, - {file = "gevent-23.7.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cea93f4f77badbddc711620cca164ad75c74056603908e621a5ba1b97adbc39c"}, - {file = "gevent-23.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dec7b08daf08385fb281b81ec2e7e703243975d867f40ae0a8a3e30b380eb9ea"}, - {file = "gevent-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:f522b6b015f1bfa9d8d3716ddffb23e3d4a8933df3e4ebf0a29a65a9fa74382b"}, - {file = "gevent-23.7.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:746a1e12f280dab07389e6709164b1e1a6caaf50493ea5b1dcaa73cff005174c"}, - {file = "gevent-23.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b230007a665d2cf5cf8878c9f56a2b8bacbdc4fe0235afc5269b71cd00528e5"}, - {file = "gevent-23.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1d2f1e67d04fde47ca2deac89733df28ef3a7ec1d7359a79f57d4778cced16d"}, - {file = "gevent-23.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:debc177e88a8c876cb1a4d974f985d03670177bdc61e1c084a8d525f1a50b12d"}, - {file = "gevent-23.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b3dd449c80814357f6568eb095a2be2421b805d59fa97c65094707e04a181f9"}, - {file = "gevent-23.7.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:769e8811ded08fe7d8b09ad8ebb72d47aecc112411e0726e7296b7ed187ed629"}, - {file = "gevent-23.7.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11b9bb0bce45170ff992760385a86e6955ccb88dba4a82a64d5ce9459290d8d6"}, - {file = "gevent-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e0d76a7848726e0646324a1adc011355dcd91875e7913badd1ada2e5eeb8a6e"}, - {file = "gevent-23.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a226b42cb9a49580ca7729572a4f8289d1fa28cd2529c9f4eed3e14b995d1c9c"}, - {file = "gevent-23.7.0-cp38-cp38-win32.whl", hash = "sha256:1234849b0bc4df560924aa92f7c01ca3f310677735fb508a2b0d7a61bb946916"}, - {file = "gevent-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:a8f62e8d37913512823923e05607a296389aeb50ccca8a271ae7cedb5b17faeb"}, - {file = "gevent-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369241d1a6a3fe3ef4eba454b71e0168026560c5344fc4bc37196867041982ac"}, - {file = "gevent-23.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:94b013587f7c4697d620c129627f7b12d7d9f6e40ab198635891ca2098cd8556"}, - {file = "gevent-23.7.0-cp39-cp39-win32.whl", hash = "sha256:83b6d61a8e9da25edb304ca7fba19ee57bb1ffa801f9df3e668bfed7bb8386cb"}, - {file = "gevent-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:8c284390f0f6d0b5be3bf805fa8e0ae1329065f2b0ac5af5423c67183197deb8"}, - {file = "gevent-23.7.0.tar.gz", hash = "sha256:d0d3630674c1b344b256a298ab1ff43220f840b12af768131b5d74e485924237"}, -] - -[package.dependencies] -cffi = {version = ">=1.12.2", markers = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\""} -greenlet = {version = ">=2.0.0", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} -"zope.event" = "*" -"zope.interface" = "*" - -[package.extras] -dnspython = ["dnspython (>=1.16.0,<2.0)", "idna"] -docs = ["furo", "repoze.sphinx.autointerface", "sphinx", "sphinxcontrib-programoutput", "zope.schema"] -monitor = ["psutil (>=5.7.0)"] -recommended = ["cffi (>=1.12.2)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)"] -test = ["cffi (>=1.12.2)", "coverage (>=5.0)", "dnspython (>=1.16.0,<2.0)", "idna", "objgraph", "psutil (>=5.7.0)", "requests", "setuptools"] - -[[package]] -name = "geventhttpclient" -version = "2.0.2" -description = "http client library for gevent" -optional = false -python-versions = "*" -files = [ - {file = "geventhttpclient-2.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd76acdc7e7ee5c54c7b279f806b28957a6b092f79c40db34adcfd972749343c"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:320a2c756d8a4f296de370476a1515485c186d9e22c3fc29e04f8f743a7d47bb"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36d3345c6585b09738195a7c45d279a87ccbab0350f1cce3679d3f0dce8577a1"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:407d54499556c2741b93691b86da93232590b013f4a0b773327d766fe3e5c0a9"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcf325131b0e4600b793643108cd85dddd66bbf532fd2eb498be5727ef532a1e"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5841dd02e6f792a4ef15dbd04fefe620c831ba0b78105808160bb779a31af4"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2ba69422d4e8670dd99803b1313ba574a4d41f52e92b512af51068c9c577bdc1"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e3af579c6b46b9caa515a8baf6a2cadeafcd1d41ad22ca5712851f074a40b47"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ff7fc19f9a4fdd54a2b1c106a705ea2c679fa049685ed763051d417725bdab1"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-win32.whl", hash = "sha256:eec7c52e8eb817674a193e0124486b507215d9e86d34f2638bf9a9292d16f815"}, - {file = "geventhttpclient-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e9f7283c01d970e643d89da81127869a8d94bb7a0081020dcad5b590bc007c4"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5ceb492d43a659b895794999dc40d0e7c23b1d41dd34040bbacd0dc264b57d5b"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95959c201d3151fa8f57e0f1ce184476d1173996bdde41dc7d600006023dc5be"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:31c7febba298ecf44838561074a3fb7a01523adca286469b5a82dcc90e8d6a07"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:996c5f453d810b3c592160193d6832a065cca0112e92adc74e62df0e4c564df6"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f817e226c02b5a71d86de3772d6accdf250288d1e6825e426c713759830162d"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c55b7ac0ba0e1e1afbf297b7608f0b3a0bbc34fb4b0c19b7869f32a77ddc6209"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6775bc81e25c48fa58b034444aecfa508b0c3d1bc1e4ae546cc17661be1f51aa"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a0156882c73537bbbbc7c693ae44c9808119963174078692613ffa4feea21fcf"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3ebb582a291c4c5daaac2ea115b413f4be86874baa60def44d333301cee17bd7"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-win32.whl", hash = "sha256:716f1f72f50b841daf9c9511a01fc31a030866510a11863f27741e26e4f556a7"}, - {file = "geventhttpclient-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:777fcdb72077dfbf70516ecb9e9022246dd337b83a4c1e96f17f3ab9e15f4547"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:379d90d8b1fcdda94e74d693806e0b0116c0610504e7f62d5576bac738dc66a5"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00b7b2b836294c091c53789a469c5671202d79420b5191931df4e3a767d607fa"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d075355862d7726eb3436f0136fce7650c884f2d04eaae7a39fed3aad9798bc"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa7b1a27f950d209fe223a97906fe41312dc12c92372424639b8a9b96f1adf91"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fe4e06313aad353b103950780b050d3958000464cc732d621ff8ea3cacbd2bc4"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:84d7be660b6bc53dd53e3f46b3bc5d275972a8116bd183a77139bb4d9d6d9fb1"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:81f839d6becd664d0972b488422f5dc821f8ad2f2196d53aa5e4d799a3a35a66"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:e707f62271a093e6e3af6f1bbd8cc398b414b8c508fe6b15505dd8e76c4409ac"}, - {file = "geventhttpclient-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:28d7655d1d50bc75ece683a0ae8faf978821d4aeae358d77b59371548db07f1e"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58877b4440a580063571a23fbc616aed7c735c6bf9ef525c5129783df8b6966"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57c993c4b2bea551c4a71b75ae1e172e9f3e4352f704ff1b619a0f16aa762f76"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f67e789e31c7b1ce440cd1465dcdefeca29ba6108735eac0b1a593d3a55b7f"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f3326e115ec7e7ce95a5d0d47698e8f3584944c4c434a7404937d56b17136b8"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ef328ee3e7dca5055b833fdf3c181647a335abf0249947b27f5df2d95390198c"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:27049ea40e3b559eee380310272aaa9b7c19e73c1d9e51e2ec137362be2caa70"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b88a10538341e33fed1682c0dd4579c655d49db5863e7456583085a1cd6bd9d4"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:d52aba2c38420b3fc518188449f1c2a46b1a99adf1c0266c68e72ee0422cd0fa"}, - {file = "geventhttpclient-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3648626ca58ea4b340e695d78e5d533e6b8be78d375edbd42ff188bc3447e095"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fcf96e212b55b93490f3a5fcdfe7a2ef4995a0d13b7d9df398b11e319b7a86b1"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e9f2ff09706e3a64a99886d5f2595f3bf364821bc609f2865dbc3e499e21a36"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:721c3075897bfc81e918066f16ae3d1a88c7bb14eeeb831a4f89ea636474643e"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91615fed7931acd49cfe5fc30984acd5411dc1f2643b1544c879d1a537233c6d"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7adaa29e5699dea54e0224d1d2d9d8869668d8ad79f5b89433ff9c46f9424a6c"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9be5000ba57336a90b438782117c1e43205f51f49aa9b1499a82e210e8431b11"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12d271cc53486efb3716e99855dc5cb84f2cd3fc9f3243721747bb39ec0fff8a"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b9c0c6b75b3905000d2490dc64b4c98a8bac155efbc0ff8917ac082ae0bad261"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e956a457d8831dc81d6f046ab09ebeec680f9a1e9c07e25a1906e77b287918ee"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-win32.whl", hash = "sha256:bc46d5479673dfb293ea428c057d2e23e48ebef5c5d44587cdbaada7f87553e4"}, - {file = "geventhttpclient-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:f44153e4b3ef9b901edcd14be54145a0058bf5fa371b3e583153865fac866245"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ebf98db9435824cf0b80b5247be6c88b20bfafd6249f7ebaabb85297da37e380"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c8b7298eb1ebd015257bf4503e34f5fbbe64bd83324140f76b511046aba5a0d5"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:60b81a6d4e65db7c1a5350c9fb72ebf800b478849a7e8020d1ab93af237a3747"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad6c2fcbc3733785bd3b8c2bb43d1f605f9085b0a8b70ce354d198f37143f884"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94edb022fa50d576cf63f6dd0c437c1acd24a719872a5935991aaf08f8e88cb2"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ca459cedb3827d960362e05ea3a4ae600a6d0d93de77eac2ac0f79828e5e18c"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7551b6db860b56411de1f96618e91b54f65e1a7be8d10255bd1adfb738bb6ee5"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bcb7e061c243308d9a44b02de5298001e917f1636a9f270c10da86601fcc8dfa"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:96922d170ef8933f4c20036e8d70d4fbe861f54c543e32e7459ebdbaafa65a2e"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ebb3c993903d40fd4bb1f3e55b84c62c8fc1d14433ae6d4d477dd9a325354c94"}, - {file = "geventhttpclient-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:dbccf1ba155dea3ea99ba0e67a835c05b4303f05298e85f5bb2a46700ccdf092"}, - {file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8770b8ab9e8c31d2aaf8a6fbc63fbb7239c58db10bb49cee191ca5c141c61542"}, - {file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daff1e977fccf98f27266d3891afdc101f1d705a48331754909e960bcae83f8a"}, - {file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2435e0f2a60e00d977822ec4c12e7851deb7aa49a23d32d648e72c641aae3b05"}, - {file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09acd03d0a8c1bb7d5a1cb6fcb77aaa19a907c1b4915ab58da5d283675edb0a5"}, - {file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5d0813d97050446dab2fb243312e6c446e4ef5e9591befd597ef8f2887f8e2a8"}, - {file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:852da9bb0fc792cdca5ffc9327490094783e42415494b3569e5d532615027439"}, - {file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79304a63a9d0512f2757c5862487b332b18a9c85feebecf6ebc3526c6dd1ba2"}, - {file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c1c783fce45f16db448d7e34864f1e9c22fe60a7780d2c1c14edbb1fb7262e"}, - {file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77c407c2b4bea817c6f752502db4ab0e9f9465b4fb85b459d1332b5f93a3096c"}, - {file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f0d70a83ef4ab93102c6601477c13e9cdbc87205e5237fbf5797e30dc9d3ee8"}, - {file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b03f298ec19b8a4717cce8112fe30322c9e5bfada84dde61a1a44d1eeffc1d3c"}, - {file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2dc94b9a23eb6744a8c729aec2b1cdc4e39acf1d8f16ea85a62810aa6b2cae5"}, - {file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:805554594bb29231fd990cc2cbbe493d223d76a6085fec891dd76bb4e0928933"}, - {file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb23527d98f626ca7a4e8961ed9bdc6aed3388de306614c69a133b34262460f4"}, - {file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a594ab319872a38fb7f16be4cfb107d3c63c43a081f2abe241834e9877f27401"}, - {file = "geventhttpclient-2.0.2.tar.gz", hash = "sha256:8135a85200b170def7293d01dd1557931fcd1bec1ac78c52ad7cedd22368b9ba"}, -] - -[package.dependencies] -brotli = "*" -certifi = "*" -gevent = ">=0.13" -six = "*" - [[package]] name = "google-crc32c" version = "1.5.0" @@ -2835,99 +1286,6 @@ files = [ [package.extras] testing = ["pytest"] -[[package]] -name = "greenlet" -version = "2.0.2" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" -files = [ - {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, - {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, - {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, - {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, - {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, - {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, - {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, - {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, - {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, - {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, - {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, - {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, - {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, - {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, - {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, - {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, - {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, - {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, - {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, - {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, - {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, - {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, - {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, - {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, - {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, - {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, - {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, - {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, - {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, - {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, - {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, - {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, - {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, - {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, - {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, - {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, - {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, - {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, -] - -[package.extras] -docs = ["Sphinx", "docutils (<0.18)"] -test = ["objgraph", "psutil"] - -[[package]] -name = "gunicorn" -version = "21.2.0" -description = "WSGI HTTP Server for UNIX" -optional = false -python-versions = ">=3.5" -files = [ - {file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"}, - {file = "gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -eventlet = ["eventlet (>=0.24.1)"] -gevent = ["gevent (>=1.4.0)"] -setproctitle = ["setproctitle"] -tornado = ["tornado (>=0.2)"] - [[package]] name = "h3" version = "3.7.6" @@ -3011,59 +1369,6 @@ files = [ {file = "hexdump-3.3.zip", hash = "sha256:d781a43b0c16ace3f9366aade73e8ad3a7bd5137d58f0b45ab2d3f54876f20db"}, ] -[[package]] -name = "html5lib" -version = "1.1" -description = "HTML parser based on the WHATWG HTML specification" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, - {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, -] - -[package.dependencies] -six = ">=1.9" -webencodings = "*" - -[package.extras] -all = ["chardet (>=2.2)", "genshi", "lxml"] -chardet = ["chardet (>=2.2)"] -genshi = ["genshi"] -lxml = ["lxml"] - -[[package]] -name = "huggingface-hub" -version = "0.16.4" -description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "huggingface_hub-0.16.4-py3-none-any.whl", hash = "sha256:0d3df29932f334fead024afc7cb4cc5149d955238b8b5e42dcf9740d6995a349"}, - {file = "huggingface_hub-0.16.4.tar.gz", hash = "sha256:608c7d4f3d368b326d1747f91523dbd1f692871e8e2e7a4750314a2dd8b63e14"}, -] - -[package.dependencies] -filelock = "*" -fsspec = "*" -packaging = ">=20.9" -pyyaml = ">=5.1" -requests = "*" -tqdm = ">=4.42.1" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "black (>=23.1,<24.0)", "gradio", "jedi", "mypy (==0.982)", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "ruff (>=0.0.241)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "urllib3 (<2.0)"] -cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "black (>=23.1,<24.0)", "gradio", "jedi", "mypy (==0.982)", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "ruff (>=0.0.241)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "urllib3 (<2.0)"] -fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] -inference = ["aiohttp", "pydantic"] -quality = ["black (>=23.1,<24.0)", "mypy (==0.982)", "ruff (>=0.0.241)"] -tensorflow = ["graphviz", "pydot", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["torch"] -typing = ["pydantic", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3"] - [[package]] name = "humanfriendly" version = "10.0" @@ -3075,9 +1380,6 @@ files = [ {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, ] -[package.dependencies] -pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""} - [[package]] name = "hypothesis" version = "6.46.7" @@ -3145,37 +1447,6 @@ files = [ {file = "ifaddr-0.2.0.tar.gz", hash = "sha256:cc0cbfcaabf765d44595825fb96a99bb12c79716b73b44330ea38ee2b0c4aed4"}, ] -[[package]] -name = "imageio" -version = "2.31.1" -description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." -optional = false -python-versions = ">=3.7" -files = [ - {file = "imageio-2.31.1-py3-none-any.whl", hash = "sha256:4106fb395ef7f8dc0262d6aa1bb03daba818445c381ca8b7d5dfc7a2089b04df"}, - {file = "imageio-2.31.1.tar.gz", hash = "sha256:f8436a02af02fd63f272dab50f7d623547a38f0e04a4a73e2b02ae1b8b180f27"}, -] - -[package.dependencies] -numpy = "*" -pillow = ">=8.3.2" - -[package.extras] -all-plugins = ["astropy", "av", "imageio-ffmpeg", "psutil", "tifffile"] -all-plugins-pypy = ["av", "imageio-ffmpeg", "psutil", "tifffile"] -build = ["wheel"] -dev = ["black", "flake8", "fsspec[github]", "pytest", "pytest-cov"] -docs = ["numpydoc", "pydata-sphinx-theme", "sphinx (<6)"] -ffmpeg = ["imageio-ffmpeg", "psutil"] -fits = ["astropy"] -full = ["astropy", "av", "black", "flake8", "fsspec[github]", "gdal", "imageio-ffmpeg", "itk", "numpydoc", "psutil", "pydata-sphinx-theme", "pytest", "pytest-cov", "sphinx (<6)", "tifffile", "wheel"] -gdal = ["gdal"] -itk = ["itk"] -linting = ["black", "flake8"] -pyav = ["av"] -test = ["fsspec[github]", "pytest", "pytest-cov"] -tifffile = ["tifffile"] - [[package]] name = "imagesize" version = "1.4.1" @@ -3187,25 +1458,6 @@ files = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] -[[package]] -name = "importlib-metadata" -version = "6.8.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] - [[package]] name = "importlib-resources" version = "6.0.1" @@ -3221,30 +1473,6 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] -[[package]] -name = "influxdb-client" -version = "1.37.0" -description = "InfluxDB 2.0 Python client library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "influxdb_client-1.37.0-py3-none-any.whl", hash = "sha256:30b03888846fab6fb740936b1a08af24841b791cf1b99773e3894dd1d64edf2f"}, - {file = "influxdb_client-1.37.0.tar.gz", hash = "sha256:01ac44d6a16a965ae2e0fa3238e2edeb147c11935a89b61439c9a752458001da"}, -] - -[package.dependencies] -certifi = ">=14.05.14" -python-dateutil = ">=2.5.3" -reactivex = ">=4.0.4" -setuptools = ">=21.0.0" -urllib3 = ">=1.26.0" - -[package.extras] -async = ["aiocsv (>=1.2.2)", "aiohttp (>=3.8.1)"] -ciso = ["ciso8601 (>=2.1.1)"] -extra = ["numpy", "pandas (>=0.25.3)"] -test = ["aioresponses (>=0.7.3)", "coverage (>=4.0.3)", "flake8 (>=5.0.3)", "httpretty (==1.0.5)", "jinja2 (==3.1.2)", "nose (>=1.3.7)", "pluggy (>=0.3.1)", "psutil (>=5.6.3)", "py (>=1.4.31)", "pytest (>=5.0.0)", "pytest-cov (>=3.0.0)", "pytest-timeout (>=2.1.0)", "randomize (>=0.13)", "sphinx (==1.8.5)", "sphinx-rtd-theme"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -3267,17 +1495,6 @@ files = [ {file = "inputs-0.5.tar.gz", hash = "sha256:a31d5b96a3525f1232f326be9e7ce8ccaf873c6b1fb84d9f3c9bc3d79b23eae4"}, ] -[[package]] -name = "installer" -version = "0.7.0" -description = "A library for installing Python wheels." -optional = false -python-versions = ">=3.7" -files = [ - {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"}, - {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"}, -] - [[package]] name = "ioctl-opt" version = "1.3" @@ -3288,217 +1505,6 @@ files = [ {file = "ioctl-opt-1.3.tar.gz", hash = "sha256:5ed4f9a80d2e02e152a43d3648d7ed8821a0aac5ea88ecc5fcc14460ff7cf2f9"}, ] -[[package]] -name = "ipykernel" -version = "6.25.1" -description = "IPython Kernel for Jupyter" -optional = false -python-versions = ">=3.8" -files = [ - {file = "ipykernel-6.25.1-py3-none-any.whl", hash = "sha256:c8a2430b357073b37c76c21c52184db42f6b4b0e438e1eb7df3c4440d120497c"}, - {file = "ipykernel-6.25.1.tar.gz", hash = "sha256:050391364c0977e768e354bdb60cbbfbee7cbb943b1af1618382021136ffd42f"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -comm = ">=0.1.1" -debugpy = ">=1.6.5" -ipython = ">=7.23.1" -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -matplotlib-inline = ">=0.1" -nest-asyncio = "*" -packaging = "*" -psutil = "*" -pyzmq = ">=20" -tornado = ">=6.1" -traitlets = ">=5.4.0" - -[package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] -pyqt5 = ["pyqt5"] -pyside6 = ["pyside6"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "ipython" -version = "8.14.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.9" -files = [ - {file = "ipython-8.14.0-py3-none-any.whl", hash = "sha256:248aca623f5c99a6635bc3857677b7320b9b8039f99f070ee0d20a5ca5a8e6bf"}, - {file = "ipython-8.14.0.tar.gz", hash = "sha256:1d197b907b6ba441b692c48cf2a3a2de280dc0ac91a3405b39349a50272ca0a1"}, -] - -[package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5" - -[package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] -black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] - -[[package]] -name = "ipython-genutils" -version = "0.2.0" -description = "Vestigial utilities from IPython" -optional = false -python-versions = "*" -files = [ - {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, - {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, -] - -[[package]] -name = "ipywidgets" -version = "8.1.0" -description = "Jupyter interactive widgets" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ipywidgets-8.1.0-py3-none-any.whl", hash = "sha256:6c8396cc7b8c95dfb4e9ab0054f48c002f045e7e5d7ae523f559d64e525a98ab"}, - {file = "ipywidgets-8.1.0.tar.gz", hash = "sha256:ce97dd90525b3066fd00094690964e7eac14cf9b7745d35565b5eeac20cce687"}, -] - -[package.dependencies] -comm = ">=0.1.3" -ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.7,<3.1.0" -traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.7,<4.1.0" - -[package.extras] -test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] - -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "isoduration" -version = "20.11.0" -description = "Operations with ISO 8601 durations" -optional = false -python-versions = ">=3.7" -files = [ - {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, - {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, -] - -[package.dependencies] -arrow = ">=0.15.0" - -[[package]] -name = "isort" -version = "5.12.0" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "itsdangerous" -version = "2.1.2" -description = "Safely pass data to untrusted environments and back." -optional = false -python-versions = ">=3.7" -files = [ - {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, - {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, -] - -[[package]] -name = "jaraco-classes" -version = "3.3.0" -description = "Utility functions for Python class constructs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jaraco.classes-3.3.0-py3-none-any.whl", hash = "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb"}, - {file = "jaraco.classes-3.3.0.tar.gz", hash = "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621"}, -] - -[package.dependencies] -more-itertools = "*" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[[package]] -name = "jedi" -version = "0.19.0" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.0-py2.py3-none-any.whl", hash = "sha256:cb8ce23fbccff0025e9386b5cf85e892f94c9b822378f8da49970471335ac64e"}, - {file = "jedi-0.19.0.tar.gz", hash = "sha256:bcf9894f1753969cbac8022a8c2eaee06bfa3724e4192470aaffe7eb6272b0c4"}, -] - -[package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "jeepney" -version = "0.8.0" -description = "Low-level, pure Python DBus protocol wrapper." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, - {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, -] - -[package.extras] -test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async_generator", "trio"] - [[package]] name = "jinja2" version = "3.1.2" @@ -3516,38 +1522,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jmespath" -version = "1.0.1" -description = "JSON Matching Expressions" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, - {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, -] - -[[package]] -name = "joblib" -version = "1.3.2" -description = "Lightweight pipelining with Python functions" -optional = false -python-versions = ">=3.7" -files = [ - {file = "joblib-1.3.2-py3-none-any.whl", hash = "sha256:ef4331c65f239985f3f2220ecc87db222f08fd22097a3dd5698f693875f8cbb9"}, - {file = "joblib-1.3.2.tar.gz", hash = "sha256:92f865e621e17784e7955080b6d042489e3b8e294949cc44c6eac304f59772b1"}, -] - -[[package]] -name = "json-logging-py" -version = "0.2" -description = "JSON / Logstash formatters for Python logging" -optional = false -python-versions = "*" -files = [ - {file = "json-logging-py-0.2.tar.gz", hash = "sha256:118b1fe1f4eacaea6370e5b9710d0f6d0c0a4599aef9d5b9875a6a579974fc9a"}, -] - [[package]] name = "json-rpc" version = "1.15.0" @@ -3559,368 +1533,6 @@ files = [ {file = "json_rpc-1.15.0-py2.py3-none-any.whl", hash = "sha256:4a4668bbbe7116feb4abbd0f54e64a4adcf4b8f648f19ffa0848ad0f6606a9bf"}, ] -[[package]] -name = "json5" -version = "0.9.14" -description = "A Python implementation of the JSON5 data format." -optional = false -python-versions = "*" -files = [ - {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, - {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, -] - -[package.extras] -dev = ["hypothesis"] - -[[package]] -name = "jsonpointer" -version = "2.4" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, -] - -[[package]] -name = "jsonschema" -version = "4.19.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, - {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} -jsonschema-specifications = ">=2023.03.6" -referencing = ">=0.28.4" -rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} -rpds-py = ">=0.7.1" -uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} -webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jsonschema-specifications" -version = "2023.7.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, -] - -[package.dependencies] -referencing = ">=0.28.0" - -[[package]] -name = "jupyter" -version = "1.0.0" -description = "Jupyter metapackage. Install all the Jupyter components in one go." -optional = false -python-versions = "*" -files = [ - {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"}, - {file = "jupyter-1.0.0.tar.gz", hash = "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"}, - {file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"}, -] - -[package.dependencies] -ipykernel = "*" -ipywidgets = "*" -jupyter-console = "*" -nbconvert = "*" -notebook = "*" -qtconsole = "*" - -[[package]] -name = "jupyter-client" -version = "8.3.0" -description = "Jupyter protocol implementation and client libraries" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, - {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, -] - -[package.dependencies] -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -python-dateutil = ">=2.8.2" -pyzmq = ">=23.0" -tornado = ">=6.2" -traitlets = ">=5.3" - -[package.extras] -docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] - -[[package]] -name = "jupyter-console" -version = "6.6.3" -description = "Jupyter terminal console" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485"}, - {file = "jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539"}, -] - -[package.dependencies] -ipykernel = ">=6.14" -ipython = "*" -jupyter-client = ">=7.0.0" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -prompt-toolkit = ">=3.0.30" -pygments = "*" -pyzmq = ">=17" -traitlets = ">=5.4" - -[package.extras] -test = ["flaky", "pexpect", "pytest"] - -[[package]] -name = "jupyter-core" -version = "5.3.1" -description = "Jupyter core package. A base package on which Jupyter projects rely." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_core-5.3.1-py3-none-any.whl", hash = "sha256:ae9036db959a71ec1cac33081eeb040a79e681f08ab68b0883e9a676c7a90dce"}, - {file = "jupyter_core-5.3.1.tar.gz", hash = "sha256:5ba5c7938a7f97a6b0481463f7ff0dbac7c15ba48cf46fa4035ca6e838aa1aba"}, -] - -[package.dependencies] -platformdirs = ">=2.5" -pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = ">=5.3" - -[package.extras] -docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] -test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] - -[[package]] -name = "jupyter-events" -version = "0.7.0" -description = "Jupyter Event System library" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_events-0.7.0-py3-none-any.whl", hash = "sha256:4753da434c13a37c3f3c89b500afa0c0a6241633441421f6adafe2fb2e2b924e"}, - {file = "jupyter_events-0.7.0.tar.gz", hash = "sha256:7be27f54b8388c03eefea123a4f79247c5b9381c49fb1cd48615ee191eb12615"}, -] - -[package.dependencies] -jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} -python-json-logger = ">=2.0.4" -pyyaml = ">=5.3" -referencing = "*" -rfc3339-validator = "*" -rfc3986-validator = ">=0.1.1" -traitlets = ">=5.3" - -[package.extras] -cli = ["click", "rich"] -docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] -test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] - -[[package]] -name = "jupyter-lsp" -version = "2.2.0" -description = "Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter-lsp-2.2.0.tar.gz", hash = "sha256:8ebbcb533adb41e5d635eb8fe82956b0aafbf0fd443b6c4bfa906edeeb8635a1"}, - {file = "jupyter_lsp-2.2.0-py3-none-any.whl", hash = "sha256:9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f"}, -] - -[package.dependencies] -jupyter-server = ">=1.1.2" - -[[package]] -name = "jupyter-server" -version = "2.7.0" -description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_server-2.7.0-py3-none-any.whl", hash = "sha256:6a77912aff643e53fa14bdb2634884b52b784a4be77ce8e93f7283faed0f0849"}, - {file = "jupyter_server-2.7.0.tar.gz", hash = "sha256:36da0a266d31a41ac335a366c88933c17dfa5bb817a48f5c02c16d303bc9477f"}, -] - -[package.dependencies] -anyio = ">=3.1.0" -argon2-cffi = "*" -jinja2 = "*" -jupyter-client = ">=7.4.4" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -jupyter-events = ">=0.6.0" -jupyter-server-terminals = "*" -nbconvert = ">=6.4.4" -nbformat = ">=5.3.0" -overrides = "*" -packaging = "*" -prometheus-client = "*" -pywinpty = {version = "*", markers = "os_name == \"nt\""} -pyzmq = ">=24" -send2trash = "*" -terminado = ">=0.8.3" -tornado = ">=6.2.0" -traitlets = ">=5.6.0" -websocket-client = "*" - -[package.extras] -docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] -test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] - -[[package]] -name = "jupyter-server-terminals" -version = "0.4.4" -description = "A Jupyter Server Extension Providing Terminals." -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, - {file = "jupyter_server_terminals-0.4.4.tar.gz", hash = "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d"}, -] - -[package.dependencies] -pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} -terminado = ">=0.8.3" - -[package.extras] -docs = ["jinja2", "jupyter-server", "mistune (<3.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] -test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] - -[[package]] -name = "jupyterlab" -version = "4.0.4" -description = "JupyterLab computational environment" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyterlab-4.0.4-py3-none-any.whl", hash = "sha256:23eef35d22be8f2ad9b873ec41ceb2e8c3b0dc8ae740c0f973e2de09e587530f"}, - {file = "jupyterlab-4.0.4.tar.gz", hash = "sha256:049449a56d93202ed204e0e86f96f5a3447a08cfc09fb012fd239e178651cb34"}, -] - -[package.dependencies] -async-lru = ">=1.0.0" -ipykernel = "*" -jinja2 = ">=3.0.3" -jupyter-core = "*" -jupyter-lsp = ">=2.0.0" -jupyter-server = ">=2.4.0,<3" -jupyterlab-server = ">=2.19.0,<3" -notebook-shim = ">=0.2" -packaging = "*" -tornado = ">=6.2.0" -traitlets = "*" - -[package.extras] -dev = ["black[jupyter] (==23.3.0)", "build", "bump2version", "coverage", "hatch", "pre-commit", "pytest-cov", "ruff (==0.0.271)"] -docs = ["jsx-lexer", "myst-parser", "pydata-sphinx-theme (>=0.13.0)", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8)", "sphinx-copybutton"] -docs-screenshots = ["altair (==5.0.1)", "ipython (==8.14.0)", "ipywidgets (==8.0.6)", "jupyterlab-geojson (==3.4.0)", "jupyterlab-language-pack-zh-cn (==4.0.post0)", "matplotlib (==3.7.1)", "nbconvert (>=7.0.0)", "pandas (==2.0.2)", "scipy (==1.10.1)", "vega-datasets (==0.9.0)"] -test = ["coverage", "pytest (>=7.0)", "pytest-check-links (>=0.7)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "pytest-timeout", "pytest-tornasync", "requests", "requests-cache", "virtualenv"] - -[[package]] -name = "jupyterlab-pygments" -version = "0.2.2" -description = "Pygments theme using JupyterLab CSS variables" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, - {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, -] - -[[package]] -name = "jupyterlab-server" -version = "2.24.0" -description = "A set of server components for JupyterLab and JupyterLab like applications." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_server-2.24.0-py3-none-any.whl", hash = "sha256:5f077e142bb8dc9b843d960f940c513581bceca3793a0d80f9c67d9522c4e876"}, - {file = "jupyterlab_server-2.24.0.tar.gz", hash = "sha256:4e6f99e0a5579bbbc32e449c4dbb039561d4f1a7827d5733273ed56738f21f07"}, -] - -[package.dependencies] -babel = ">=2.10" -jinja2 = ">=3.0.3" -json5 = ">=0.9.0" -jsonschema = ">=4.17.3" -jupyter-server = ">=1.21,<3" -packaging = ">=21.3" -requests = ">=2.28" - -[package.extras] -docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] -openapi = ["openapi-core (>=0.16.1,<0.17.0)", "ruamel-yaml"] -test = ["hatch", "ipykernel", "jupyterlab-server[openapi]", "openapi-spec-validator (>=0.5.1,<0.7.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] - -[[package]] -name = "jupyterlab-vim" -version = "4.0.2" -description = "Code cell vim bindings" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jupyterlab_vim-4.0.2-py3-none-any.whl", hash = "sha256:3731106f067a50933fd694999dca288cff6a51b455fd75cb51b9d52d4980694d"}, - {file = "jupyterlab_vim-4.0.2.tar.gz", hash = "sha256:b9b371d1abff313edc0f9f00c4633cc33cd81f5a60645358c36564b2ff5f81b1"}, -] - -[package.dependencies] -jupyterlab = ">=4.0.0,<5" - -[[package]] -name = "jupyterlab-widgets" -version = "3.0.8" -description = "Jupyter interactive widgets for JupyterLab" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_widgets-3.0.8-py3-none-any.whl", hash = "sha256:4715912d6ceab839c9db35953c764b3214ebbc9161c809f6e0510168845dfdf5"}, - {file = "jupyterlab_widgets-3.0.8.tar.gz", hash = "sha256:d428ab97b8d87cc7c54cbf37644d6e0f0e662f23876e05fa460a73ec3257252a"}, -] - -[[package]] -name = "keyring" -version = "23.13.1" -description = "Store and access your passwords safely." -optional = false -python-versions = ">=3.7" -files = [ - {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, - {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} -"jaraco.classes" = "*" -jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} -pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} -SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} - -[package.extras] -completion = ["shtab"] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [[package]] name = "kiwisolver" version = "1.4.4" @@ -3998,85 +1610,6 @@ files = [ {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, ] -[[package]] -name = "knack" -version = "0.11.0" -description = "A Command-Line Interface framework" -optional = false -python-versions = "*" -files = [ - {file = "knack-0.11.0-py3-none-any.whl", hash = "sha256:6704c867840978a119a193914a90e2e98c7be7dff764c8fcd8a2286c5a978d00"}, - {file = "knack-0.11.0.tar.gz", hash = "sha256:eb6568001e9110b1b320941431c51033d104cc98cda2254a5c2b09ba569fd494"}, -] - -[package.dependencies] -argcomplete = "*" -jmespath = "*" -packaging = "*" -pygments = "*" -pyyaml = "*" -tabulate = "*" - -[[package]] -name = "lazy-loader" -version = "0.3" -description = "lazy_loader" -optional = false -python-versions = ">=3.7" -files = [ - {file = "lazy_loader-0.3-py3-none-any.whl", hash = "sha256:1e9e76ee8631e264c62ce10006718e80b2cfc74340d17d1031e0f84af7478554"}, - {file = "lazy_loader-0.3.tar.gz", hash = "sha256:3b68898e34f5b2a29daaaac172c6555512d0f32074f147e2254e4a6d9d838f37"}, -] - -[package.extras] -lint = ["pre-commit (>=3.3)"] -test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] - -[[package]] -name = "lazy-object-proxy" -version = "1.9.0" -description = "A fast and thorough lazy object proxy." -optional = false -python-versions = ">=3.7" -files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] - [[package]] name = "libusb1" version = "3.0.0" @@ -4090,27 +1623,6 @@ files = [ {file = "libusb1-3.0.0.tar.gz", hash = "sha256:5792a9defee40f15d330a40d9b1800545c32e47ba7fc66b6f28f133c9fcc8538"}, ] -[[package]] -name = "lit" -version = "16.0.6" -description = "A Software Testing Tool" -optional = false -python-versions = "*" -files = [ - {file = "lit-16.0.6.tar.gz", hash = "sha256:84623c9c23b6b14763d637f4e63e6b721b3446ada40bf7001d8fee70b8e77a9a"}, -] - -[[package]] -name = "lockfile" -version = "0.12.2" -description = "Platform-independent file locking module" -optional = false -python-versions = "*" -files = [ - {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, - {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, -] - [[package]] name = "lru-dict" version = "1.2.0" @@ -4205,147 +1717,6 @@ files = [ [package.extras] test = ["pytest"] -[[package]] -name = "lxml" -version = "4.9.3" -description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" -files = [ - {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, - {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, - {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, - {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, - {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, - {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, - {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, - {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, - {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, - {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, - {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, - {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, - {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, - {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, - {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, - {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, - {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, - {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, - {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, - {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, - {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, - {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, - {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, - {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, - {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, -] - -[package.extras] -cssselect = ["cssselect (>=0.7)"] -html5 = ["html5lib"] -htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=0.29.35)"] - -[[package]] -name = "mako" -version = "1.2.4" -description = "A super-fast templating language that borrows the best ideas from the existing templating languages." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Mako-1.2.4-py3-none-any.whl", hash = "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818"}, - {file = "Mako-1.2.4.tar.gz", hash = "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34"}, -] - -[package.dependencies] -MarkupSafe = ">=0.9.2" - -[package.extras] -babel = ["Babel"] -lingua = ["lingua"] -testing = ["pytest"] - -[[package]] -name = "markdown" -version = "3.4.4" -description = "Python implementation of John Gruber's Markdown." -optional = false -python-versions = ">=3.7" -files = [ - {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, - {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, -] - -[package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] -testing = ["coverage", "pyyaml"] - [[package]] name = "markdown-it-py" version = "3.0.0" @@ -4490,31 +1861,6 @@ pillow = ">=6.2.0" pyparsing = ">=2.3.1,<3.1" python-dateutil = ">=2.7" -[[package]] -name = "matplotlib-inline" -version = "0.1.6" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.5" -files = [ - {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, - {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mdit-py-plugins" version = "0.4.0" @@ -4545,28 +1891,6 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] -[[package]] -name = "mistune" -version = "3.0.1" -description = "A sane and fast Markdown parser with useful plugins and renderers" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mistune-3.0.1-py3-none-any.whl", hash = "sha256:b9b3e438efbb57c62b5beb5e134dab664800bdf1284a7ee09e8b12b13eb1aac6"}, - {file = "mistune-3.0.1.tar.gz", hash = "sha256:e912116c13aa0944f9dc530db38eb88f6a77087ab128f49f84a48f4c05ea163c"}, -] - -[[package]] -name = "more-itertools" -version = "10.1.0" -description = "More routines for operating on iterables, beyond itertools" -optional = false -python-versions = ">=3.8" -files = [ - {file = "more-itertools-10.1.0.tar.gz", hash = "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a"}, - {file = "more_itertools-10.1.0-py3-none-any.whl", hash = "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6"}, -] - [[package]] name = "mpld3" version = "0.5.9" @@ -4599,178 +1923,6 @@ docs = ["sphinx"] gmpy = ["gmpy2 (>=2.1.0a4)"] tests = ["pytest (>=4.6)"] -[[package]] -name = "msal" -version = "1.24.0b1" -description = "The Microsoft Authentication Library (MSAL) for Python library" -optional = false -python-versions = ">=2.7" -files = [ - {file = "msal-1.24.0b1-py2.py3-none-any.whl", hash = "sha256:55a232e106c144c42f2fef05d3613ddc354e254338fc2ffb326a0d08878ebad6"}, - {file = "msal-1.24.0b1.tar.gz", hash = "sha256:cdee42a97fa6f171f83541022f64a0353f445d5e304bfd0380ee573031e8fd4a"}, -] - -[package.dependencies] -cryptography = ">=0.6,<44" -PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]} -pymsalruntime = {version = ">=0.13.2,<0.14", optional = true, markers = "python_version >= \"3.6\" and platform_system == \"Windows\" and extra == \"broker\""} -requests = ">=2.0.0,<3" - -[package.extras] -broker = ["pymsalruntime (>=0.13.2,<0.14)"] - -[[package]] -name = "msal-extensions" -version = "1.0.0" -description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." -optional = false -python-versions = "*" -files = [ - {file = "msal-extensions-1.0.0.tar.gz", hash = "sha256:c676aba56b0cce3783de1b5c5ecfe828db998167875126ca4b47dc6436451354"}, - {file = "msal_extensions-1.0.0-py2.py3-none-any.whl", hash = "sha256:91e3db9620b822d0ed2b4d1850056a0f133cba04455e62f11612e40f5502f2ee"}, -] - -[package.dependencies] -msal = ">=0.4.1,<2.0.0" -portalocker = [ - {version = ">=1.0,<3", markers = "python_version >= \"3.5\" and platform_system != \"Windows\""}, - {version = ">=1.6,<3", markers = "python_version >= \"3.5\" and platform_system == \"Windows\""}, -] - -[[package]] -name = "msgpack" -version = "1.0.5" -description = "MessagePack serializer" -optional = false -python-versions = "*" -files = [ - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:525228efd79bb831cf6830a732e2e80bc1b05436b086d4264814b4b2955b2fa9"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f8d8b3bf1ff2672567d6b5c725a1b347fe838b912772aa8ae2bf70338d5a198"}, - {file = "msgpack-1.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdc793c50be3f01106245a61b739328f7dccc2c648b501e237f0699fe1395b81"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cb47c21a8a65b165ce29f2bec852790cbc04936f502966768e4aae9fa763cb7"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e42b9594cc3bf4d838d67d6ed62b9e59e201862a25e9a157019e171fbe672dd3"}, - {file = "msgpack-1.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55b56a24893105dc52c1253649b60f475f36b3aa0fc66115bffafb624d7cb30b"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1967f6129fc50a43bfe0951c35acbb729be89a55d849fab7686004da85103f1c"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a97bf595a232c3ee6d57ddaadd5453d174a52594bf9c21d10407e2a2d9b3bd"}, - {file = "msgpack-1.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d25dd59bbbbb996eacf7be6b4ad082ed7eacc4e8f3d2df1ba43822da9bfa122a"}, - {file = "msgpack-1.0.5-cp310-cp310-win32.whl", hash = "sha256:382b2c77589331f2cb80b67cc058c00f225e19827dbc818d700f61513ab47bea"}, - {file = "msgpack-1.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:4867aa2df9e2a5fa5f76d7d5565d25ec76e84c106b55509e78c1ede0f152659a"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9f5ae84c5c8a857ec44dc180a8b0cc08238e021f57abdf51a8182e915e6299f0"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e6ca5d5699bcd89ae605c150aee83b5321f2115695e741b99618f4856c50898"}, - {file = "msgpack-1.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5494ea30d517a3576749cad32fa27f7585c65f5f38309c88c6d137877fa28a5a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ab2f3331cb1b54165976a9d976cb251a83183631c88076613c6c780f0d6e45a"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28592e20bbb1620848256ebc105fc420436af59515793ed27d5c77a217477705"}, - {file = "msgpack-1.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5c63197c55bce6385d9aee16c4d0641684628f63ace85f73571e65ad1c1e8d"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed40e926fa2f297e8a653c954b732f125ef97bdd4c889f243182299de27e2aa9"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b2de4c1c0538dcb7010902a2b97f4e00fc4ddf2c8cda9749af0e594d3b7fa3d7"}, - {file = "msgpack-1.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf22a83f973b50f9d38e55c6aade04c41ddda19b00c4ebc558930d78eecc64ed"}, - {file = "msgpack-1.0.5-cp311-cp311-win32.whl", hash = "sha256:c396e2cc213d12ce017b686e0f53497f94f8ba2b24799c25d913d46c08ec422c"}, - {file = "msgpack-1.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c4c68d87497f66f96d50142a2b73b97972130d93677ce930718f68828b382e2"}, - {file = "msgpack-1.0.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2b031c2e9b9af485d5e3c4520f4220d74f4d222a5b8dc8c1a3ab9448ca79c57"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f837b93669ce4336e24d08286c38761132bc7ab29782727f8557e1eb21b2080"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1d46dfe3832660f53b13b925d4e0fa1432b00f5f7210eb3ad3bb9a13c6204a6"}, - {file = "msgpack-1.0.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366c9a7b9057e1547f4ad51d8facad8b406bab69c7d72c0eb6f529cf76d4b85f"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:4c075728a1095efd0634a7dccb06204919a2f67d1893b6aa8e00497258bf926c"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:f933bbda5a3ee63b8834179096923b094b76f0c7a73c1cfe8f07ad608c58844b"}, - {file = "msgpack-1.0.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:36961b0568c36027c76e2ae3ca1132e35123dcec0706c4b7992683cc26c1320c"}, - {file = "msgpack-1.0.5-cp36-cp36m-win32.whl", hash = "sha256:b5ef2f015b95f912c2fcab19c36814963b5463f1fb9049846994b007962743e9"}, - {file = "msgpack-1.0.5-cp36-cp36m-win_amd64.whl", hash = "sha256:288e32b47e67f7b171f86b030e527e302c91bd3f40fd9033483f2cacc37f327a"}, - {file = "msgpack-1.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:137850656634abddfb88236008339fdaba3178f4751b28f270d2ebe77a563b6c"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c05a4a96585525916b109bb85f8cb6511db1c6f5b9d9cbcbc940dc6b4be944b"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56a62ec00b636583e5cb6ad313bbed36bb7ead5fa3a3e38938503142c72cba4f"}, - {file = "msgpack-1.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef8108f8dedf204bb7b42994abf93882da1159728a2d4c5e82012edd92c9da9f"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1835c84d65f46900920b3708f5ba829fb19b1096c1800ad60bae8418652a951d"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e57916ef1bd0fee4f21c4600e9d1da352d8816b52a599c46460e93a6e9f17086"}, - {file = "msgpack-1.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:17358523b85973e5f242ad74aa4712b7ee560715562554aa2134d96e7aa4cbbf"}, - {file = "msgpack-1.0.5-cp37-cp37m-win32.whl", hash = "sha256:cb5aaa8c17760909ec6cb15e744c3ebc2ca8918e727216e79607b7bbce9c8f77"}, - {file = "msgpack-1.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:ab31e908d8424d55601ad7075e471b7d0140d4d3dd3272daf39c5c19d936bd82"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b72d0698f86e8d9ddf9442bdedec15b71df3598199ba33322d9711a19f08145c"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:379026812e49258016dd84ad79ac8446922234d498058ae1d415f04b522d5b2d"}, - {file = "msgpack-1.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:332360ff25469c346a1c5e47cbe2a725517919892eda5cfaffe6046656f0b7bb"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:476a8fe8fae289fdf273d6d2a6cb6e35b5a58541693e8f9f019bfe990a51e4ba"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9985b214f33311df47e274eb788a5893a761d025e2b92c723ba4c63936b69b1"}, - {file = "msgpack-1.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48296af57cdb1d885843afd73c4656be5c76c0c6328db3440c9601a98f303d87"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:addab7e2e1fcc04bd08e4eb631c2a90960c340e40dfc4a5e24d2ff0d5a3b3edb"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:916723458c25dfb77ff07f4c66aed34e47503b2eb3188b3adbec8d8aa6e00f48"}, - {file = "msgpack-1.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:821c7e677cc6acf0fd3f7ac664c98803827ae6de594a9f99563e48c5a2f27eb0"}, - {file = "msgpack-1.0.5-cp38-cp38-win32.whl", hash = "sha256:1c0f7c47f0087ffda62961d425e4407961a7ffd2aa004c81b9c07d9269512f6e"}, - {file = "msgpack-1.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:bae7de2026cbfe3782c8b78b0db9cbfc5455e079f1937cb0ab8d133496ac55e1"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:20c784e66b613c7f16f632e7b5e8a1651aa5702463d61394671ba07b2fc9e025"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:266fa4202c0eb94d26822d9bfd7af25d1e2c088927fe8de9033d929dd5ba24c5"}, - {file = "msgpack-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:18334484eafc2b1aa47a6d42427da7fa8f2ab3d60b674120bce7a895a0a85bdd"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57e1f3528bd95cc44684beda696f74d3aaa8a5e58c816214b9046512240ef437"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:586d0d636f9a628ddc6a17bfd45aa5b5efaf1606d2b60fa5d87b8986326e933f"}, - {file = "msgpack-1.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a740fa0e4087a734455f0fc3abf5e746004c9da72fbd541e9b113013c8dc3282"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3055b0455e45810820db1f29d900bf39466df96ddca11dfa6d074fa47054376d"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a61215eac016f391129a013c9e46f3ab308db5f5ec9f25811e811f96962599a8"}, - {file = "msgpack-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:362d9655cd369b08fda06b6657a303eb7172d5279997abe094512e919cf74b11"}, - {file = "msgpack-1.0.5-cp39-cp39-win32.whl", hash = "sha256:ac9dd47af78cae935901a9a500104e2dea2e253207c924cc95de149606dc43cc"}, - {file = "msgpack-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:06f5174b5f8ed0ed919da0e62cbd4ffde676a374aba4020034da05fab67b9164"}, - {file = "msgpack-1.0.5.tar.gz", hash = "sha256:c075544284eadc5cddc70f4757331d99dcbc16b2bbd4849d15f8aae4cf36d31c"}, -] - -[[package]] -name = "msgpack-numpy" -version = "0.4.8" -description = "Numpy data serialization using msgpack" -optional = false -python-versions = "*" -files = [ - {file = "msgpack-numpy-0.4.8.tar.gz", hash = "sha256:c667d3180513422f9c7545be5eec5d296dcbb357e06f72ed39cc683797556e69"}, - {file = "msgpack_numpy-0.4.8-py2.py3-none-any.whl", hash = "sha256:773c19d4dfbae1b3c7b791083e2caf66983bb19b40901646f61d8731554ae3da"}, -] - -[package.dependencies] -msgpack = ">=0.5.2" -numpy = ">=1.9.0" - -[[package]] -name = "msgpack-python" -version = "0.5.6" -description = "MessagePack (de)serializer." -optional = false -python-versions = "*" -files = [ - {file = "msgpack-python-0.5.6.tar.gz", hash = "sha256:378cc8a6d3545b532dfd149da715abae4fda2a3adb6d74e525d0d5e51f46909b"}, -] - -[[package]] -name = "msrest" -version = "0.7.1" -description = "AutoRest swagger generator Python client runtime." -optional = false -python-versions = ">=3.6" -files = [ - {file = "msrest-0.7.1-py3-none-any.whl", hash = "sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32"}, - {file = "msrest-0.7.1.zip", hash = "sha256:6e7661f46f3afd88b75667b7187a92829924446c7ea1d169be8c4bb7eeb788b9"}, -] - -[package.dependencies] -azure-core = ">=1.24.0" -certifi = ">=2017.4.17" -isodate = ">=0.6.0" -requests = ">=2.16,<3.0" -requests-oauthlib = ">=0.5.0" - -[package.extras] -async = ["aiodns", "aiohttp (>=3.0)"] - -[[package]] -name = "msrestazure" -version = "0.6.4" -description = "AutoRest swagger generator Python client runtime. Azure-specific module." -optional = false -python-versions = "*" -files = [ - {file = "msrestazure-0.6.4-py2.py3-none-any.whl", hash = "sha256:3de50f56147ef529b31e099a982496690468ecef33f0544cb0fa0cfe1e1de5b9"}, - {file = "msrestazure-0.6.4.tar.gz", hash = "sha256:a06f0dabc9a6f5efe3b6add4bd8fb623aeadacf816b7a35b0f89107e0544d189"}, -] - -[package.dependencies] -adal = ">=0.6.0,<2.0.0" -msrest = ">=0.6.0,<2.0.0" -six = "*" - [[package]] name = "multidict" version = "6.0.4" @@ -4854,54 +2006,35 @@ files = [ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] -[[package]] -name = "munch" -version = "4.0.0" -description = "A dot-accessible dictionary (a la JavaScript objects)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "munch-4.0.0-py2.py3-none-any.whl", hash = "sha256:71033c45db9fb677a0b7eb517a4ce70ae09258490e419b0e7f00d1e386ecb1b4"}, - {file = "munch-4.0.0.tar.gz", hash = "sha256:542cb151461263216a4e37c3fd9afc425feeaf38aaa3025cd2a981fadb422235"}, -] - -[package.extras] -testing = ["astroid (>=2.0)", "coverage", "pylint (>=2.3.1,<2.4.0)", "pytest"] -yaml = ["PyYAML (>=5.1.0)"] - [[package]] name = "mypy" -version = "1.4.1" +version = "1.5.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, - {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, - {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, - {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, - {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, - {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, - {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, - {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, - {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, - {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, - {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, - {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, - {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, - {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, - {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, - {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, - {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, - {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, - {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, - {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, + {file = "mypy-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ad3109bec37cc33654de8db30fe8ff3a1bb57ea65144167d68185e6dced9868d"}, + {file = "mypy-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b4ea3a0241cb005b0ccdbd318fb99619b21ae51bcf1660b95fc22e0e7d3ba4a1"}, + {file = "mypy-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fe816e26e676c1311b9e04fd576543b873576d39439f7c24c8e5c7728391ecf"}, + {file = "mypy-1.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:42170e68adb1603ccdc55a30068f72bcfcde2ce650188e4c1b2a93018b826735"}, + {file = "mypy-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:d145b81a8214687cfc1f85c03663a5bbe736777410e5580e54d526e7e904f564"}, + {file = "mypy-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c36011320e452eb30bec38b9fd3ba20569dc9545d7d4540d967f3ea1fab9c374"}, + {file = "mypy-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f3940cf5845b2512b3ab95463198b0cdf87975dfd17fdcc6ce9709a9abe09e69"}, + {file = "mypy-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9166186c498170e1ff478a7f540846b2169243feb95bc228d39a67a1a450cdc6"}, + {file = "mypy-1.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:725b57a19b7408ef66a0fd9db59b5d3e528922250fb56e50bded27fea9ff28f0"}, + {file = "mypy-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:eec5c927aa4b3e8b4781840f1550079969926d0a22ce38075f6cfcf4b13e3eb4"}, + {file = "mypy-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79c520aa24f21852206b5ff2cf746dc13020113aa73fa55af504635a96e62718"}, + {file = "mypy-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:769ddb6bfe55c2bd9c7d6d7020885a5ea14289619db7ee650e06b1ef0852c6f4"}, + {file = "mypy-1.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbf18f8db7e5f060d61c91e334d3b96d6bb624ddc9ee8a1cde407b737acbca2c"}, + {file = "mypy-1.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a2500ad063413bc873ae102cf655bf49889e0763b260a3a7cf544a0cbbf7e70a"}, + {file = "mypy-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:84cf9f7d8a8a22bb6a36444480f4cbf089c917a4179fbf7eea003ea931944a7f"}, + {file = "mypy-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a551ed0fc02455fe2c1fb0145160df8336b90ab80224739627b15ebe2b45e9dc"}, + {file = "mypy-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:372fd97293ed0076d52695849f59acbbb8461c4ab447858cdaeaf734a396d823"}, + {file = "mypy-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8a7444d6fcac7e2585b10abb91ad900a576da7af8f5cffffbff6065d9115813"}, + {file = "mypy-1.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:35b13335c6c46a386577a51f3d38b2b5d14aa619e9633bb756bd77205e4bd09f"}, + {file = "mypy-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:2c9d570f53908cbea326ad8f96028a673b814d9dca7515bf71d95fa662c3eb6f"}, + {file = "mypy-1.5.0-py3-none-any.whl", hash = "sha256:69b32d0dedd211b80f1b7435644e1ef83033a2af2ac65adcdc87c38db68a86be"}, + {file = "mypy-1.5.0.tar.gz", hash = "sha256:f3460f34b3839b9bc84ee3ed65076eb827cd99ed13ed08d723f9083cada4a212"}, ] [package.dependencies] @@ -4911,7 +2044,6 @@ typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] reports = ["lxml"] [[package]] @@ -4966,86 +2098,6 @@ files = [ fast = ["fastnumbers (>=2.0.0)"] icu = ["PyICU (>=1.0.0)"] -[[package]] -name = "nbclient" -version = "0.8.0" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, - {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, -] - -[package.dependencies] -jupyter-client = ">=6.1.12" -jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" -nbformat = ">=5.1" -traitlets = ">=5.4" - -[package.extras] -dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] - -[[package]] -name = "nbconvert" -version = "7.7.3" -description = "Converting Jupyter Notebooks" -optional = false -python-versions = ">=3.8" -files = [ - {file = "nbconvert-7.7.3-py3-none-any.whl", hash = "sha256:3022adadff3f86578a47fab7c2228bb3ca9c56a24345642a22f917f6168b48fc"}, - {file = "nbconvert-7.7.3.tar.gz", hash = "sha256:4a5996bf5f3cd16aa0431897ba1aa4c64842c2079f434b3dc6b8c4b252ef3355"}, -] - -[package.dependencies] -beautifulsoup4 = "*" -bleach = "!=5.0.0" -defusedxml = "*" -jinja2 = ">=3.0" -jupyter-core = ">=4.7" -jupyterlab-pygments = "*" -markupsafe = ">=2.0" -mistune = ">=2.0.3,<4" -nbclient = ">=0.5.0" -nbformat = ">=5.7" -packaging = "*" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -tinycss2 = "*" -traitlets = ">=5.1" - -[package.extras] -all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] -docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert[qtpng]"] -qtpng = ["pyqtwebengine (>=5.15)"] -serve = ["tornado (>=6.1)"] -test = ["flaky", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] -webpdf = ["playwright"] - -[[package]] -name = "nbformat" -version = "5.9.2" -description = "The Jupyter Notebook format" -optional = false -python-versions = ">=3.8" -files = [ - {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, - {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, -] - -[package.dependencies] -fastjsonschema = "*" -jsonschema = ">=2.6" -jupyter-core = "*" -traitlets = ">=5.1" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["pep440", "pre-commit", "pytest", "testpath"] - [[package]] name = "ncompress" version = "1.0.1" @@ -5110,35 +2162,6 @@ files = [ [package.extras] tests = ["pytest"] -[[package]] -name = "nest-asyncio" -version = "1.5.7" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"}, - {file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"}, -] - -[[package]] -name = "networkx" -version = "2.8.8" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.8" -files = [ - {file = "networkx-2.8.8-py3-none-any.whl", hash = "sha256:e435dfa75b1d7195c7b8378c3859f0445cd88c6b0375c181ed66823a9ceb7524"}, - {file = "networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e"}, -] - -[package.extras] -default = ["matplotlib (>=3.4)", "numpy (>=1.19)", "pandas (>=1.3)", "scipy (>=1.8)"] -developer = ["mypy (>=0.982)", "pre-commit (>=2.20)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.2)", "pydata-sphinx-theme (>=0.11)", "sphinx (>=5.2)", "sphinx-gallery (>=0.11)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.9)", "sympy (>=1.10)"] -test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] - [[package]] name = "nodeenv" version = "1.8.0" @@ -5153,118 +2176,40 @@ files = [ [package.dependencies] setuptools = "*" -[[package]] -name = "notebook" -version = "7.0.2" -description = "Jupyter Notebook - A web-based notebook environment for interactive computing" -optional = false -python-versions = ">=3.8" -files = [ - {file = "notebook-7.0.2-py3-none-any.whl", hash = "sha256:c77b1499dc9b07ce4f4f26990dcb25b2107b434f2536766b51a72a4228d9a4b6"}, - {file = "notebook-7.0.2.tar.gz", hash = "sha256:d70d6a07418c829bd5f54337ce993b7105261d9026f9d3fe68e9b8aa1a20da9a"}, -] - -[package.dependencies] -jupyter-server = ">=2.4.0,<3" -jupyterlab = ">=4.0.2,<5" -jupyterlab-server = ">=2.22.1,<3" -notebook-shim = ">=0.2,<0.3" -tornado = ">=6.2.0" - -[package.extras] -dev = ["hatch", "pre-commit"] -docs = ["myst-parser", "nbsphinx", "pydata-sphinx-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["ipykernel", "jupyter-server[test] (>=2.4.0,<3)", "jupyterlab-server[test] (>=2.22.1,<3)", "nbval", "pytest (>=7.0)", "pytest-console-scripts", "pytest-timeout", "pytest-tornasync", "requests"] - -[[package]] -name = "notebook-shim" -version = "0.2.3" -description = "A shim layer for notebook traits and config" -optional = false -python-versions = ">=3.7" -files = [ - {file = "notebook_shim-0.2.3-py3-none-any.whl", hash = "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7"}, - {file = "notebook_shim-0.2.3.tar.gz", hash = "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9"}, -] - -[package.dependencies] -jupyter-server = ">=1.8,<3" - -[package.extras] -test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] - [[package]] name = "numpy" -version = "1.23.0" -description = "NumPy is the fundamental package for array computing with Python." +version = "1.25.2" +description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "numpy-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58bfd40eb478f54ff7a5710dd61c8097e169bc36cc68333d00a9bcd8def53b38"}, - {file = "numpy-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:196cd074c3f97c4121601790955f915187736f9cf458d3ee1f1b46aff2b1ade0"}, - {file = "numpy-1.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1d88ef79e0a7fa631bb2c3dda1ea46b32b1fe614e10fedd611d3d5398447f2f"}, - {file = "numpy-1.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d54b3b828d618a19779a84c3ad952e96e2c2311b16384e973e671aa5be1f6187"}, - {file = "numpy-1.23.0-cp310-cp310-win32.whl", hash = "sha256:2b2da66582f3a69c8ce25ed7921dcd8010d05e59ac8d89d126a299be60421171"}, - {file = "numpy-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:97a76604d9b0e79f59baeca16593c711fddb44936e40310f78bfef79ee9a835f"}, - {file = "numpy-1.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8cc87bed09de55477dba9da370c1679bd534df9baa171dd01accbb09687dac3"}, - {file = "numpy-1.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f0f18804df7370571fb65db9b98bf1378172bd4e962482b857e612d1fec0f53e"}, - {file = "numpy-1.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac86f407873b952679f5f9e6c0612687e51547af0e14ddea1eedfcb22466babd"}, - {file = "numpy-1.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae8adff4172692ce56233db04b7ce5792186f179c415c37d539c25de7298d25d"}, - {file = "numpy-1.23.0-cp38-cp38-win32.whl", hash = "sha256:fe8b9683eb26d2c4d5db32cd29b38fdcf8381324ab48313b5b69088e0e355379"}, - {file = "numpy-1.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:5043bcd71fcc458dfb8a0fc5509bbc979da0131b9d08e3d5f50fb0bbb36f169a"}, - {file = "numpy-1.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c29b44905af288b3919803aceb6ec7fec77406d8b08aaa2e8b9e63d0fe2f160"}, - {file = "numpy-1.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98e8e0d8d69ff4d3fa63e6c61e8cfe2d03c29b16b58dbef1f9baa175bbed7860"}, - {file = "numpy-1.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a506cacf2be3a74ead5467aee97b81fca00c9c4c8b3ba16dbab488cd99ba10"}, - {file = "numpy-1.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:092f5e6025813e64ad6d1b52b519165d08c730d099c114a9247c9bb635a2a450"}, - {file = "numpy-1.23.0-cp39-cp39-win32.whl", hash = "sha256:d6ca8dabe696c2785d0c8c9b0d8a9b6e5fdbe4f922bde70d57fa1a2848134f95"}, - {file = "numpy-1.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc431493df245f3c627c0c05c2bd134535e7929dbe2e602b80e42bf52ff760bc"}, - {file = "numpy-1.23.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f9c3fc2adf67762c9fe1849c859942d23f8d3e0bee7b5ed3d4a9c3eeb50a2f07"}, - {file = "numpy-1.23.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0d2094e8f4d760500394d77b383a1b06d3663e8892cdf5df3c592f55f3bff66"}, - {file = "numpy-1.23.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:94b170b4fa0168cd6be4becf37cb5b127bd12a795123984385b8cd4aca9857e5"}, - {file = "numpy-1.23.0.tar.gz", hash = "sha256:bd3fa4fe2e38533d5336e1272fc4e765cabbbde144309ccee8675509d5cd7b05"}, + {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, + {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, + {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, + {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, + {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, + {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, + {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, + {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, + {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, + {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, + {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, + {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, ] -[[package]] -name = "nvidia-ml-py3" -version = "7.352.0" -description = "Python Bindings for the NVIDIA Management Library" -optional = false -python-versions = "*" -files = [ - {file = "nvidia-ml-py3-7.352.0.tar.gz", hash = "sha256:390f02919ee9d73fe63a98c73101061a6b37fa694a793abf56673320f1f51277"}, -] - -[[package]] -name = "oauthlib" -version = "3.2.2" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.6" -files = [ - {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, - {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - -[[package]] -name = "omegaconf" -version = "2.3.0" -description = "A flexible configuration library" -optional = false -python-versions = ">=3.6" -files = [ - {file = "omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b"}, - {file = "omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7"}, -] - -[package.dependencies] -antlr4-python3-runtime = "==4.9.*" -PyYAML = ">=5.1.0" - [[package]] name = "onnx" version = "1.14.0" @@ -5313,61 +2258,6 @@ typing-extensions = ">=3.6.2.1" [package.extras] lint = ["lintrunner (>=0.10.0)", "lintrunner-adapters (>=0.3)"] -[[package]] -name = "onnx2torch" -version = "1.5.11" -description = "ONNX to PyTorch converter" -optional = false -python-versions = ">=3.6" -files = [ - {file = "onnx2torch-1.5.11-py3-none-any.whl", hash = "sha256:7dd22a7d2bd06a71d9cde1b38888fb6d2234e55ee1e28a16221f1fae8197acce"}, - {file = "onnx2torch-1.5.11.tar.gz", hash = "sha256:5254522279fb15c2e3ccd33ca9104dbd08cf4e188341338b4a3aead50475c419"}, -] - -[package.dependencies] -numpy = ">=1.16.4" -onnx = ">=1.9.0" -torch = ">=1.8.0" -torchvision = ">=0.9.0" - -[package.extras] -dev = ["Pillow", "black", "googledrivedownloader", "isort", "onnxruntime", "pre-commit", "pylint", "pytest", "requests"] - -[[package]] -name = "onnxoptimizer" -version = "0.3.13" -description = "Open Neural Network Exchange" -optional = false -python-versions = "*" -files = [ - {file = "onnxoptimizer-0.3.13-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:019968dc02b37ab87588b67331f15719a9fcfc5de54de866dd7b02eaad68bdd5"}, - {file = "onnxoptimizer-0.3.13-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:542b43b13c3b1b7b72aae2579a2d75ef68dcf0513231bb1cb2b5f3c8af838d87"}, - {file = "onnxoptimizer-0.3.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98716324135ac5505529423dbba5479273e6f46a0f895ac611a29ed8a6f79690"}, - {file = "onnxoptimizer-0.3.13-cp310-cp310-win_amd64.whl", hash = "sha256:f34db9dc55a682d3e5e60f5e6ff62101410620d2b70bef41f6158481a9a0b5ec"}, - {file = "onnxoptimizer-0.3.13-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:dcd1c529cb3d285f1bc75480ebe198a43f6bcc84ad010386f6e2d7bcd3052501"}, - {file = "onnxoptimizer-0.3.13-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:a65b2ff1d480f966f906fdc3731cd6a844762e0aae1876eeafb7586048d6be96"}, - {file = "onnxoptimizer-0.3.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f985cfef0fa2b7cf9ae64a36ca8dacb3e1861e31fa41fb85645cdbd73ccab6a"}, - {file = "onnxoptimizer-0.3.13-cp311-cp311-win_amd64.whl", hash = "sha256:82e606024a6dce999a8586d1f4b6af2ec454f7c5fd69807672a79067017a4812"}, - {file = "onnxoptimizer-0.3.13-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:feb5fb749cb9b12602fef7bae034aaf9a36baa05d068fb3d991bbb758c0508bb"}, - {file = "onnxoptimizer-0.3.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:917363d773f6b517a6edb97b9d1d64cd49dc12ee507d9daef04a443d2d8889a5"}, - {file = "onnxoptimizer-0.3.13-cp37-cp37m-win_amd64.whl", hash = "sha256:f809f7ba336e6569e699b4e6741042ef71e8db30bb60a3380faae87c59d6118f"}, - {file = "onnxoptimizer-0.3.13-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:f6a93aa863e23e040b23822b783b5d9bc1bf3a2153909bcc68dd9cd61c824798"}, - {file = "onnxoptimizer-0.3.13-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ad02bd61d5731587bcecb4aef3ecde6d22fdb0a36c8a2fb6c9b78b6b3cf30e42"}, - {file = "onnxoptimizer-0.3.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3a08e7d3077830bbc99009442230547cae2e9f74682b4fffa42036b88ac49ea"}, - {file = "onnxoptimizer-0.3.13-cp38-cp38-win_amd64.whl", hash = "sha256:3dc63c930db678d07cdd816618b6d990dadb572691c62576962c2aab995a0ba1"}, - {file = "onnxoptimizer-0.3.13-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:1949c259bc87a92680b1d4ee54813dc712a4328b4d4e140ec44c1739862baccc"}, - {file = "onnxoptimizer-0.3.13-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:9c0516d96da47875e9a36d0c9689e2d3e6f72950d98425ccfeba793b6ba4f55e"}, - {file = "onnxoptimizer-0.3.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cfa79a41d2439c47e6675f19cc6bcd7dce5d5da492f9bcde71dc0eba739dea6"}, - {file = "onnxoptimizer-0.3.13-cp39-cp39-win_amd64.whl", hash = "sha256:f97f454cc2602095e341219f5c1b828d1588351251e4a4108017fd132ac5590c"}, - {file = "onnxoptimizer-0.3.13.tar.gz", hash = "sha256:e08b726e0d4577e51e529f36bc324bf11b7cff12852cf3eee081f05c8b8c6f33"}, -] - -[package.dependencies] -onnx = "*" - -[package.extras] -mypy = ["mypy (==0.600)"] - [[package]] name = "onnxruntime-gpu" version = "1.15.1" @@ -5395,96 +2285,30 @@ sympy = "*" [[package]] name = "opencv-python-headless" -version = "4.5.5.64" +version = "4.8.0.76" description = "Wrapper package for OpenCV python bindings." optional = false python-versions = ">=3.6" files = [ - {file = "opencv_python_headless-4.5.5.64-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:6f4e1be1906a8acea618be85c54348dd69735699f692e11cea87da2aff1e11f2"}, + {file = "opencv-python-headless-4.8.0.76.tar.gz", hash = "sha256:bc15726187dae26d8a08777faf6bc71d38f20c785c102677f58ba0e935003afb"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:f85d2e3b9d952db35d31f9db8882d073c903921b72b8db1cfed8bbc75e8d3e63"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:8ee3bf1c9086493c340c6a87899f1c7778d729de92bce8560b8c31ab8a9cdf79"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c675b8dec6298ba6a1eec2ce24077a393b4236a043f68dfacb06bf594354ce06"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:220d2e292fa45ef0582aab730460bbc15cfe61f2089208167a372ccf76f01e21"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-win32.whl", hash = "sha256:df0608de207ae9b094ad9eaf1a475cf6e9a069fb12cd289d4a18cefdab2f8aa8"}, + {file = "opencv_python_headless-4.8.0.76-cp37-abi3-win_amd64.whl", hash = "sha256:9c094faf6ec7bd360244647b26ebdf8f54edec1d9292cb9179fff9badcca7be8"}, ] [package.dependencies] numpy = [ - {version = ">=1.21.2", markers = "python_version >= \"3.10\" or python_version >= \"3.6\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, + {version = ">=1.21.2", markers = "python_version >= \"3.10\""}, + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, {version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\""}, - {version = ">=1.14.5", markers = "python_version >= \"3.7\""}, + {version = ">=1.17.0", markers = "python_version >= \"3.7\""}, {version = ">=1.17.3", markers = "python_version >= \"3.8\""}, ] -[package.source] -type = "url" -url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu118-cp311/opencv_python_headless-4.5.5.64-cp311-cp311-manylinux_2_31_x86_64.whl" - -[[package]] -name = "osmium" -version = "3.6.0" -description = "Python bindings for libosmium, the data processing library for OSM data" -optional = false -python-versions = ">=3.6" -files = [ - {file = "osmium-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0520d39797c17030c11427213421237aa17f327b076c5367dd2721e856a8aab7"}, - {file = "osmium-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e46615d9761f49ae86b7f891c1e00a7e010b85622d17d956029299407b86b0cb"}, - {file = "osmium-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:ae26ef88d386ba57eece0b577d61d58f70688f04f4366265001fe63f0d0da1ac"}, - {file = "osmium-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:844a614a39435ab6d20ae136feda9b57acd15f062b8177321ec3343610d12dd7"}, - {file = "osmium-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:184bb9dc6938db2e0f08cf4f33fd1d1d35fa106c9a71bb5f060967110d701bf3"}, - {file = "osmium-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6ecd7f036bf89e69e67aa1f8ed4fa1b5997307c7586a17e793b250cdcb8e7a0f"}, - {file = "osmium-3.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:10a40a6803cfa964e9ec34bb701c5f1466e37d77fa2fac93531dc2ba80651602"}, - {file = "osmium-3.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2156805e83122e9bcfce43b789c53fc2460cc021e4cde04c065b18ac540e176d"}, - {file = "osmium-3.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7665829f16ecea783e037ef2ed6c983909ce48ea7b0e7fdff4fbc23159a27368"}, - {file = "osmium-3.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b45c06943982e2da8e2c710ed555b074f293b2349da1ca526c8b9db6bdf06a3c"}, - {file = "osmium-3.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:131f882871e1b49d33e2258f5ea5e65b383b56cb24521b7c488d6a1763dcf8fb"}, - {file = "osmium-3.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:569b9206bf99b8157a578ccbbccfc1eedfeb7ea685db69542101f459304be4fb"}, - {file = "osmium-3.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:755c2baaf87148a55167e6357c7f6461c583a29d365bc36f97bdab5829ccd6f4"}, - {file = "osmium-3.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84bda7074dcfbd83019bb30787c5bcf20411707b8ec7a550c3fbacbaba41ed19"}, - {file = "osmium-3.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:866c76bc816cd3dceab9a1cf1ff158762dba659cfac24f704aa9796facf5c6b8"}, - {file = "osmium-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:11e7a930cc7ac7afedd6d77d267b1899942a0236ff4351e1ba1f9f228789dee1"}, - {file = "osmium-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb99685d18f08e766ba8d971a7f93a3bfb2829b917996591a7cfec053c2711b3"}, - {file = "osmium-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:360bf9b30ed995e3d3e359eada5c3690c850eb1453a699c739a2f45a5d8c4ee4"}, - {file = "osmium-3.6.0.tar.gz", hash = "sha256:c7b4becb5f13aa82421b269e583bee4d14b56a2c490b334d44ec954cb480a289"}, -] - -[package.dependencies] -requests = "*" - -[[package]] -name = "osmnx" -version = "1.2.2" -description = "Retrieve, model, analyze, and visualize OpenStreetMap street networks and other spatial data" -optional = false -python-versions = ">=3.8" -files = [ - {file = "osmnx-1.2.2-py2.py3-none-any.whl", hash = "sha256:94f2a3929e857d8c0da39ae552c6da3b1a3f4bcfea6de108696bda5ee3a7689d"}, - {file = "osmnx-1.2.2.tar.gz", hash = "sha256:30924452ca02758ece3301f9fcfb1b80edf31e2be7abe7fa7e0fefddb5050408"}, -] - -[package.dependencies] -geopandas = ">=0.11" -matplotlib = ">=3.5" -networkx = ">=2.8" -numpy = ">=1.22" -pandas = ">=1.4" -pyproj = ">=3.3" -requests = ">=2.28" -Rtree = ">=1.0" -Shapely = ">=1.8,<2.0" - -[package.extras] -entropy = ["scipy"] -nearest-neighbor = ["scikit-learn", "scipy"] -raster = ["gdal", "rasterio"] -web-map = ["folium"] - -[[package]] -name = "overrides" -version = "7.4.0" -description = "A decorator to automatically detect mismatch when overriding a method." -optional = false -python-versions = ">=3.6" -files = [ - {file = "overrides-7.4.0-py3-none-any.whl", hash = "sha256:3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d"}, - {file = "overrides-7.4.0.tar.gz", hash = "sha256:9502a3cca51f4fac40b5feca985b6703a5c1f6ad815588a7ca9e285b9dca6757"}, -] - [[package]] name = "packaging" version = "23.1" @@ -5496,327 +2320,6 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] -[[package]] -name = "pandas" -version = "1.5.1" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-1.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a78e05ec09731c5b3bd7a9805927ea631fe6f6cb06f0e7c63191a9a778d52b4"}, - {file = "pandas-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5b0c970e2215572197b42f1cff58a908d734503ea54b326412c70d4692256391"}, - {file = "pandas-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f340331a3f411910adfb4bbe46c2ed5872d9e473a783d7f14ecf49bc0869c594"}, - {file = "pandas-1.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8c709f4700573deb2036d240d140934df7e852520f4a584b2a8d5443b71f54d"}, - {file = "pandas-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32e3d9f65606b3f6e76555bfd1d0b68d94aff0929d82010b791b6254bf5a4b96"}, - {file = "pandas-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a52419d9ba5906db516109660b114faf791136c94c1a636ed6b29cbfff9187ee"}, - {file = "pandas-1.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:66a1ad667b56e679e06ba73bb88c7309b3f48a4c279bd3afea29f65a766e9036"}, - {file = "pandas-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36aa1f8f680d7584e9b572c3203b20d22d697c31b71189322f16811d4ecfecd3"}, - {file = "pandas-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bcf1a82b770b8f8c1e495b19a20d8296f875a796c4fe6e91da5ef107f18c5ecb"}, - {file = "pandas-1.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c25e5c16ee5c0feb6cf9d982b869eec94a22ddfda9aa2fbed00842cbb697624"}, - {file = "pandas-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:932d2d7d3cab44cfa275601c982f30c2d874722ef6396bb539e41e4dc4618ed4"}, - {file = "pandas-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:eb7e8cf2cf11a2580088009b43de84cabbf6f5dae94ceb489f28dba01a17cb77"}, - {file = "pandas-1.5.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cb2a9cf1150302d69bb99861c5cddc9c25aceacb0a4ef5299785d0f5389a3209"}, - {file = "pandas-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:81f0674fa50b38b6793cd84fae5d67f58f74c2d974d2cb4e476d26eee33343d0"}, - {file = "pandas-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:17da7035d9e6f9ea9cdc3a513161f8739b8f8489d31dc932bc5a29a27243f93d"}, - {file = "pandas-1.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:669c8605dba6c798c1863157aefde959c1796671ffb342b80fcb80a4c0bc4c26"}, - {file = "pandas-1.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:683779e5728ac9138406c59a11e09cd98c7d2c12f0a5fc2b9c5eecdbb4a00075"}, - {file = "pandas-1.5.1-cp38-cp38-win32.whl", hash = "sha256:ddf46b940ef815af4e542697eaf071f0531449407a7607dd731bf23d156e20a7"}, - {file = "pandas-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:db45b94885000981522fb92349e6b76f5aee0924cc5315881239c7859883117d"}, - {file = "pandas-1.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:927e59c694e039c75d7023465d311277a1fc29ed7236b5746e9dddf180393113"}, - {file = "pandas-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e675f8fe9aa6c418dc8d3aac0087b5294c1a4527f1eacf9fe5ea671685285454"}, - {file = "pandas-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04e51b01d5192499390c0015630975f57836cc95c7411415b499b599b05c0c96"}, - {file = "pandas-1.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cee0c74e93ed4f9d39007e439debcaadc519d7ea5c0afc3d590a3a7b2edf060"}, - {file = "pandas-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b156a971bc451c68c9e1f97567c94fd44155f073e3bceb1b0d195fd98ed12048"}, - {file = "pandas-1.5.1-cp39-cp39-win32.whl", hash = "sha256:05c527c64ee02a47a24031c880ee0ded05af0623163494173204c5b72ddce658"}, - {file = "pandas-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:6bb391659a747cf4f181a227c3e64b6d197100d53da98dcd766cc158bdd9ec68"}, - {file = "pandas-1.5.1.tar.gz", hash = "sha256:249cec5f2a5b22096440bd85c33106b6102e0672204abd2d5c014106459804ee"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.1" -pytz = ">=2020.1" - -[package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] - -[[package]] -name = "pandas" -version = "1.5.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e9dbacd22555c2d47f262ef96bb4e30880e5956169741400af8b306bbb24a273"}, - {file = "pandas-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e2b83abd292194f350bb04e188f9379d36b8dfac24dd445d5c87575f3beaf789"}, - {file = "pandas-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2552bffc808641c6eb471e55aa6899fa002ac94e4eebfa9ec058649122db5824"}, - {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc87eac0541a7d24648a001d553406f4256e744d92df1df8ebe41829a915028"}, - {file = "pandas-1.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0d8fd58df5d17ddb8c72a5075d87cd80d71b542571b5f78178fb067fa4e9c72"}, - {file = "pandas-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:4aed257c7484d01c9a194d9a94758b37d3d751849c05a0050c087a358c41ad1f"}, - {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:375262829c8c700c3e7cbb336810b94367b9c4889818bbd910d0ecb4e45dc261"}, - {file = "pandas-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc3cd122bea268998b79adebbb8343b735a5511ec14efb70a39e7acbc11ccbdc"}, - {file = "pandas-1.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4f5a82afa4f1ff482ab8ded2ae8a453a2cdfde2001567b3ca24a4c5c5ca0db3"}, - {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8092a368d3eb7116e270525329a3e5c15ae796ccdf7ccb17839a73b4f5084a39"}, - {file = "pandas-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6257b314fc14958f8122779e5a1557517b0f8e500cfb2bd53fa1f75a8ad0af2"}, - {file = "pandas-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:82ae615826da838a8e5d4d630eb70c993ab8636f0eff13cb28aafc4291b632b5"}, - {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:457d8c3d42314ff47cc2d6c54f8fc0d23954b47977b2caed09cd9635cb75388b"}, - {file = "pandas-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c009a92e81ce836212ce7aa98b219db7961a8b95999b97af566b8dc8c33e9519"}, - {file = "pandas-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:71f510b0efe1629bf2f7c0eadb1ff0b9cf611e87b73cd017e6b7d6adb40e2b3a"}, - {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a40dd1e9f22e01e66ed534d6a965eb99546b41d4d52dbdb66565608fde48203f"}, - {file = "pandas-1.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae7e989f12628f41e804847a8cc2943d362440132919a69429d4dea1f164da0"}, - {file = "pandas-1.5.2-cp38-cp38-win32.whl", hash = "sha256:530948945e7b6c95e6fa7aa4be2be25764af53fba93fe76d912e35d1c9ee46f5"}, - {file = "pandas-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:73f219fdc1777cf3c45fde7f0708732ec6950dfc598afc50588d0d285fddaefc"}, - {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9608000a5a45f663be6af5c70c3cbe634fa19243e720eb380c0d378666bc7702"}, - {file = "pandas-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:315e19a3e5c2ab47a67467fc0362cb36c7c60a93b6457f675d7d9615edad2ebe"}, - {file = "pandas-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e18bc3764cbb5e118be139b3b611bc3fbc5d3be42a7e827d1096f46087b395eb"}, - {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0183cb04a057cc38fde5244909fca9826d5d57c4a5b7390c0cc3fa7acd9fa883"}, - {file = "pandas-1.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:344021ed3e639e017b452aa8f5f6bf38a8806f5852e217a7594417fb9bbfa00e"}, - {file = "pandas-1.5.2-cp39-cp39-win32.whl", hash = "sha256:e7469271497960b6a781eaa930cba8af400dd59b62ec9ca2f4d31a19f2f91090"}, - {file = "pandas-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:c218796d59d5abd8780170c937b812c9637e84c32f8271bbf9845970f8c1351f"}, - {file = "pandas-1.5.2.tar.gz", hash = "sha256:220b98d15cee0b2cd839a6358bd1f273d0356bf964c1a1aeb32d47db0215488b"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.1" -pytz = ">=2020.1" - -[package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] - -[[package]] -name = "pandas" -version = "1.5.3" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, - {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, - {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, - {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, - {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, - {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, - {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, - {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, - {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, - {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, - {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, - {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, - {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, - {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, - {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, - {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.1" -pytz = ">=2020.1" - -[package.extras] -test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] - -[[package]] -name = "pandas" -version = "2.0.0" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bbb2c5e94d6aa4e632646a3bacd05c2a871c3aa3e85c9bec9be99cb1267279f2"}, - {file = "pandas-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b5337c87c4e963f97becb1217965b6b75c6fe5f54c4cf09b9a5ac52fc0bd03d3"}, - {file = "pandas-2.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ded51f7e3dd9b4f8b87f2ceb7bd1a8df2491f7ee72f7074c6927a512607199e"}, - {file = "pandas-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c858de9e9fc422d25e67e1592a6e6135d7bcf9a19fcaf4d0831a0be496bf21"}, - {file = "pandas-2.0.0-cp310-cp310-win32.whl", hash = "sha256:2d1d138848dd71b37e3cbe7cd952ff84e2ab04d8988972166e18567dcc811245"}, - {file = "pandas-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:d08e41d96bc4de6f500afe80936c68fce6099d5a434e2af7c7fd8e7c72a3265d"}, - {file = "pandas-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24472cfc7ced511ac90608728b88312be56edc8f19b9ed885a7d2e47ffaf69c0"}, - {file = "pandas-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ffb14f50c74ee541610668137830bb93e9dfa319b1bef2cedf2814cd5ac9c70"}, - {file = "pandas-2.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c24c7d12d033a372a9daf9ff2c80f8b0af6f98d14664dbb0a4f6a029094928a7"}, - {file = "pandas-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8318de0f886e4dcb8f9f36e45a3d6a6c3d1cfdc508354da85e739090f0222991"}, - {file = "pandas-2.0.0-cp311-cp311-win32.whl", hash = "sha256:57c34b79c13249505e850d0377b722961b99140f81dafbe6f19ef10239f6284a"}, - {file = "pandas-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:8f987ec26e96a8490909bc5d98c514147236e49830cba7df8690f6087c12bbae"}, - {file = "pandas-2.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b3ba8f5dd470d8bfbc4259829589f4a32881151c49e36384d9eb982b35a12020"}, - {file = "pandas-2.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fcd471c9d9f60926ab2f15c6c29164112f458acb42280365fbefa542d0c2fc74"}, - {file = "pandas-2.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9253edfd015520ce77a9343eb7097429479c039cd3ebe81d7810ea11b4b24695"}, - {file = "pandas-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977326039bd1ded620001a1889e2ed4798460a6bc5a24fbaebb5f07a41c32a55"}, - {file = "pandas-2.0.0-cp38-cp38-win32.whl", hash = "sha256:78425ca12314b23356c28b16765639db10ebb7d8983f705d6759ff7fe41357fa"}, - {file = "pandas-2.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:d93b7fcfd9f3328072b250d6d001dcfeec5d3bb66c1b9c8941e109a46c0c01a8"}, - {file = "pandas-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:425705cee8be54db2504e8dd2a730684790b15e5904b750c367611ede49098ab"}, - {file = "pandas-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a4f789b7c012a608c08cda4ff0872fd979cb18907a37982abe884e6f529b8793"}, - {file = "pandas-2.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bb9d840bf15656805f6a3d87eea9dcb7efdf1314a82adcf7f00b820427c5570"}, - {file = "pandas-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0778ab54c8f399d83d98ffb674d11ec716449956bc6f6821891ab835848687f2"}, - {file = "pandas-2.0.0-cp39-cp39-win32.whl", hash = "sha256:70db5c278bbec0306d32bf78751ff56b9594c05a5098386f6c8a563659124f91"}, - {file = "pandas-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f3320bb55f34af4193020158ef8118ee0fb9aec7cc47d2084dbfdd868a0a24f"}, - {file = "pandas-2.0.0.tar.gz", hash = "sha256:cda9789e61b44463c1c4fe17ef755de77bcd13b09ba31c940d20f193d63a5dc8"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] - -[[package]] -name = "pandas" -version = "2.0.1" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70a996a1d2432dadedbb638fe7d921c88b0cc4dd90374eab51bb33dc6c0c2a12"}, - {file = "pandas-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:909a72b52175590debbf1d0c9e3e6bce2f1833c80c76d80bd1aa09188be768e5"}, - {file = "pandas-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe7914d8ddb2d54b900cec264c090b88d141a1eed605c9539a187dbc2547f022"}, - {file = "pandas-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a514ae436b23a92366fbad8365807fc0eed15ca219690b3445dcfa33597a5cc"}, - {file = "pandas-2.0.1-cp310-cp310-win32.whl", hash = "sha256:12bd6618e3cc737c5200ecabbbb5eaba8ab645a4b0db508ceeb4004bb10b060e"}, - {file = "pandas-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:2b6fe5f7ce1cba0e74188c8473c9091ead9b293ef0a6794939f8cc7947057abd"}, - {file = "pandas-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:00959a04a1d7bbc63d75a768540fb20ecc9e65fd80744c930e23768345a362a7"}, - {file = "pandas-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af2449e9e984dfad39276b885271ba31c5e0204ffd9f21f287a245980b0e4091"}, - {file = "pandas-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:910df06feaf9935d05247db6de452f6d59820e432c18a2919a92ffcd98f8f79b"}, - {file = "pandas-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fa0067f2419f933101bdc6001bcea1d50812afbd367b30943417d67fbb99678"}, - {file = "pandas-2.0.1-cp311-cp311-win32.whl", hash = "sha256:7b8395d335b08bc8b050590da264f94a439b4770ff16bb51798527f1dd840388"}, - {file = "pandas-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:8db5a644d184a38e6ed40feeb12d410d7fcc36648443defe4707022da127fc35"}, - {file = "pandas-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7bbf173d364130334e0159a9a034f573e8b44a05320995127cf676b85fd8ce86"}, - {file = "pandas-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c0853d487b6c868bf107a4b270a823746175b1932093b537b9b76c639fc6f7e"}, - {file = "pandas-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25e23a03f7ad7211ffa30cb181c3e5f6d96a8e4cb22898af462a7333f8a74eb"}, - {file = "pandas-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e09a53a4fe8d6ae2149959a2d02e1ef2f4d2ceb285ac48f74b79798507e468b4"}, - {file = "pandas-2.0.1-cp38-cp38-win32.whl", hash = "sha256:a2564629b3a47b6aa303e024e3d84e850d36746f7e804347f64229f8c87416ea"}, - {file = "pandas-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:03e677c6bc9cfb7f93a8b617d44f6091613a5671ef2944818469be7b42114a00"}, - {file = "pandas-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d099ecaa5b9e977b55cd43cf842ec13b14afa1cfa51b7e1179d90b38c53ce6a"}, - {file = "pandas-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a37ee35a3eb6ce523b2c064af6286c45ea1c7ff882d46e10d0945dbda7572753"}, - {file = "pandas-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:320b180d125c3842c5da5889183b9a43da4ebba375ab2ef938f57bf267a3c684"}, - {file = "pandas-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18d22cb9043b6c6804529810f492ab09d638ddf625c5dea8529239607295cb59"}, - {file = "pandas-2.0.1-cp39-cp39-win32.whl", hash = "sha256:90d1d365d77d287063c5e339f49b27bd99ef06d10a8843cf00b1a49326d492c1"}, - {file = "pandas-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:99f7192d8b0e6daf8e0d0fd93baa40056684e4b4aaaef9ea78dff34168e1f2f0"}, - {file = "pandas-2.0.1.tar.gz", hash = "sha256:19b8e5270da32b41ebf12f0e7165efa7024492e9513fb46fb631c5022ae5709d"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] - -[[package]] -name = "pandas" -version = "2.0.2" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pandas-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ebb9f1c22ddb828e7fd017ea265a59d80461d5a79154b49a4207bd17514d122"}, - {file = "pandas-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eb09a242184092f424b2edd06eb2b99d06dc07eeddff9929e8667d4ed44e181"}, - {file = "pandas-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7319b6e68de14e6209460f72a8d1ef13c09fb3d3ef6c37c1e65b35d50b5c145"}, - {file = "pandas-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd46bde7309088481b1cf9c58e3f0e204b9ff9e3244f441accd220dd3365ce7c"}, - {file = "pandas-2.0.2-cp310-cp310-win32.whl", hash = "sha256:51a93d422fbb1bd04b67639ba4b5368dffc26923f3ea32a275d2cc450f1d1c86"}, - {file = "pandas-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:66d00300f188fa5de73f92d5725ced162488f6dc6ad4cecfe4144ca29debe3b8"}, - {file = "pandas-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02755de164da6827764ceb3bbc5f64b35cb12394b1024fdf88704d0fa06e0e2f"}, - {file = "pandas-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0a1e0576611641acde15c2322228d138258f236d14b749ad9af498ab69089e2d"}, - {file = "pandas-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6b5f14cd24a2ed06e14255ff40fe2ea0cfaef79a8dd68069b7ace74bd6acbba"}, - {file = "pandas-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50e451932b3011b61d2961b4185382c92cc8c6ee4658dcd4f320687bb2d000ee"}, - {file = "pandas-2.0.2-cp311-cp311-win32.whl", hash = "sha256:7b21cb72958fc49ad757685db1919021d99650d7aaba676576c9e88d3889d456"}, - {file = "pandas-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:c4af689352c4fe3d75b2834933ee9d0ccdbf5d7a8a7264f0ce9524e877820c08"}, - {file = "pandas-2.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69167693cb8f9b3fc060956a5d0a0a8dbfed5f980d9fd2c306fb5b9c855c814c"}, - {file = "pandas-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:30a89d0fec4263ccbf96f68592fd668939481854d2ff9da709d32a047689393b"}, - {file = "pandas-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a18e5c72b989ff0f7197707ceddc99828320d0ca22ab50dd1b9e37db45b010c0"}, - {file = "pandas-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7376e13d28eb16752c398ca1d36ccfe52bf7e887067af9a0474de6331dd948d2"}, - {file = "pandas-2.0.2-cp38-cp38-win32.whl", hash = "sha256:6d6d10c2142d11d40d6e6c0a190b1f89f525bcf85564707e31b0a39e3b398e08"}, - {file = "pandas-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:e69140bc2d29a8556f55445c15f5794490852af3de0f609a24003ef174528b79"}, - {file = "pandas-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b42b120458636a981077cfcfa8568c031b3e8709701315e2bfa866324a83efa8"}, - {file = "pandas-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f908a77cbeef9bbd646bd4b81214cbef9ac3dda4181d5092a4aa9797d1bc7774"}, - {file = "pandas-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:713f2f70abcdade1ddd68fc91577cb090b3544b07ceba78a12f799355a13ee44"}, - {file = "pandas-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf3f0c361a4270185baa89ec7ab92ecaa355fe783791457077473f974f654df5"}, - {file = "pandas-2.0.2-cp39-cp39-win32.whl", hash = "sha256:598e9020d85a8cdbaa1815eb325a91cfff2bb2b23c1442549b8a3668e36f0f77"}, - {file = "pandas-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:77550c8909ebc23e56a89f91b40ad01b50c42cfbfab49b3393694a50549295ea"}, - {file = "pandas-2.0.2.tar.gz", hash = "sha256:dd5476b6c3fe410ee95926873f377b856dbc4e81a9c605a0dc05aaccc6a7c6c6"}, -] - -[package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.1" - -[package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] -feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] -parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] -plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] - [[package]] name = "pandas" version = "2.0.3" @@ -5852,7 +2355,10 @@ files = [ ] [package.dependencies] -numpy = {version = ">=1.21.0", markers = "python_version >= \"3.10\""} +numpy = [ + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, +] python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" @@ -5880,17 +2386,6 @@ sql-other = ["SQLAlchemy (>=1.4.16)"] test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.6.3)"] -[[package]] -name = "pandocfilters" -version = "1.5.0" -description = "Utilities for writing pandoc filters in python" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, - {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, -] - [[package]] name = "panflute" version = "2.3.0" @@ -5925,67 +2420,6 @@ files = [ [package.extras] dev = ["jinja2"] -[[package]] -name = "paramiko" -version = "3.3.1" -description = "SSH2 protocol library" -optional = false -python-versions = ">=3.6" -files = [ - {file = "paramiko-3.3.1-py3-none-any.whl", hash = "sha256:b7bc5340a43de4287bbe22fe6de728aa2c22468b2a849615498dd944c2f275eb"}, - {file = "paramiko-3.3.1.tar.gz", hash = "sha256:6a3777a961ac86dbef375c5f5b8d50014a1a96d0fd7f054a43bc880134b0ff77"}, -] - -[package.dependencies] -bcrypt = ">=3.2" -cryptography = ">=3.3" -pynacl = ">=1.5" - -[package.extras] -all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] -gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"] -invoke = ["invoke (>=2.0)"] - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "pillow" version = "10.0.0" @@ -6055,97 +2489,6 @@ files = [ docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -[[package]] -name = "pillow-avif-plugin" -version = "1.3.1" -description = "A pillow plugin that adds avif support via libavif" -optional = false -python-versions = "*" -files = [ - {file = "pillow-avif-plugin-1.3.1.tar.gz", hash = "sha256:7da21ffce23f9b497a868af2d3e03b03ffacb29c1c727903e84a73df42b489f1"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:ce7be67200f8250d7c06cd0f701ea760faf73fd13df5962a28edabf4c61c36ec"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27m-macosx_11_0_arm64.whl", hash = "sha256:e8cf59907cd39df592e447ae647119d1cb0a0250bcc88868036022905c404141"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:42fe51eb2ae682639e1bf3a846e4b4d5a47805af9524bbf1a12bf5ae20c73995"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:40baaa3848fd2a8648c7102a4214c4e0192b05a43bb1d8c7e2cc4f9866088f82"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:a64620e8f6287edf8360cd79eb1dabc803476a5da1daf3c405461d00f2033c25"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:81e9e549a67cc3d34e91231f9de7ef9467744845e155e9acdd58b21840c9dee5"}, - {file = "pillow_avif_plugin-1.3.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d72f6fe7eff8ddcd1d7316b215b05c23afc5840bc20cb47f33c39c8dc3765c2f"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:b10fb7753383f868a4c44db99c29fb3b25b2c1d70ef3f0578ba8ef6440ab32f1"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a7944b1deb016921e1e8e15eb59ed0b302ed78a05858dffaf5cd02109146f812"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d0dea55b5ee37de3eb31f0b89d2b9b8b533bfacc1eabfc04c7cc3e06634c494f"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f13ffc7a385590825c89f08a073c7ccd4709d96b6de378fa203fcd1956beb1a7"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f1e67c653999befe3b676c53c27b88a9a7d227f685fe17be4331527190e656"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a35087b13c7ab60a203302eeac85c95a1112d8ae1a16949173cd281558671d23"}, - {file = "pillow_avif_plugin-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:d7a3af04841cc0ac4cb7843a1965eac640e4578cd7c2d44ed3470326f2569e58"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9cf44bc41f109c43976e5f073beb6e55314b6fe7ba75a8b59d9ed15f13fa77bc"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85bed54fbf514b3ac9cf48046c8837ca4781ea5288bd51b38ecf86094d721f88"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a3f0b38ceca8815a7e2fa1d911027d4e817fab667d63a50ecb7946ca5ae6ddd"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a9b8e8943a8b9f860d2b03e0b9c9839bc59db22c5a0a55d66a534a3d4cea00b"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98dbb6b21ab5b7e0d80134721e756c956d4de2c6cb5c48bb32f78f97339425cb"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c4d0b80ff0819de1ba6d401796bc900be252468621b6e734560eee2ea154dbb4"}, - {file = "pillow_avif_plugin-1.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:c4ff1d331df8ca0f0c5c90d3f05b3a05325c40c9f330e0ad58eb70f7ede20157"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:0a02a436494e380fc99d5ff48be2ef15d42ce655614b9ebd80e106615eb3a594"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:fe8250efd581e362a135d63bbca62b0c78ef1e474582da4013c3a995bc1f40c2"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:39e93224a3d0132a64e7d978e48b74f020c65fcb3a141641084d2a4357ed6ceb"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:afc3fb7897ff2e2c0da4cbe3802ffeeb4cafbfccb1adb666e287ce087981101e"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c7230d888adab65a92658d94ae7ad79731d30242bdfed5f945cb12e822927e0e"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e7740e7b6bb22b3781a0e7f8e20b4b2071940504cf5d5705a3c870ff0b001c7c"}, - {file = "pillow_avif_plugin-1.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b696be6597766c37035cf337e248732da35e2f1ebc7aa4dad5a93c9ed5e1245a"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ea0ecc193e1a1ba0f064e605a9d79d82be35d00251638d59b12f924f33e3c4b6"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ab018eb2bbe1d4f1f9276ceb95df93940c623c7eb6791a6fc50780a9c94bc1fa"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee222e2158c043d69af411a85dfadab76d027cc4ecdfa1f6c8d1741baa1eb814"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e5b881e081386ee58bfd2dc556ea8bc283cec83bcea3e77508b2d0483a8a3142"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7835b02615b35814252bd56d5811f09a3daa33c76af75d3ea0f90a556891288"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb7c2987c23c32f9093f6fbcb3c21360370216be85a6054b513cc37acc954fff"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eddac7fdbb83f183b97269657fc520cd8fb2ae91c156be7a799f06db6006dda2"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0ca3e3bc4044194f1b33c54dfb52ea38db6bdd436896806cbdc1249df1262ace"}, - {file = "pillow_avif_plugin-1.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:74a45ffe45d67620149a07cce38c34a17e00da9a360cd399ce337646e159dd73"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:bab68ace09e19f4e230f3cc375b7c17be065e6989c5ca6e3f14f69fc9591926d"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:caaad418e21dec0d6f1bc0e0a00e1346e0e06e335b42da2e5faa19c11d485aab"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f4080e2617da73149b64c21d20ed866998d6ac6ed4e6f4c2b367a9d73f22fd1d"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bcab75f85d934656bb0ade6488933a9f8f0733a0dd1f135208f51087a4931d0e"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4219681022b7206e08c6604a21c8e2985532c65b8dfb1febb1b7199cb4bd7010"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c06019f98840f05272ade0b72fc2cd5a74d6413b070c40c6be5cdd2c0f41046b"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1cbe69338b2af5fd472f65379a2d5497e0ec55187e7faae11bbaebaf90338388"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:982ba9aba18738aa367eff0ffbfcefd0635003c145ed2534dadef33973b90ca5"}, - {file = "pillow_avif_plugin-1.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:b9ab0aa5c0d8cf283db7f85cc380af98f27f8a63891cf5cfa103f9e684dd5e95"}, -] - -[[package]] -name = "pipenv" -version = "2022.10.12" -description = "Python Development Workflow for Humans." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pipenv-2022.10.12-py2.py3-none-any.whl", hash = "sha256:f43972a42411107ade86b6f17dd698dfcd843bd84eb7264163ebb363f6b0ede4"}, - {file = "pipenv-2022.10.12.tar.gz", hash = "sha256:a4d88f6667cbcd9ea432d626a8b373cd3101886b9fb964ea7e7f9650a83fc307"}, -] - -[package.dependencies] -certifi = "*" -setuptools = ">=36.2.1" -virtualenv = "*" -virtualenv-clone = ">=0.2.5" - -[package.extras] -dev = ["black", "bs4", "flake8 (>=3.3.0,<4.0)", "invoke", "parver", "sphinx", "towncrier"] -tests = ["flaky", "mock", "pytest (>=5.0)", "pytest-timeout", "pytest-xdist"] - -[[package]] -name = "pkginfo" -version = "1.9.6" -description = "Query metadata from sdists / bdists / installed packages." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, - {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, -] - -[package.extras] -testing = ["pytest", "pytest-cov"] - [[package]] name = "platformdirs" version = "3.10.0" @@ -6161,21 +2504,6 @@ files = [ docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] -[[package]] -name = "plotly" -version = "5.15.0" -description = "An open-source, interactive data visualization library for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "plotly-5.15.0-py2.py3-none-any.whl", hash = "sha256:3508876bbd6aefb8a692c21a7128ca87ce42498dd041efa5c933ee44b55aab24"}, - {file = "plotly-5.15.0.tar.gz", hash = "sha256:822eabe53997d5ebf23c77e1d1fcbf3bb6aa745eb05d532afd4b6f9a2e2ab02f"}, -] - -[package.dependencies] -packaging = "*" -tenacity = ">=6.2.0" - [[package]] name = "pluggy" version = "1.2.0" @@ -6191,71 +2519,6 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "poetry" -version = "1.5.1" -description = "Python dependency management and packaging made easy." -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry-1.5.1-py3-none-any.whl", hash = "sha256:dfc7ce3a38ae216c0465694e2e674bef6eb1a2ba81aa47a26f9dc03362fe2f5f"}, - {file = "poetry-1.5.1.tar.gz", hash = "sha256:cc7ea4524d1a11558006224bfe8ba8ed071417d4eb5ef6c89decc6a37d437eeb"}, -] - -[package.dependencies] -build = ">=0.10.0,<0.11.0" -cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]} -cleo = ">=2.0.0,<3.0.0" -crashtest = ">=0.4.1,<0.5.0" -dulwich = ">=0.21.2,<0.22.0" -filelock = ">=3.8.0,<4.0.0" -html5lib = ">=1.0,<2.0" -installer = ">=0.7.0,<0.8.0" -jsonschema = ">=4.10.0,<5.0.0" -keyring = ">=23.9.0,<24.0.0" -lockfile = ">=0.12.2,<0.13.0" -packaging = ">=20.4" -pexpect = ">=4.7.0,<5.0.0" -pkginfo = ">=1.9.4,<2.0.0" -platformdirs = ">=3.0.0,<4.0.0" -poetry-core = "1.6.1" -poetry-plugin-export = ">=1.4.0,<2.0.0" -pyproject-hooks = ">=1.0.0,<2.0.0" -requests = ">=2.18,<3.0" -requests-toolbelt = ">=0.9.1,<2" -shellingham = ">=1.5,<2.0" -tomlkit = ">=0.11.4,<1.0.0" -trove-classifiers = ">=2022.5.19" -urllib3 = ">=1.26.0,<2.0.0" -virtualenv = ">=20.22.0,<21.0.0" -xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} - -[[package]] -name = "poetry-core" -version = "1.6.1" -description = "Poetry PEP 517 Build Backend" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_core-1.6.1-py3-none-any.whl", hash = "sha256:70707340447dee0e7f334f9495ae652481c67b32d8d218f296a376ac2ed73573"}, - {file = "poetry_core-1.6.1.tar.gz", hash = "sha256:0f9b0de39665f36d6594657e7d57b6f463cc10f30c28e6d1c3b9ff54c26c9ac3"}, -] - -[[package]] -name = "poetry-plugin-export" -version = "1.4.0" -description = "Poetry plugin to export the dependencies to various formats" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_plugin_export-1.4.0-py3-none-any.whl", hash = "sha256:5d9186d6f77cf2bf35fc96bd11fe650cc7656e515b17d99cb65018d50ba22589"}, - {file = "poetry_plugin_export-1.4.0.tar.gz", hash = "sha256:f16974cd9f222d4ef640fa97a8d661b04d4fb339e51da93973f1bc9d578e183f"}, -] - -[package.dependencies] -poetry = ">=1.5.0,<2.0.0" -poetry-core = ">=1.6.0,<2.0.0" - [[package]] name = "polyline" version = "2.0.0" @@ -6271,25 +2534,6 @@ files = [ dev = ["pylint (>=2.15.10,<2.16.0)", "pytest (>=7.0,<8.0)", "pytest-cov (>=4.0,<5.0)", "sphinx (>=4.2.0,<4.3.0)", "sphinx-rtd-theme (>=1.0.0,<1.1.0)", "toml (>=0.10.2,<0.11.0)"] publish = ["build (>=0.8,<1.0)", "twine (>=4.0,<5.0)"] -[[package]] -name = "portalocker" -version = "2.7.0" -description = "Wraps the portalocker recipe for easy usage" -optional = false -python-versions = ">=3.5" -files = [ - {file = "portalocker-2.7.0-py2.py3-none-any.whl", hash = "sha256:a07c5b4f3985c3cf4798369631fb7011adb498e2a46d8440efc75a8f29a0f983"}, - {file = "portalocker-2.7.0.tar.gz", hash = "sha256:032e81d534a88ec1736d03f780ba073f047a06c478b06e2937486f334e955c51"}, -] - -[package.dependencies] -pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} - -[package.extras] -docs = ["sphinx (>=1.7.1)"] -redis = ["redis"] -tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] - [[package]] name = "pprofile" version = "2.1.0" @@ -6318,79 +2562,26 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" -[[package]] -name = "pretrainedmodels" -version = "0.7.4" -description = "Pretrained models for Pytorch" -optional = false -python-versions = "*" -files = [ - {file = "pretrainedmodels-0.7.4.tar.gz", hash = "sha256:7e77ead4619a3e11ab3c41982c8ad5b86edffe37c87fd2a37ec3c2cc6470b98a"}, -] - -[package.dependencies] -munch = "*" -torch = "*" -torchvision = "*" -tqdm = "*" - -[[package]] -name = "prometheus-client" -version = "0.17.1" -description = "Python client for the Prometheus monitoring system." -optional = false -python-versions = ">=3.6" -files = [ - {file = "prometheus_client-0.17.1-py3-none-any.whl", hash = "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101"}, - {file = "prometheus_client-0.17.1.tar.gz", hash = "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091"}, -] - -[package.extras] -twisted = ["twisted"] - -[[package]] -name = "prompt-toolkit" -version = "3.0.39" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, - {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, -] - -[package.dependencies] -wcwidth = "*" - [[package]] name = "protobuf" -version = "3.20.3" -description = "Protocol Buffers" +version = "4.24.0" +description = "" optional = false python-versions = ">=3.7" files = [ - {file = "protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, - {file = "protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, - {file = "protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, - {file = "protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, - {file = "protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, - {file = "protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, - {file = "protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, - {file = "protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, - {file = "protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, - {file = "protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, - {file = "protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, - {file = "protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, - {file = "protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, - {file = "protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, - {file = "protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, - {file = "protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, + {file = "protobuf-4.24.0-cp310-abi3-win32.whl", hash = "sha256:81cb9c4621d2abfe181154354f63af1c41b00a4882fb230b4425cbaed65e8f52"}, + {file = "protobuf-4.24.0-cp310-abi3-win_amd64.whl", hash = "sha256:6c817cf4a26334625a1904b38523d1b343ff8b637d75d2c8790189a4064e51c3"}, + {file = "protobuf-4.24.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ae97b5de10f25b7a443b40427033e545a32b0e9dda17bcd8330d70033379b3e5"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:567fe6b0647494845d0849e3d5b260bfdd75692bf452cdc9cb660d12457c055d"}, + {file = "protobuf-4.24.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:a6b1ca92ccabfd9903c0c7dde8876221dc7d8d87ad5c42e095cc11b15d3569c7"}, + {file = "protobuf-4.24.0-cp37-cp37m-win32.whl", hash = "sha256:a38400a692fd0c6944c3c58837d112f135eb1ed6cdad5ca6c5763336e74f1a04"}, + {file = "protobuf-4.24.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5ab19ee50037d4b663c02218a811a5e1e7bb30940c79aac385b96e7a4f9daa61"}, + {file = "protobuf-4.24.0-cp38-cp38-win32.whl", hash = "sha256:e8834ef0b4c88666ebb7c7ec18045aa0f4325481d724daa624a4cf9f28134653"}, + {file = "protobuf-4.24.0-cp38-cp38-win_amd64.whl", hash = "sha256:8bb52a2be32db82ddc623aefcedfe1e0eb51da60e18fcc908fb8885c81d72109"}, + {file = "protobuf-4.24.0-cp39-cp39-win32.whl", hash = "sha256:ae7a1835721086013de193311df858bc12cd247abe4ef9710b715d930b95b33e"}, + {file = "protobuf-4.24.0-cp39-cp39-win_amd64.whl", hash = "sha256:44825e963008f8ea0d26c51911c30d3e82e122997c3c4568fd0385dd7bacaedf"}, + {file = "protobuf-4.24.0-py3-none-any.whl", hash = "sha256:82e6e9ebdd15b8200e8423676eab38b774624d6a1ad696a60d86a2ac93f18201"}, + {file = "protobuf-4.24.0.tar.gz", hash = "sha256:5d0ceb9de6e08311832169e601d1fc71bd8e8c779f3ee38a97a78554945ecb85"}, ] [[package]] @@ -6419,31 +2610,6 @@ files = [ [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] - -[package.extras] -tests = ["pytest"] - [[package]] name = "pyaudio" version = "0.2.13" @@ -6507,17 +2673,6 @@ files = [ {file = "pycapnp-1.3.0.tar.gz", hash = "sha256:7cf514c3068064e593d0401503f7a623c24c55776702a7a2d9cad9854710aa56"}, ] -[[package]] -name = "pycodestyle" -version = "2.11.0" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.0-py2.py3-none-any.whl", hash = "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8"}, - {file = "pycodestyle-2.11.0.tar.gz", hash = "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0"}, -] - [[package]] name = "pycparser" version = "2.21" @@ -6570,21 +2725,6 @@ files = [ {file = "pycryptodome-3.18.0.tar.gz", hash = "sha256:c9adee653fc882d98956e33ca2c1fb582e23a8af7ac82fee75bd6113c55a0413"}, ] -[[package]] -name = "pycuda" -version = "2022.2.2" -description = "Python wrapper for Nvidia CUDA" -optional = false -python-versions = "~=3.8" -files = [ - {file = "pycuda-2022.2.2.tar.gz", hash = "sha256:cd92e7246bb45ac3452955a110714112674cdf3b4a9e2f4ff25a4159c684e6bb"}, -] - -[package.dependencies] -appdirs = ">=1.4.0" -mako = "*" -pytools = ">=2011.2" - [[package]] name = "pycurl" version = "7.45.2" @@ -6623,17 +2763,6 @@ typing-extensions = "*" [package.extras] dev = ["black", "flake8", "flake8-black", "isort", "jupyter-console", "mkdocs", "mkdocs-include-markdown-plugin", "mkdocstrings[python]", "pytest", "pytest-asyncio", "pytest-trio", "toml", "tox", "trio", "trio", "trio-typing", "twine", "twisted", "validate-pyproject[all]"] -[[package]] -name = "pyflakes" -version = "3.1.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, - {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, -] - [[package]] name = "pygame" version = "2.5.0" @@ -6723,9 +2852,6 @@ files = [ {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"}, ] -[package.dependencies] -cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} - [package.extras] crypto = ["cryptography (>=3.4.0)"] dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] @@ -6794,117 +2920,6 @@ files = [ [package.dependencies] cffi = ">=1.0.0" -[[package]] -name = "pylint" -version = "2.17.5" -description = "python code static checker" -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"}, - {file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"}, -] - -[package.dependencies] -astroid = ">=2.15.6,<=2.17.0-dev0" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""} -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.8" -platformdirs = ">=2.2.0" -tomlkit = ">=0.10.1" - -[package.extras] -spelling = ["pyenchant (>=3.2,<4.0)"] -testutils = ["gitpython (>3)"] - -[[package]] -name = "pymsalruntime" -version = "0.13.9" -description = "The MSALRuntime Python Interop Package" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pymsalruntime-0.13.9-cp310-cp310-win32.whl", hash = "sha256:d61dbca27f6b1aec647c7e2487ac3ac0274f69dc29c8b26f4ff0ee6d85c7414c"}, - {file = "pymsalruntime-0.13.9-cp310-cp310-win_amd64.whl", hash = "sha256:1f0ed70cbd2f6c67ef5af0a41ccdb001566cce17432bb63eb775bee3369f76b0"}, - {file = "pymsalruntime-0.13.9-cp311-cp311-win32.whl", hash = "sha256:0220580e0f0a15f82d3b77ba92202c1c2c083d20903e691c54a8b055fa4bcf8f"}, - {file = "pymsalruntime-0.13.9-cp311-cp311-win_amd64.whl", hash = "sha256:e5146759fb50eb1bf17287b4b61e0a8eb23dd6100798aeefbc8bdea16217fa2d"}, - {file = "pymsalruntime-0.13.9-cp36-cp36m-win32.whl", hash = "sha256:3d732eb305c2114bee1bc5a579ef0dad188de751924c1262a64127d99e75f6a4"}, - {file = "pymsalruntime-0.13.9-cp36-cp36m-win_amd64.whl", hash = "sha256:a63b6e034d43895b6183897a40c4fc589a680019664744e1cb9da4153afed01d"}, - {file = "pymsalruntime-0.13.9-cp37-cp37m-win32.whl", hash = "sha256:e0a8478449a73ace3a4c408c1116361b74e074902defeb7a97eb6337cc37951e"}, - {file = "pymsalruntime-0.13.9-cp37-cp37m-win_amd64.whl", hash = "sha256:781ef1de3e3335e255c0a17c31a1ecc8eecfb5f274129a76e82428d3d9867cc1"}, - {file = "pymsalruntime-0.13.9-cp38-cp38-win32.whl", hash = "sha256:8f67291ab983dc70e23ad35cb570452aec3b0960475956398039a6cafd79cde2"}, - {file = "pymsalruntime-0.13.9-cp38-cp38-win_amd64.whl", hash = "sha256:9381347abb2df60c54d864d4efe067d9afcb970d6b8f393602ac62a265230ff1"}, - {file = "pymsalruntime-0.13.9-cp39-cp39-win32.whl", hash = "sha256:226752759d8fb09592e343d0870ed8d23ab2137ba0a2c1b838936599728450ba"}, - {file = "pymsalruntime-0.13.9-cp39-cp39-win_amd64.whl", hash = "sha256:91488f5e2d0d9260afb99428264f03afc9f32ae977695ff3676ac7f86d1fe2ed"}, - {file = "pymsalruntime-0.13.9.tar.gz", hash = "sha256:aac8c9cc930bce394e3c50f622c65c1bcd9c3d2e9a8d7c1a9e0cef2bd70d2d84"}, -] - -[[package]] -name = "pymysql" -version = "0.9.3" -description = "Pure Python MySQL Driver" -optional = false -python-versions = "*" -files = [ - {file = "PyMySQL-0.9.3-py2.py3-none-any.whl", hash = "sha256:3943fbbbc1e902f41daf7f9165519f140c4451c179380677e6a848587042561a"}, - {file = "PyMySQL-0.9.3.tar.gz", hash = "sha256:d8c059dcd81dedb85a9f034d5e22dcb4442c0b201908bede99e306d65ea7c8e7"}, -] - -[package.extras] -rsa = ["cryptography"] - -[[package]] -name = "pynacl" -version = "1.5.0" -description = "Python binding to the Networking and Cryptography (NaCl) library" -optional = false -python-versions = ">=3.6" -files = [ - {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, - {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, - {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, - {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, - {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, - {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, -] - -[package.dependencies] -cffi = ">=1.4.1" - -[package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] -tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] - -[[package]] -name = "PyNvCodec" -version = "2.0" -description = "Video Processing Library with full NVENC/NVDEC hardware acceleration" -optional = false -python-versions = "*" -files = [] -develop = false - -[package.dependencies] -numpy = "*" - -[package.extras] -dev = ["PytorchNvCodec @ file:///home/batman/.pyenv/versions/3.11.4/src/VideoProcessingFramework/src/PytorchNvCodec", "onnx", "opencv-python", "pycuda", "pyopengl", "tensorrt", "torch", "torchvision"] -samples = ["PytorchNvCodec @ git+https://github.com/NVIDIA/VideoProcessingFramework.git#subdirectory=src/PytorchNvCodec/", "onnx", "opencv-python", "pycuda", "pyopengl", "tensorrt", "torch", "torchvision", "tqdm"] -tensorrt = ["PytorchNvCodec @ git+https://github.com/NVIDIA/VideoProcessingFramework.git#subdirectory=src/PytorchNvCodec/", "torch", "torchvision"] -tests = ["PytorchNvCodec @ git+https://github.com/NVIDIA/VideoProcessingFramework.git#subdirectory=src/PytorchNvCodec/", "opencv-python", "pycuda", "pyopengl", "torch", "torchvision"] -torch = ["PytorchNvCodec @ git+https://github.com/NVIDIA/VideoProcessingFramework.git#subdirectory=src/PytorchNvCodec/", "torch", "torchvision"] - -[package.source] -type = "git" -url = "https://github.com/NVIDIA/VideoProcessingFramework.git" -reference = "HEAD" -resolved_reference = "f45e862b3e735c5a5f0c2b16b5394e71eadcc0d7" - [[package]] name = "pyopencl" version = "2023.1.1" @@ -6996,62 +3011,64 @@ files = [ ] [[package]] -name = "pyproj" -version = "3.6.0" -description = "Python interface to PROJ (cartographic projections and coordinate transformations library)" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pyproj-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e600f6a2771d3b41aeb2cc1efd96771ae9a01451013da1dd48ff272e7c6e34ef"}, - {file = "pyproj-3.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d7f6cd045df29aae960391dfe06a575c110af598f1dea5add8be6ca42332b0f5"}, - {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557e6592855111c84eda176ddf6b130f55d5e2b9cb1c017b8c91b69f37f474f5"}, - {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de6288b6ceabdeeac01abf627c74414822d322d8f55dc8efe4d29dedd27c5719"}, - {file = "pyproj-3.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e427ccdbb1763872416549bdfa9fa1f5f169054653c4daf674e71480cc39cf11"}, - {file = "pyproj-3.6.0-cp310-cp310-win32.whl", hash = "sha256:1283d3c1960edbb74828f5f3405b27578a9a27f7766ab6a3956f4bd851f08239"}, - {file = "pyproj-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:9de1aab71234bfd3fd648a1152519b5ee152c43113d7d8ea52590a0140129501"}, - {file = "pyproj-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:00fab048596c17572fa8980014ef117dbb2a445e6f7ba3b9ddfcc683efc598e7"}, - {file = "pyproj-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba5e7c8ddd6ed5a3f9fcf95ea80ba44c931913723de2ece841c94bb38b200c4a"}, - {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08dfc5c9533c78a97afae9d53b99b810a4a8f97c3be9eb2b8f323b726c736403"}, - {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18a8bdb87aeb41b60a2e91d32f623227de3569fb83b4c64b174c3a7c5b0ed3ae"}, - {file = "pyproj-3.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfe392dfc0eba2248dc08c976a72f52ff9da2bddfddfd9ff5dcf18e8e88200c7"}, - {file = "pyproj-3.6.0-cp311-cp311-win32.whl", hash = "sha256:78276c6b0c831255c97c56dff7313a3571f327a284d8ac63d6a56437a72ed0e0"}, - {file = "pyproj-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:8fbac2eb9a0e425d7d6b7c6f4ebacd675cf3bdef0c59887057b8b4b0374e7c12"}, - {file = "pyproj-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:95120d65cbc5983dfd877076f28dbc18b9b329cbee38ca6e217bb7a5a043c099"}, - {file = "pyproj-3.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:830e6de7cfe43853967afee5ef908dfd5aa72d1ec12af9b9e3fecc179886e346"}, - {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e342b3010b2b20134671564ff9a8c476e5e512bf589477480aded1a5813af7c8"}, - {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23787460fab85ba2f857ee60ffb2e8e21fd9bd5db9833c51c1c05b2a6d9f0be5"}, - {file = "pyproj-3.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595376e4d3bb72b7dceeccbce0f4c43053d47561f17a1ad0224407e9980ee849"}, - {file = "pyproj-3.6.0-cp39-cp39-win32.whl", hash = "sha256:4d8a9773503085eada59b6892c96ddf686ab8cf64cfdc18ad744d13ee76dfa6f"}, - {file = "pyproj-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:137a07404f937f264b11b7130cd4cfa00002dbe4333b222e8056db84849c2ea4"}, - {file = "pyproj-3.6.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2799499a4045e4fb73e44c31bdacab0593a253a7a4b6baae6fdd27d604cf9bc2"}, - {file = "pyproj-3.6.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f04f6297c615c3b17f835df2556ac8fb9b4f51f281e960437eaf0cd80e7ae26a"}, - {file = "pyproj-3.6.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a4d2d438b007cb1f8d5f6f308d53d7ff9a2508cff8f9da6e2a93b76ffd98aaf"}, - {file = "pyproj-3.6.0.tar.gz", hash = "sha256:a5b111865b3f0f8b77b3983f2fbe4dd6248fc09d3730295949977c8dcd988062"}, -] - -[package.dependencies] -certifi = "*" - -[[package]] -name = "pyproject-hooks" -version = "1.0.0" -description = "Wrappers to call pyproject.toml-based build backend hooks." +name = "pyqt5" +version = "5.15.9" +description = "Python bindings for the Qt cross platform application toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"}, - {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"}, + {file = "PyQt5-5.15.9-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:883ba5c8a348be78c8be6a3d3ba014c798e679503bce00d76c666c2dc6afe828"}, + {file = "PyQt5-5.15.9-cp37-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:dd5ce10e79fbf1df29507d2daf99270f2057cdd25e4de6fbf2052b46c652e3a5"}, + {file = "PyQt5-5.15.9-cp37-abi3-win32.whl", hash = "sha256:e45c5cc15d4fd26ab5cb0e5cdba60691a3e9086411f8e3662db07a5a4222a696"}, + {file = "PyQt5-5.15.9-cp37-abi3-win_amd64.whl", hash = "sha256:e030d795df4cbbfcf4f38b18e2e119bcc9e177ef658a5094b87bb16cac0ce4c5"}, + {file = "PyQt5-5.15.9.tar.gz", hash = "sha256:dc41e8401a90dc3e2b692b411bd5492ab559ae27a27424eed4bd3915564ec4c0"}, ] +[package.dependencies] +PyQt5-Qt5 = ">=5.15.2" +PyQt5-sip = ">=12.11,<13" + [[package]] -name = "pyreadline3" -version = "3.4.1" -description = "A python implementation of GNU readline." +name = "pyqt5-qt5" +version = "5.15.2" +description = "The subset of a Qt installation needed by PyQt5." optional = false python-versions = "*" files = [ - {file = "pyreadline3-3.4.1-py3-none-any.whl", hash = "sha256:b0efb6516fd4fb07b45949053826a62fa4cb353db5be2bbb4a7aa1fdd1e345fb"}, - {file = "pyreadline3-3.4.1.tar.gz", hash = "sha256:6f3d1f7b8a31ba32b73917cefc1f28cc660562f39aea8646d30bd6eff21f7bae"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-macosx_10_13_intel.whl", hash = "sha256:76980cd3d7ae87e3c7a33bfebfaee84448fd650bad6840471d6cae199b56e154"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:1988f364ec8caf87a6ee5d5a3a5210d57539988bf8e84714c7d60972692e2f4a"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-win32.whl", hash = "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962"}, +] + +[[package]] +name = "pyqt5-sip" +version = "12.12.2" +description = "The sip module support for PyQt5" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyQt5_sip-12.12.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1cc49c8498c34649325d53bcd243c854391f828d9bab4f2f3afd3ee3451cab72"}, + {file = "PyQt5_sip-12.12.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c8f6e7a697d0ddf754798988fae7b2a0da04f6a59fb13ae863e5d1da4b280c4f"}, + {file = "PyQt5_sip-12.12.2-cp310-cp310-win32.whl", hash = "sha256:7e572c8104e75db2c69609d195daf44c7b965dcb1c5b48e30fc376868909be56"}, + {file = "PyQt5_sip-12.12.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a65697aa0fdb66e20d7b1ef8adfacc1caf1e61655530920172bf3a2fb1148cd"}, + {file = "PyQt5_sip-12.12.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:761e018dbbc46daccdb01f8f0dcc0d055c76834d839f0343cbec4b0ecbbde512"}, + {file = "PyQt5_sip-12.12.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9d2b127ba5155bff452944b8a96ba06d7ec2161f48a2f9cc190425bfca94ab6b"}, + {file = "PyQt5_sip-12.12.2-cp311-cp311-win32.whl", hash = "sha256:26e75bc4ffd8e6b19ae96fe93dc135eb5aea03e4570724d4b3c40dbf36f3a2e6"}, + {file = "PyQt5_sip-12.12.2-cp311-cp311-win_amd64.whl", hash = "sha256:d9548f353f17407d00f67d08c737de9f5c067352c3bdac8571492c614c2893eb"}, + {file = "PyQt5_sip-12.12.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7e640b7636d86271ba8969b260e1655068b44750f20801ebc80f49a1aa737bf9"}, + {file = "PyQt5_sip-12.12.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e46d957fbeecaa1437f2dd715407b1e59e0918cc29382c7ea79784c5f3cbe0d2"}, + {file = "PyQt5_sip-12.12.2-cp37-cp37m-win32.whl", hash = "sha256:cb4523097f1ccabb95b3197a58278a40fc944b33791d3406bfa397e12303b6c6"}, + {file = "PyQt5_sip-12.12.2-cp37-cp37m-win_amd64.whl", hash = "sha256:ed04bd0065d870912c1b0a4b34b8a78698c76d77f15474c3e841b0b6dd2f429f"}, + {file = "PyQt5_sip-12.12.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:71795c177010e52109812b03ec919020461ec42a7d9d241a45fe6d708529b5a6"}, + {file = "PyQt5_sip-12.12.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:de06b6bd8241a189f729b8c093ce5dcf5928489eb7748bda28e28324e57544b0"}, + {file = "PyQt5_sip-12.12.2-cp38-cp38-win32.whl", hash = "sha256:7050ad8f94370eb7e4caa022b7e6d8b2de615e0714b557ca2098c82c0132074a"}, + {file = "PyQt5_sip-12.12.2-cp38-cp38-win_amd64.whl", hash = "sha256:67eed70427d3291e5c52c349fb4619c57c9a8810ab8d78a142c00edcbfd20d3b"}, + {file = "PyQt5_sip-12.12.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cf74db9a1542f66793ccc00e403c8c2c36c67c0cff0fb01d23fe71cc1c56c788"}, + {file = "PyQt5_sip-12.12.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:23e983119f760dc6c1a1e6cb21fd4c268d14c4ee497de6da9ce2b9d46f9779b2"}, + {file = "PyQt5_sip-12.12.2-cp39-cp39-win32.whl", hash = "sha256:a88ce85176639723f04cf5ce59157ecf3a9faca5d5dd1fe82d5ef46a3bd1d102"}, + {file = "PyQt5_sip-12.12.2-cp39-cp39-win_amd64.whl", hash = "sha256:7f13e71f5171f30d8b4176c081f0203a43e1704746b4cdaa837477945177b2a0"}, + {file = "PyQt5_sip-12.12.2.tar.gz", hash = "sha256:10d9bfa9f59f0fd1cad81be187479316ffc95684f573efea94512cb4257d2b17"}, ] [[package]] @@ -7068,18 +3085,6 @@ files = [ [package.extras] cp2110 = ["hidapi"] -[[package]] -name = "pysocks" -version = "1.7.1" -description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, - {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, - {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, -] - [[package]] name = "pytest" version = "7.4.0" @@ -7134,127 +3139,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "python-engineio" -version = "4.5.1" -description = "Engine.IO server and client for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-engineio-4.5.1.tar.gz", hash = "sha256:b167a1b208fcdce5dbe96a61a6ca22391cfa6715d796c22de93e3adf9c07ae0c"}, - {file = "python_engineio-4.5.1-py3-none-any.whl", hash = "sha256:67a675569f3e9bb274a8077f3c2068a8fe79cbfcb111cf31ca27b968484fe6c7"}, -] - -[package.extras] -asyncio-client = ["aiohttp (>=3.4)"] -client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] -docs = ["sphinx"] - -[[package]] -name = "python-json-logger" -version = "2.0.7" -description = "A python library adding a json log formatter" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, - {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, -] - -[[package]] -name = "python-logstash" -version = "0.4.8" -description = "Python logging handler for Logstash." -optional = false -python-versions = "*" -files = [ - {file = "python-logstash-0.4.8.tar.gz", hash = "sha256:d04e1ce11ecc107e4a4f3b807fc57d96811e964a554081b3bbb44732f74ef5f9"}, -] - -[[package]] -name = "python-rapidjson" -version = "1.10" -description = "Python wrapper around rapidjson" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-rapidjson-1.10.tar.gz", hash = "sha256:acfecbf5edb91ec72a20a125de7f56b8c2f6161eff4c65382c8ee6a2484d3540"}, - {file = "python_rapidjson-1.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1db7b0af882999f5685eb7046a0f3b3aca5d55a3e84b3089747d29a4ec6fdade"}, - {file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87c8c8b615513f9dc414af1554140589036d14840f5e1f1845965e1c0a080e1"}, - {file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0a2f5c4abe529ca2764343416e35710a263832533b7bdc76c3285efb5b5ecc8"}, - {file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40467c3a6d8f070cc4d196fe46a79ed59d1a13a4d3fdc6a0325a21816600e5a7"}, - {file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df4e7237a3e77666ccb9b437013294e6aa3968528f7c61f60f6f38eea0f8f79"}, - {file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:99a5215f24ff1fa6cc67ee275a6852aa56d934d3b8cd7a40197feb632b54fd76"}, - {file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3dbea0ee9fa1cd6ecc13a949f6bb94013639d39cdb56f58df4ab61130d35e57c"}, - {file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:6d1d0c5da3bd5f701b1aed550e1e7bd59b16ae642877cddf18815006cf998f9a"}, - {file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:072f76c1f1483bcc4056d7d3a8b0319bf841a73e955f188302094b62b2163bf9"}, - {file = "python_rapidjson-1.10-cp310-cp310-win32.whl", hash = "sha256:c95d466307a2140a7687a575103980c6e81c9f62d19556cafad3d6b2932b7eb1"}, - {file = "python_rapidjson-1.10-cp310-cp310-win_amd64.whl", hash = "sha256:454ffda58cc6fed64d983b1b8ae4b39a563b4fd671dae9132e06450025898539"}, - {file = "python_rapidjson-1.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fff343076fbeee0cd7e4e3fb9472f2d567a127ec7b8b5b7ecba6bf7960a3ce07"}, - {file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:686482c67727edad4b6d0c753bc159f35134a5a623e9651c4b7c008ef2996252"}, - {file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ef7d55688b7123d62690b193537cc048fa9f35cfa43d249fedc0d9fd398890a"}, - {file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f27c0601792533ab6e98452961d61566480dc155da19d2a358a5fd9a85d9321"}, - {file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95176e35e3bacb8a1a27f563e815b5b57c717992c871b1c25fd76a835fbba32c"}, - {file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47a0ec20886b8be86af307c10d699a447e22979ed7dd1f2b7ed5cb7496b3d920"}, - {file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f7968c0cb09d9a76aa2483556ba46ab42634baf216cb2f2c7cd6bf77119a33c1"}, - {file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5faab270a4dd49216ceaca7169682680b2f5df8311c1ed259e4612d9d0cf61b7"}, - {file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81b797934dc037810f5f98af138b55a3b6f18dd569cc5e8f81fe79956a4717ca"}, - {file = "python_rapidjson-1.10-cp311-cp311-win32.whl", hash = "sha256:6c1d62cc58a61629fc5e216fb7b3a1b02787c98fded874a7b474b1e6325e377e"}, - {file = "python_rapidjson-1.10-cp311-cp311-win_amd64.whl", hash = "sha256:29d31fc4254f1a4dca420e58bd1331e990fc2959d09ff2daa7934d52732a8491"}, - {file = "python_rapidjson-1.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:718f4e217b511cfbf9166f55ccf4bf4e4538495bee403e390cf89791c0debc26"}, - {file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541bbb96353cf3fe2bdb29e727087226532be4e4573daad6f042cfdea533a564"}, - {file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50f0402a6899c6a177d4a37152deefcd59c61e44bef56b71e8d006a186c86286"}, - {file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c035e17744d6d6fba073b550b0040a74e55f2ad33fd798df206ff6879b41ad10"}, - {file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da970bde42309a74a5556e696673ea11c4545b8bee5081b84265ded460b2e9ef"}, - {file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7437a649821008aa456f2fbec737880d7f9bdda7ec94cc1743a43ccf32b5d26"}, - {file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:362d969bbd277f78bf0b1ffaa810857ea40351146b827f896f8d49e9c25fc99c"}, - {file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:409256e7748c4ab7f17b3793c7a78ca01914c487644fc42140d116ed4dec8c4f"}, - {file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a34a7e2853456fe50ba2ee22e38e7841e55eee10021d4496cce62285f148e8e7"}, - {file = "python_rapidjson-1.10-cp37-cp37m-win32.whl", hash = "sha256:bc4a97940e5afa60a598483d0eb863b26e4810aaf030d92a4301f5fc183e1b6d"}, - {file = "python_rapidjson-1.10-cp37-cp37m-win_amd64.whl", hash = "sha256:89586b67f9c69b66885774acebf3d018e7b8f93cea2b3cffa306ec9d37877594"}, - {file = "python_rapidjson-1.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e38082b1a8ce3e2bd55821852c0cd643cdabe6497fd9c054f6b47a099afbea0"}, - {file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0955ef22fabb36b26fcad702ae54c1bce2bc2a74b1883c42d251d72011d0d426"}, - {file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a9db03c68ab0158bcdf80299b2c980186d148aa3e05d5650fea5148a425a29a"}, - {file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fde8ab0f06debaa06d93085f19dc3ec3db53f22883f1625dd32b96a87e7009de"}, - {file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23539c9f7d85d64a00d3cb44c7d9ab3be2184d4da42a5f3263dcfd1d0203ee43"}, - {file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8bfd484285f3477acef0bb45abd2b80b6252e35a5a53395ce48f0327cbe43c23"}, - {file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8b0ed643ebaa8ddf3f40422752efe83abda29aa30a9e6866ccd9dd591b5057d0"}, - {file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:5aeca661a0f229f1312fb3ad3e1a5c6736d49942d80d4931810158559eb8f119"}, - {file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8a68ed066e8f0878b7112f943cf35ba9e5217395bcdd8cb478cde01871e2701c"}, - {file = "python_rapidjson-1.10-cp38-cp38-win32.whl", hash = "sha256:d286be6f63446776c4958bb37824c683194b4878fc9cd5b7255134fb5a6ba536"}, - {file = "python_rapidjson-1.10-cp38-cp38-win_amd64.whl", hash = "sha256:aece5270c6e6d5c3d54586c9a5fb9677d70d7019744a59560c5c369c7b9bba25"}, - {file = "python_rapidjson-1.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc09c5ad0fe71f262cdcc5655409f132f1560a8af80e76e7757945ce401fdbab"}, - {file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f6447bd7a8ff5135ab7e372b48a174d3c560d5b322e32bd465e8458e6e4593"}, - {file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22ede69213885391b46cc14596bfd4cd1a5c6f34a2db6600fb08b03982dbc7b7"}, - {file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a9425129623718a04b885a12190faa23e7997c4e8632054e18df7ea473f746d"}, - {file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e10f32e1a8d155448842934cbe71eb620b4b4a0cb3627ba4c4856e27556534"}, - {file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d23caab17b87ed5b82e28cdc19172ba1ca65c982e3fff387961d3f33710031f"}, - {file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f07d4fcdcfd64bdad0143b9705c5d5089677ebddf60ac6c1f8074a34b1c70cf9"}, - {file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:87b991c7ae435489c56a46cef228d2b65a3df689ee4fe24fab69c791c841f633"}, - {file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3706a5c4f21073c04be133c36565efc6e3f5646a03c8d19af78c19d7c70eb708"}, - {file = "python_rapidjson-1.10-cp39-cp39-win32.whl", hash = "sha256:47f9078ea6884f700166a8728d863609fec62232e66a33b8fb4a7706ce7c731c"}, - {file = "python_rapidjson-1.10-cp39-cp39-win_amd64.whl", hash = "sha256:9e4921ab7002ae9faad7f439a7c50aa195039f177e9e51a76c34c97966c79a79"}, -] - -[[package]] -name = "python-socketio" -version = "5.8.0" -description = "Socket.IO server and client for Python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-socketio-5.8.0.tar.gz", hash = "sha256:e714f4dddfaaa0cb0e37a1e2deef2bb60590a5b9fea9c343dd8ca5e688416fd9"}, - {file = "python_socketio-5.8.0-py3-none-any.whl", hash = "sha256:7adb8867aac1c2929b9c1429f1c02e12ca4c36b67c807967393e367dfbb01441"}, -] - -[package.dependencies] -bidict = ">=0.21.0" -python-engineio = ">=4.3.0" - -[package.extras] -asyncio-client = ["aiohttp (>=3.4)"] -client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] - [[package]] name = "pytools" version = "2023.1.1" @@ -7283,91 +3167,6 @@ files = [ {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] -[[package]] -name = "pywavelets" -version = "1.4.1" -description = "PyWavelets, wavelet transform module" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyWavelets-1.4.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:d854411eb5ee9cb4bc5d0e66e3634aeb8f594210f6a1bed96dbed57ec70f181c"}, - {file = "PyWavelets-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:231b0e0b1cdc1112f4af3c24eea7bf181c418d37922a67670e9bf6cfa2d544d4"}, - {file = "PyWavelets-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:754fa5085768227c4f4a26c1e0c78bc509a266d9ebd0eb69a278be7e3ece943c"}, - {file = "PyWavelets-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da7b9c006171be1f9ddb12cc6e0d3d703b95f7f43cb5e2c6f5f15d3233fcf202"}, - {file = "PyWavelets-1.4.1-cp310-cp310-win32.whl", hash = "sha256:67a0d28a08909f21400cb09ff62ba94c064882ffd9e3a6b27880a111211d59bd"}, - {file = "PyWavelets-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:91d3d393cffa634f0e550d88c0e3f217c96cfb9e32781f2960876f1808d9b45b"}, - {file = "PyWavelets-1.4.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:64c6bac6204327321db30b775060fbe8e8642316e6bff17f06b9f34936f88875"}, - {file = "PyWavelets-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f19327f2129fb7977bc59b966b4974dfd72879c093e44a7287500a7032695de"}, - {file = "PyWavelets-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad987748f60418d5f4138db89d82ba0cb49b086e0cbb8fd5c3ed4a814cfb705e"}, - {file = "PyWavelets-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:875d4d620eee655346e3589a16a73790cf9f8917abba062234439b594e706784"}, - {file = "PyWavelets-1.4.1-cp311-cp311-win32.whl", hash = "sha256:7231461d7a8eb3bdc7aa2d97d9f67ea5a9f8902522818e7e2ead9c2b3408eeb1"}, - {file = "PyWavelets-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:daf0aa79842b571308d7c31a9c43bc99a30b6328e6aea3f50388cd8f69ba7dbc"}, - {file = "PyWavelets-1.4.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:ab7da0a17822cd2f6545626946d3b82d1a8e106afc4b50e3387719ba01c7b966"}, - {file = "PyWavelets-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:578af438a02a86b70f1975b546f68aaaf38f28fb082a61ceb799816049ed18aa"}, - {file = "PyWavelets-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb5ca8d11d3f98e89e65796a2125be98424d22e5ada360a0dbabff659fca0fc"}, - {file = "PyWavelets-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:058b46434eac4c04dd89aeef6fa39e4b6496a951d78c500b6641fd5b2cc2f9f4"}, - {file = "PyWavelets-1.4.1-cp38-cp38-win32.whl", hash = "sha256:de7cd61a88a982edfec01ea755b0740e94766e00a1ceceeafef3ed4c85c605cd"}, - {file = "PyWavelets-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:7ab8d9db0fe549ab2ee0bea61f614e658dd2df419d5b75fba47baa761e95f8f2"}, - {file = "PyWavelets-1.4.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:23bafd60350b2b868076d976bdd92f950b3944f119b4754b1d7ff22b7acbf6c6"}, - {file = "PyWavelets-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d0e56cd7a53aed3cceca91a04d62feb3a0aca6725b1912d29546c26f6ea90426"}, - {file = "PyWavelets-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030670a213ee8fefa56f6387b0c8e7d970c7f7ad6850dc048bd7c89364771b9b"}, - {file = "PyWavelets-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71ab30f51ee4470741bb55fc6b197b4a2b612232e30f6ac069106f0156342356"}, - {file = "PyWavelets-1.4.1-cp39-cp39-win32.whl", hash = "sha256:47cac4fa25bed76a45bc781a293c26ac63e8eaae9eb8f9be961758d22b58649c"}, - {file = "PyWavelets-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:88aa5449e109d8f5e7f0adef85f7f73b1ab086102865be64421a3a3d02d277f4"}, - {file = "PyWavelets-1.4.1.tar.gz", hash = "sha256:6437af3ddf083118c26d8f97ab43b0724b956c9f958e9ea788659f6a2834ba93"}, -] - -[package.dependencies] -numpy = ">=1.17.3" - -[[package]] -name = "pywin32" -version = "306" -description = "Python for Window Extensions" -optional = false -python-versions = "*" -files = [ - {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, - {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, - {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, - {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, - {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, - {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, - {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, - {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, - {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, - {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, - {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, - {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, - {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, - {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, -] - -[[package]] -name = "pywin32-ctypes" -version = "0.2.2" -description = "A (partial) reimplementation of pywin32 using ctypes/cffi" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"}, - {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"}, -] - -[[package]] -name = "pywinpty" -version = "2.0.11" -description = "Pseudo terminal support for Windows from Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pywinpty-2.0.11-cp310-none-win_amd64.whl", hash = "sha256:452f10ac9ff8ab9151aa8cea9e491a9612a12250b1899278c6a56bc184afb47f"}, - {file = "pywinpty-2.0.11-cp311-none-win_amd64.whl", hash = "sha256:6701867d42aec1239bc0fedf49a336570eb60eb886e81763db77ea2b6c533cc3"}, - {file = "pywinpty-2.0.11-cp38-none-win_amd64.whl", hash = "sha256:0ffd287751ad871141dc9724de70ea21f7fc2ff1af50861e0d232cf70739d8c4"}, - {file = "pywinpty-2.0.11-cp39-none-win_amd64.whl", hash = "sha256:e4e7f023c28ca7aa8e1313e53ba80a4d10171fe27857b7e02f99882dfe3e8638"}, - {file = "pywinpty-2.0.11.tar.gz", hash = "sha256:e244cffe29a894876e2cd251306efd0d8d64abd5ada0a46150a4a71c0b9ad5c5"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -7522,314 +3321,6 @@ files = [ [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} -[[package]] -name = "qtconsole" -version = "5.4.3" -description = "Jupyter Qt console" -optional = false -python-versions = ">= 3.7" -files = [ - {file = "qtconsole-5.4.3-py3-none-any.whl", hash = "sha256:35fd6e87b1f6d1fd41801b07e69339f8982e76afd4fa8ef35595bc6036717189"}, - {file = "qtconsole-5.4.3.tar.gz", hash = "sha256:5e4082a86a201796b2a5cfd4298352d22b158b51b57736531824715fc2a979dd"}, -] - -[package.dependencies] -ipykernel = ">=4.1" -ipython-genutils = "*" -jupyter-client = ">=4.1" -jupyter-core = "*" -packaging = "*" -pygments = "*" -pyzmq = ">=17.1" -qtpy = ">=2.0.1" -traitlets = "<5.2.1 || >5.2.1,<5.2.2 || >5.2.2" - -[package.extras] -doc = ["Sphinx (>=1.3)"] -test = ["flaky", "pytest", "pytest-qt"] - -[[package]] -name = "qtpy" -version = "2.3.1" -description = "Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6)." -optional = false -python-versions = ">=3.7" -files = [ - {file = "QtPy-2.3.1-py3-none-any.whl", hash = "sha256:5193d20e0b16e4d9d3bc2c642d04d9f4e2c892590bd1b9c92bfe38a95d5a2e12"}, - {file = "QtPy-2.3.1.tar.gz", hash = "sha256:a8c74982d6d172ce124d80cafd39653df78989683f760f2281ba91a6e7b9de8b"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -test = ["pytest (>=6,!=7.0.0,!=7.0.1)", "pytest-cov (>=3.0.0)", "pytest-qt"] - -[[package]] -name = "qudida" -version = "0.0.4" -description = "QUick and DIrty Domain Adaptation" -optional = false -python-versions = ">=3.5.0" -files = [ - {file = "qudida-0.0.4-py3-none-any.whl", hash = "sha256:4519714c40cd0f2e6c51e1735edae8f8b19f4efe1f33be13e9d644ca5f736dd6"}, - {file = "qudida-0.0.4.tar.gz", hash = "sha256:db198e2887ab0c9aa0023e565afbff41dfb76b361f85fd5e13f780d75ba18cc8"}, -] - -[package.dependencies] -numpy = ">=0.18.0" -opencv-python-headless = ">=4.0.1" -scikit-learn = ">=0.19.1" -typing-extensions = "*" - -[[package]] -name = "rapidfuzz" -version = "2.15.1" -description = "rapid fuzzy string matching" -optional = false -python-versions = ">=3.7" -files = [ - {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fc0bc259ebe3b93e7ce9df50b3d00e7345335d35acbd735163b7c4b1957074d3"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d59fb3a410d253f50099d7063855c2b95df1ef20ad93ea3a6b84115590899f25"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c525a3da17b6d79d61613096c8683da86e3573e807dfaecf422eea09e82b5ba6"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4deae6a918ecc260d0c4612257be8ba321d8e913ccb43155403842758c46fbe"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2577463d10811386e704a3ab58b903eb4e2a31b24dfd9886d789b0084d614b01"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f67d5f56aa48c0da9de4ab81bffb310683cf7815f05ea38e5aa64f3ba4368339"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7927722ff43690e52b3145b5bd3089151d841d350c6f8378c3cfac91f67573a"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6534afc787e32c4104f65cdeb55f6abe4d803a2d0553221d00ef9ce12788dcde"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d0ae6ec79a1931929bb9dd57bc173eb5ba4c7197461bf69e3a34b6dd314feed2"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be7ccc45c4d1a7dfb595f260e8022a90c6cb380c2a346ee5aae93f85c96d362b"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:8ba013500a2b68c64b2aecc5fb56a2dad6c2872cf545a0308fd044827b6e5f6a"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4d9f7d10065f657f960b48699e7dddfce14ab91af4bab37a215f0722daf0d716"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7e24a1b802cea04160b3fccd75d2d0905065783ebc9de157d83c14fb9e1c6ce2"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-win32.whl", hash = "sha256:dffdf03499e0a5b3442951bb82b556333b069e0661e80568752786c79c5b32de"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d150d90a7c6caae7962f29f857a4e61d42038cfd82c9df38508daf30c648ae7"}, - {file = "rapidfuzz-2.15.1-cp310-cp310-win_arm64.whl", hash = "sha256:87c30e9184998ff6eb0fa9221f94282ce7c908fd0da96a1ef66ecadfaaa4cdb7"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6986413cb37035eb796e32f049cbc8c13d8630a4ac1e0484e3e268bb3662bd1b"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a72f26e010d4774b676f36e43c0fc8a2c26659efef4b3be3fd7714d3491e9957"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b5cd54c98a387cca111b3b784fc97a4f141244bbc28a92d4bde53f164464112e"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7fac7c3da39f93e6b2ebe386ed0ffe1cefec91509b91857f6e1204509e931f"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f976e76ac72f650790b3a5402431612175b2ac0363179446285cb3c901136ca9"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abde47e1595902a490ed14d4338d21c3509156abb2042a99e6da51f928e0c117"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca8f1747007a3ce919739a60fa95c5325f7667cccf6f1c1ef18ae799af119f5e"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c35da09ab9797b020d0d4f07a66871dfc70ea6566363811090353ea971748b5a"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a3a769ca7580686a66046b77df33851b3c2d796dc1eb60c269b68f690f3e1b65"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d50622efefdb03a640a51a6123748cd151d305c1f0431af762e833d6ffef71f0"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b7461b0a7651d68bc23f0896bffceea40f62887e5ab8397bf7caa883592ef5cb"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:074ee9e17912e025c72a5780ee4c7c413ea35cd26449719cc399b852d4e42533"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7025fb105a11f503943f17718cdb8241ea3bb4d812c710c609e69bead40e2ff0"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-win32.whl", hash = "sha256:2084d36b95139413cef25e9487257a1cc892b93bd1481acd2a9656f7a1d9930c"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:5a738fcd24e34bce4b19126b92fdae15482d6d3a90bd687fd3d24ce9d28ce82d"}, - {file = "rapidfuzz-2.15.1-cp311-cp311-win_arm64.whl", hash = "sha256:dc3cafa68cfa54638632bdcadf9aab89a3d182b4a3f04d2cad7585ed58ea8731"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c53d57ba7a88f7bf304d4ea5a14a0ca112db0e0178fff745d9005acf2879f7d"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6ee758eec4cf2215dc8d8eafafcea0d1f48ad4b0135767db1b0f7c5c40a17dd"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d93ba3ae59275e7a3a116dac4ffdb05e9598bf3ee0861fecc5b60fb042d539e"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c3ff75e647908ddbe9aa917fbe39a112d5631171f3fcea5809e2363e525a59d"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d89c421702474c6361245b6b199e6e9783febacdbfb6b002669e6cb3ef17a09"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f69e6199fec0f58f9a89afbbaea78d637c7ce77f656a03a1d6ea6abdc1d44f8"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:41dfea282844d0628279b4db2929da0dacb8ac317ddc5dcccc30093cf16357c1"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2dd03477feefeccda07b7659dd614f6738cfc4f9b6779dd61b262a73b0a9a178"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:5efe035aa76ff37d1b5fa661de3c4b4944de9ff227a6c0b2e390a95c101814c0"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:ed2cf7c69102c7a0a06926d747ed855bc836f52e8d59a5d1e3adfd980d1bd165"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a0e441d4c2025110ec3eba5d54f11f78183269a10152b3a757a739ffd1bb12bf"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-win32.whl", hash = "sha256:a4a54efe17cc9f53589c748b53f28776dfdfb9bc83619685740cb7c37985ac2f"}, - {file = "rapidfuzz-2.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:bb8318116ecac4dfb84841d8b9b461f9bb0c3be5b616418387d104f72d2a16d1"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e9296c530e544f68858c3416ad1d982a1854f71e9d2d3dcedb5b216e6d54f067"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:49c4bcdb9238f11f8c4eba1b898937f09b92280d6f900023a8216008f299b41a"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb40a279e134bb3fef099a8b58ed5beefb201033d29bdac005bddcdb004ef71"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7381c11cb590bbd4e6f2d8779a0b34fdd2234dfa13d0211f6aee8ca166d9d05"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfdcdedfd12a0077193f2cf3626ff6722c5a184adf0d2d51f1ec984bf21c23c3"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f85bece1ec59bda8b982bd719507d468d4df746dfb1988df11d916b5e9fe19e8"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1b393f4a1eaa6867ffac6aef58cfb04bab2b3d7d8e40b9fe2cf40dd1d384601"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53de456ef020a77bf9d7c6c54860a48e2e902584d55d3001766140ac45c54bc7"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2492330bc38b76ed967eab7bdaea63a89b6ceb254489e2c65c3824efcbf72993"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:099e4c6befaa8957a816bdb67ce664871f10aaec9bebf2f61368cf7e0869a7a1"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:46599b2ad4045dd3f794a24a6db1e753d23304699d4984462cf1ead02a51ddf3"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:591f19d16758a3c55c9d7a0b786b40d95599a5b244d6eaef79c7a74fcf5104d8"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed17359061840eb249f8d833cb213942e8299ffc4f67251a6ed61833a9f2ea20"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-win32.whl", hash = "sha256:aa1e5aad325168e29bf8e17006479b97024aa9d2fdbe12062bd2f8f09080acf8"}, - {file = "rapidfuzz-2.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:c2bb68832b140c551dbed691290bef4ee6719d4e8ce1b7226a3736f61a9d1a83"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3fac40972cf7b6c14dded88ae2331eb50dfbc278aa9195473ef6fc6bfe49f686"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0e456cbdc0abf39352800309dab82fd3251179fa0ff6573fa117f51f4e84be8"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:22b9d22022b9d09fd4ece15102270ab9b6a5cfea8b6f6d1965c1df7e3783f5ff"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46754fe404a9a6f5cbf7abe02d74af390038d94c9b8c923b3f362467606bfa28"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91abb8bf7610efe326394adc1d45e1baca8f360e74187f3fa0ef3df80cdd3ba6"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e40a2f60024f9d3c15401e668f732800114a023f3f8d8c40f1521a62081ff054"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a48ee83916401ac73938526d7bd804e01d2a8fe61809df7f1577b0b3b31049a3"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c71580052f9dbac443c02f60484e5a2e5f72ad4351b84b2009fbe345b1f38422"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:82b86d5b8c1b9bcbc65236d75f81023c78d06a721c3e0229889ff4ed5c858169"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fc4528b7736e5c30bc954022c2cf410889abc19504a023abadbc59cdf9f37cae"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e1e0e569108a5760d8f01d0f2148dd08cc9a39ead79fbefefca9e7c7723c7e88"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94e1c97f0ad45b05003806f8a13efc1fc78983e52fa2ddb00629003acf4676ef"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47e81767a962e41477a85ad7ac937e34d19a7d2a80be65614f008a5ead671c56"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-win32.whl", hash = "sha256:79fc574aaf2d7c27ec1022e29c9c18f83cdaf790c71c05779528901e0caad89b"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:f3dd4bcef2d600e0aa121e19e6e62f6f06f22a89f82ef62755e205ce14727874"}, - {file = "rapidfuzz-2.15.1-cp39-cp39-win_arm64.whl", hash = "sha256:cac095cbdf44bc286339a77214bbca6d4d228c9ebae3da5ff6a80aaeb7c35634"}, - {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b89d1126be65c85763d56e3b47d75f1a9b7c5529857b4d572079b9a636eaa8a7"}, - {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7460e91168229768be882ea365ba0ac7da43e57f9416e2cfadc396a7df3c2"}, - {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c33c03e7092642c38f8a15ca2d8fc38da366f2526ec3b46adf19d5c7aa48ba"}, - {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:040faca2e26d9dab5541b45ce72b3f6c0e36786234703fc2ac8c6f53bb576743"}, - {file = "rapidfuzz-2.15.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6e2a3b23e1e9aa13474b3c710bba770d0dcc34d517d3dd6f97435a32873e3f28"}, - {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e597b9dfd6dd180982684840975c458c50d447e46928efe3e0120e4ec6f6686"}, - {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d14752c9dd2036c5f36ebe8db5f027275fa7d6b3ec6484158f83efb674bab84e"}, - {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558224b6fc6124d13fa32d57876f626a7d6188ba2a97cbaea33a6ee38a867e31"}, - {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c89cfa88dc16fd8c9bcc0c7f0b0073f7ef1e27cceb246c9f5a3f7004fa97c4d"}, - {file = "rapidfuzz-2.15.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:509c5b631cd64df69f0f011893983eb15b8be087a55bad72f3d616b6ae6a0f96"}, - {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0f73a04135a03a6e40393ecd5d46a7a1049d353fc5c24b82849830d09817991f"}, - {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c99d53138a2dfe8ada67cb2855719f934af2733d726fbf73247844ce4dd6dd5"}, - {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f01fa757f0fb332a1f045168d29b0d005de6c39ee5ce5d6c51f2563bb53c601b"}, - {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60368e1add6e550faae65614844c43f8a96e37bf99404643b648bf2dba92c0fb"}, - {file = "rapidfuzz-2.15.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:785744f1270828cc632c5a3660409dee9bcaac6931a081bae57542c93e4d46c4"}, - {file = "rapidfuzz-2.15.1.tar.gz", hash = "sha256:d62137c2ca37aea90a11003ad7dc109c8f1739bfbe5a9a217f3cdb07d7ac00f6"}, -] - -[package.extras] -full = ["numpy"] - -[[package]] -name = "reactivex" -version = "4.0.4" -description = "ReactiveX (Rx) for Python" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "reactivex-4.0.4-py3-none-any.whl", hash = "sha256:0004796c420bd9e68aad8e65627d85a8e13f293de76656165dffbcb3a0e3fb6a"}, - {file = "reactivex-4.0.4.tar.gz", hash = "sha256:e912e6591022ab9176df8348a653fe8c8fa7a301f26f9931c9d8c78a650e04e8"}, -] - -[package.dependencies] -typing-extensions = ">=4.1.1,<5.0.0" - -[[package]] -name = "redis" -version = "4.6.0" -description = "Python client for Redis database and key-value store" -optional = false -python-versions = ">=3.7" -files = [ - {file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"}, - {file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"}, -] - -[package.dependencies] -async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} - -[package.extras] -hiredis = ["hiredis (>=1.0.0)"] -ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] - -[[package]] -name = "referencing" -version = "0.30.2" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - -[[package]] -name = "regex" -version = "2023.8.8" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.6" -files = [ - {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, - {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, - {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, - {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, - {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, - {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, - {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, - {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, - {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, - {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, - {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, - {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, - {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, - {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, - {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, - {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, - {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, -] - [[package]] name = "requests" version = "2.31.0" @@ -7845,480 +3336,47 @@ files = [ certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -PySocks = {version = ">=1.5.6,<1.5.7 || >1.5.7", optional = true, markers = "extra == \"socks\""} urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-oauthlib" -version = "1.3.1" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, - {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, -] - -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "reverse-geocoder" -version = "1.5.1" -description = "Fast, offline reverse geocoder" -optional = false -python-versions = "*" -files = [ - {file = "reverse_geocoder-1.5.1.tar.gz", hash = "sha256:2a2e781b5f69376d922b78fe8978f1350c84fce0ddb07e02c834ecf98b57c75c"}, -] - -[package.dependencies] -numpy = ">=1.11.0" -scipy = ">=0.17.1" - -[[package]] -name = "rfc3339-validator" -version = "0.1.4" -description = "A pure python RFC3339 validator" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, - {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, -] - -[package.dependencies] -six = "*" - -[[package]] -name = "rfc3986-validator" -version = "0.1.1" -description = "Pure python rfc3986 validator" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, - {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, -] - -[[package]] -name = "rpds-py" -version = "0.9.2" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, - {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29cd8bfb2d716366a035913ced99188a79b623a3512292963d84d3e06e63b496"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44659b1f326214950a8204a248ca6199535e73a694be8d3e0e869f820767f12f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:745f5a43fdd7d6d25a53ab1a99979e7f8ea419dfefebcab0a5a1e9095490ee5e"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a987578ac5214f18b99d1f2a3851cba5b09f4a689818a106c23dbad0dfeb760f"}, - {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf4151acb541b6e895354f6ff9ac06995ad9e4175cbc6d30aaed08856558201f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03421628f0dc10a4119d714a17f646e2837126a25ac7a256bdf7c3943400f67f"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13b602dc3e8dff3063734f02dcf05111e887f301fdda74151a93dbbc249930fe"}, - {file = "rpds_py-0.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fae5cb554b604b3f9e2c608241b5d8d303e410d7dfb6d397c335f983495ce7f6"}, - {file = "rpds_py-0.9.2-cp310-none-win32.whl", hash = "sha256:47c5f58a8e0c2c920cc7783113df2fc4ff12bf3a411d985012f145e9242a2764"}, - {file = "rpds_py-0.9.2-cp310-none-win_amd64.whl", hash = "sha256:4ea6b73c22d8182dff91155af018b11aac9ff7eca085750455c5990cb1cfae6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e564d2238512c5ef5e9d79338ab77f1cbbda6c2d541ad41b2af445fb200385e3"}, - {file = "rpds_py-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f411330a6376fb50e5b7a3e66894e4a39e60ca2e17dce258d53768fea06a37bd"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e7521f5af0233e89939ad626b15278c71b69dc1dfccaa7b97bd4cdf96536bb7"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3335c03100a073883857e91db9f2e0ef8a1cf42dc0369cbb9151c149dbbc1b"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d25b1c1096ef0447355f7293fbe9ad740f7c47ae032c2884113f8e87660d8f6e"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a5d3fbd02efd9cf6a8ffc2f17b53a33542f6b154e88dd7b42ef4a4c0700fdad"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5934e2833afeaf36bd1eadb57256239785f5af0220ed8d21c2896ec4d3a765f"}, - {file = "rpds_py-0.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:095b460e117685867d45548fbd8598a8d9999227e9061ee7f012d9d264e6048d"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91378d9f4151adc223d584489591dbb79f78814c0734a7c3bfa9c9e09978121c"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:24a81c177379300220e907e9b864107614b144f6c2a15ed5c3450e19cf536fae"}, - {file = "rpds_py-0.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:de0b6eceb46141984671802d412568d22c6bacc9b230174f9e55fc72ef4f57de"}, - {file = "rpds_py-0.9.2-cp311-none-win32.whl", hash = "sha256:700375326ed641f3d9d32060a91513ad668bcb7e2cffb18415c399acb25de2ab"}, - {file = "rpds_py-0.9.2-cp311-none-win_amd64.whl", hash = "sha256:0766babfcf941db8607bdaf82569ec38107dbb03c7f0b72604a0b346b6eb3298"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1440c291db3f98a914e1afd9d6541e8fc60b4c3aab1a9008d03da4651e67386"}, - {file = "rpds_py-0.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0f2996fbac8e0b77fd67102becb9229986396e051f33dbceada3debaacc7033f"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f30d205755566a25f2ae0382944fcae2f350500ae4df4e795efa9e850821d82"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:159fba751a1e6b1c69244e23ba6c28f879a8758a3e992ed056d86d74a194a0f3"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1f044792e1adcea82468a72310c66a7f08728d72a244730d14880cd1dabe36b"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9251eb8aa82e6cf88510530b29eef4fac825a2b709baf5b94a6094894f252387"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01899794b654e616c8625b194ddd1e5b51ef5b60ed61baa7a2d9c2ad7b2a4238"}, - {file = "rpds_py-0.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0c43f8ae8f6be1d605b0465671124aa8d6a0e40f1fb81dcea28b7e3d87ca1e1"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:207f57c402d1f8712618f737356e4b6f35253b6d20a324d9a47cb9f38ee43a6b"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b52e7c5ae35b00566d244ffefba0f46bb6bec749a50412acf42b1c3f402e2c90"}, - {file = "rpds_py-0.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:978fa96dbb005d599ec4fd9ed301b1cc45f1a8f7982d4793faf20b404b56677d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6aa8326a4a608e1c28da191edd7c924dff445251b94653988efb059b16577a4d"}, - {file = "rpds_py-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aad51239bee6bff6823bbbdc8ad85136c6125542bbc609e035ab98ca1e32a192"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd4dc3602370679c2dfb818d9c97b1137d4dd412230cfecd3c66a1bf388a196"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dd9da77c6ec1f258387957b754f0df60766ac23ed698b61941ba9acccd3284d1"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:190ca6f55042ea4649ed19c9093a9be9d63cd8a97880106747d7147f88a49d18"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:876bf9ed62323bc7dcfc261dbc5572c996ef26fe6406b0ff985cbcf460fc8a4c"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2818759aba55df50592ecbc95ebcdc99917fa7b55cc6796235b04193eb3c55"}, - {file = "rpds_py-0.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9ea4d00850ef1e917815e59b078ecb338f6a8efda23369677c54a5825dbebb55"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5855c85eb8b8a968a74dc7fb014c9166a05e7e7a8377fb91d78512900aadd13d"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:14c408e9d1a80dcb45c05a5149e5961aadb912fff42ca1dd9b68c0044904eb32"}, - {file = "rpds_py-0.9.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:65a0583c43d9f22cb2130c7b110e695fff834fd5e832a776a107197e59a1898e"}, - {file = "rpds_py-0.9.2-cp38-none-win32.whl", hash = "sha256:71f2f7715935a61fa3e4ae91d91b67e571aeb5cb5d10331ab681256bda2ad920"}, - {file = "rpds_py-0.9.2-cp38-none-win_amd64.whl", hash = "sha256:674c704605092e3ebbbd13687b09c9f78c362a4bc710343efe37a91457123044"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:07e2c54bef6838fa44c48dfbc8234e8e2466d851124b551fc4e07a1cfeb37260"}, - {file = "rpds_py-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f7fdf55283ad38c33e35e2855565361f4bf0abd02470b8ab28d499c663bc5d7c"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:890ba852c16ace6ed9f90e8670f2c1c178d96510a21b06d2fa12d8783a905193"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:50025635ba8b629a86d9d5474e650da304cb46bbb4d18690532dd79341467846"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517cbf6e67ae3623c5127206489d69eb2bdb27239a3c3cc559350ef52a3bbf0b"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0836d71ca19071090d524739420a61580f3f894618d10b666cf3d9a1688355b1"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c439fd54b2b9053717cca3de9583be6584b384d88d045f97d409f0ca867d80f"}, - {file = "rpds_py-0.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f68996a3b3dc9335037f82754f9cdbe3a95db42bde571d8c3be26cc6245f2324"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7d68dc8acded354c972116f59b5eb2e5864432948e098c19fe6994926d8e15c3"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f963c6b1218b96db85fc37a9f0851eaf8b9040aa46dec112611697a7023da535"}, - {file = "rpds_py-0.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a46859d7f947061b4010e554ccd1791467d1b1759f2dc2ec9055fa239f1bc26"}, - {file = "rpds_py-0.9.2-cp39-none-win32.whl", hash = "sha256:e07e5dbf8a83c66783a9fe2d4566968ea8c161199680e8ad38d53e075df5f0d0"}, - {file = "rpds_py-0.9.2-cp39-none-win_amd64.whl", hash = "sha256:682726178138ea45a0766907957b60f3a1bf3acdf212436be9733f28b6c5af3c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:196cb208825a8b9c8fc360dc0f87993b8b260038615230242bf18ec84447c08d"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c7671d45530fcb6d5e22fd40c97e1e1e01965fc298cbda523bb640f3d923b387"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b32f0940adec65099f3b1c215ef7f1d025d13ff947975a055989cb7fd019a4"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f67da97f5b9eac838b6980fc6da268622e91f8960e083a34533ca710bec8611"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03975db5f103997904c37e804e5f340c8fdabbb5883f26ee50a255d664eed58c"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:987b06d1cdb28f88a42e4fb8a87f094e43f3c435ed8e486533aea0bf2e53d931"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c861a7e4aef15ff91233751619ce3a3d2b9e5877e0fcd76f9ea4f6847183aa16"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02938432352359805b6da099c9c95c8a0547fe4b274ce8f1a91677401bb9a45f"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:ef1f08f2a924837e112cba2953e15aacfccbbfcd773b4b9b4723f8f2ddded08e"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:35da5cc5cb37c04c4ee03128ad59b8c3941a1e5cd398d78c37f716f32a9b7f67"}, - {file = "rpds_py-0.9.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:141acb9d4ccc04e704e5992d35472f78c35af047fa0cfae2923835d153f091be"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:79f594919d2c1a0cc17d1988a6adaf9a2f000d2e1048f71f298b056b1018e872"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:a06418fe1155e72e16dddc68bb3780ae44cebb2912fbd8bb6ff9161de56e1798"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b2eb034c94b0b96d5eddb290b7b5198460e2d5d0c421751713953a9c4e47d10"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b08605d248b974eb02f40bdcd1a35d3924c83a2a5e8f5d0fa5af852c4d960af"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0805911caedfe2736935250be5008b261f10a729a303f676d3d5fea6900c96a"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab2299e3f92aa5417d5e16bb45bb4586171c1327568f638e8453c9f8d9e0f020"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c8d7594e38cf98d8a7df25b440f684b510cf4627fe038c297a87496d10a174f"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b9ec12ad5f0a4625db34db7e0005be2632c1013b253a4a60e8302ad4d462afd"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1fcdee18fea97238ed17ab6478c66b2095e4ae7177e35fb71fbe561a27adf620"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:933a7d5cd4b84f959aedeb84f2030f0a01d63ae6cf256629af3081cf3e3426e8"}, - {file = "rpds_py-0.9.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:686ba516e02db6d6f8c279d1641f7067ebb5dc58b1d0536c4aaebb7bf01cdc5d"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0173c0444bec0a3d7d848eaeca2d8bd32a1b43f3d3fde6617aac3731fa4be05f"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d576c3ef8c7b2d560e301eb33891d1944d965a4d7a2eacb6332eee8a71827db6"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed89861ee8c8c47d6beb742a602f912b1bb64f598b1e2f3d758948721d44d468"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1054a08e818f8e18910f1bee731583fe8f899b0a0a5044c6e680ceea34f93876"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99e7c4bb27ff1aab90dcc3e9d37ee5af0231ed98d99cb6f5250de28889a3d502"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c545d9d14d47be716495076b659db179206e3fd997769bc01e2d550eeb685596"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9039a11bca3c41be5a58282ed81ae422fa680409022b996032a43badef2a3752"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fb39aca7a64ad0c9490adfa719dbeeb87d13be137ca189d2564e596f8ba32c07"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2d8b3b3a2ce0eaa00c5bbbb60b6713e94e7e0becab7b3db6c5c77f979e8ed1f1"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:99b1c16f732b3a9971406fbfe18468592c5a3529585a45a35adbc1389a529a03"}, - {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, - {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, -] - -[[package]] -name = "rtree" -version = "1.0.1" -description = "R-Tree spatial index for Python GIS" -optional = false -python-versions = ">=3.7" -files = [ - {file = "Rtree-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9855b8f11cdad99c56eb361b7b632a4fbd3d8cbe3f2081426b445f0cfb7fdca9"}, - {file = "Rtree-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:18ce7e4d04b85c48f2d364835620b3b20e38e199639746e7b12f07a2303e18ff"}, - {file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:784efa6b7be9e99b33613ae8495931032689441eabb6120c9b3eb91188c33794"}, - {file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:157207191aebdacbbdbb369e698cfbfebce53bc97114e96c8af5bed3126475f1"}, - {file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fb3671a8d440c24b1dd29ec621d4345ced7185e26f02abe98e85a6629fcb50"}, - {file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11d16f51cf9205cd6995af36e24efe8f184270f667fb49bb69b09fc46b97e7d4"}, - {file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6db6a0a93e41594ffc14b053f386dd414ab5a82535bbd9aedafa6ac8dc0650d8"}, - {file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6e29e5eb3083ad12ac5c1ce6e37465ea3428d894d3466cc9c9e2ee4bf768e53"}, - {file = "Rtree-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:656b148589c0b5bab4a7db4d033634329f42a5feaac10ca40aceeca109d83c1f"}, - {file = "Rtree-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b2c15f9373ba314c83a8df5cb6d99b4e3af23c376c6b1317add995432dd0970"}, - {file = "Rtree-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93c5e0bf31e76b4f92a6eec3d2891e938408774c75a8ed6ac3d2c8db04a2be33"}, - {file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6792de0e3c2fd3ad7e069445027603bec7a47000432f49c80246886311f4f152"}, - {file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e131b570dc360a49e7f3b60e7bc6517943a54df056587964d1cb903889e7e"}, - {file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:becd711fe97c2e09b1b7969e83080a3c8012bce2d30f6db879aade255fcba5c1"}, - {file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:015df09e1bc55ddf7c88799bf1515d058cd0ee78eacf4cd443a32876d3b3a863"}, - {file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c2973b76f61669a85e160b4ad09879c4089fc0e3f20fd99adf161ca298fe8374"}, - {file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e4335e131a58952635560a003458011d97f9ea6f3c010dc24906050b42ee2c03"}, - {file = "Rtree-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:e7ca5d743f6a1dc62653dfac8ee7ce2e1ba91be7cf97916a7f60b7cbe48fb48d"}, - {file = "Rtree-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2ee7165e9872a026ccb868c021711eba39cedf7d1820763c9de52d5324691a92"}, - {file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8de99f28af0f1783eefb80918959903b4b18112f6a12b48f296ecb162804e69d"}, - {file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a94e2f4bf74bd202ea8b67ea3d7c71e763ad41f79be1d6b72aa2c8d5a8e92c4"}, - {file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5120da3a1b96f3a7a17dd6af0afdd4e6f3cc9baa87e9ee0a272882f01f980bb"}, - {file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7e3d5f0e7b28250afbb290ab88b49aa0f121c9714d0da2080581783690347507"}, - {file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:296203e933b6ec0dd07f6a7456c4f1492def95b6993f20cc61c92b0fee0aecc5"}, - {file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:77908cd7acdd519a731979ebf5baff8afd102109c2f52864c1e6ee75d3ea2d87"}, - {file = "Rtree-1.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1a213e5d385278ca7668bc5b27083f8d6e39996a9bd59b6528f3a30009dae4ed"}, - {file = "Rtree-1.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfa8cffec5cb9fed494c4bb335ebdb69b3c26178b0b685f67f79296c6b3d800c"}, - {file = "Rtree-1.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b31fd22d214160859d038da7cb2aaa27acb71efc24a7bcc75c84b5e502721549"}, - {file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d68a81ad419d5c2ea5fecc677e6c178666c057e2c7b24100a6c48392196f1e9"}, - {file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62f38020af47b765adc6b0bc7c4e810c6c3d1eab44ba339b592ff25a4c0dc0a7"}, - {file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50b658a6707f215a0056d52e9f83a97148c0af62dea07cf29b3789a2c429e78a"}, - {file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3573cbb0de872f54d0a0c29596a84e8ac3939c47ca3bece4a82e92775730a0d0"}, - {file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5abe5a19d943a88bea14901970e4c53e4579fc2662404cdea6163bf4c04d49a"}, - {file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1e894112cef4de6c518bdea0b43eada65f12888c3645cc437c3a677aa023039f"}, - {file = "Rtree-1.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:582854252b8fd5c8472478af060635434931fb55edd269bac128cbf2eef43620"}, - {file = "Rtree-1.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b54057e8a8ad92c1d8e9eaa5cf32aad70dde454abbf9b638e9d6024520a52c02"}, - {file = "Rtree-1.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:698de8ce6c62e159d93b35bacf64bcf3619077b5367bc88cd2cff5e0bc36169b"}, - {file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273ee61783de3a1664e5f868feebf5eea4629447137751bfa4087b0f82093082"}, - {file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16900ee02cf5c198a42b03635268a80f606aa102f3f7618b89f75023d406da1c"}, - {file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ce4a6fdb63254a4c1efebe7a4f7a59b1c333c703bde4ae715d9ad88c833e10b"}, - {file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5b20f69e040a05503b22297af223f336fe7047909b57e4b207b98292f33a229f"}, - {file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:57128293dd625cb1f07726f32208097953e8854d70ab1fc55d6858733618b9ed"}, - {file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e898d7409ab645c25e06d4e058f99271182601d70b2887aba3351bf08e09a0c6"}, - {file = "Rtree-1.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ad9912faeddb1ddcec5e26b33089166d58a107af6862d8b7f1bb2b7c0002ab39"}, - {file = "Rtree-1.0.1.tar.gz", hash = "sha256:222121699c303a64065d849bf7038b1ecabc37b65c7fa340bedb38ef0e805429"}, -] - -[[package]] -name = "ruff" -version = "0.0.284" -description = "An extremely fast Python linter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.0.284-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:8b949084941232e2c27f8d12c78c5a6a010927d712ecff17231ee1a8371c205b"}, - {file = "ruff-0.0.284-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:a3930d66b35e4dc96197422381dff2a4e965e9278b5533e71ae8474ef202fab0"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d1f7096038961d8bc3b956ee69d73826843eb5b39a5fa4ee717ed473ed69c95"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bcaf85907fc905d838f46490ee15f04031927bbea44c478394b0bfdeadc27362"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3660b85a9d84162a055f1add334623ae2d8022a84dcd605d61c30a57b436c32"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0a3218458b140ea794da72b20ea09cbe13c4c1cdb7ac35e797370354628f4c05"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2fe880cff13fffd735387efbcad54ba0ff1272bceea07f86852a33ca71276f4"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1d098ea74d0ce31478765d1f8b4fbdbba2efc532397b5c5e8e5ea0c13d7e5ae"}, - {file = "ruff-0.0.284-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c79ae3308e308b94635cd57a369d1e6f146d85019da2fbc63f55da183ee29b"}, - {file = "ruff-0.0.284-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f86b2b1e7033c00de45cc176cf26778650fb8804073a0495aca2f674797becbb"}, - {file = "ruff-0.0.284-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e37e086f4d623c05cd45a6fe5006e77a2b37d57773aad96b7802a6b8ecf9c910"}, - {file = "ruff-0.0.284-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d29dfbe314e1131aa53df213fdfea7ee874dd96ea0dd1471093d93b59498384d"}, - {file = "ruff-0.0.284-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:88295fd649d0aa1f1271441df75bf06266a199497afd239fd392abcfd75acd7e"}, - {file = "ruff-0.0.284-py3-none-win32.whl", hash = "sha256:735cd62fccc577032a367c31f6a9de7c1eb4c01fa9a2e60775067f44f3fc3091"}, - {file = "ruff-0.0.284-py3-none-win_amd64.whl", hash = "sha256:f67ed868d79fbcc61ad0fa034fe6eed2e8d438d32abce9c04b7c4c1464b2cf8e"}, - {file = "ruff-0.0.284-py3-none-win_arm64.whl", hash = "sha256:1292cfc764eeec3cde35b3a31eae3f661d86418b5e220f5d5dba1c27a6eccbb6"}, - {file = "ruff-0.0.284.tar.gz", hash = "sha256:ebd3cc55cd499d326aac17a331deaea29bea206e01c08862f9b5c6e93d77a491"}, -] - -[[package]] -name = "s2sphere" -version = "0.2.5" -description = "Python implementation of the S2 Geometry Library" -optional = false -python-versions = "*" -files = [ - {file = "s2sphere-0.2.5-py2.py3-none-any.whl", hash = "sha256:d2340c9cf458ddc9a89afd1d8048a4195ce6fa6b0095ab900d4be5271e537401"}, - {file = "s2sphere-0.2.5.tar.gz", hash = "sha256:c2478c1ff7c601a59a7151a57b605435897514578fa6bdb8730721c182adbbaf"}, -] - -[package.dependencies] -future = ">=0.15" - -[package.extras] -docs = ["Sphinx (>=1.6.5)", "sphinx-rtd-theme (>=0.1.9)"] -tests = ["flake8 (>=2.5.4)", "hacking (>=0.11.0)", "nose (>=1.3.4)", "numpy (>=1.11.0)"] - -[[package]] -name = "safetensors" -version = "0.3.2" -description = "Fast and Safe Tensor serialization" -optional = false -python-versions = "*" -files = [ - {file = "safetensors-0.3.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b6a66989075c2891d743153e8ba9ca84ee7232c8539704488f454199b8b8f84d"}, - {file = "safetensors-0.3.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:670d6bc3a3b377278ce2971fa7c36ebc0a35041c4ea23b9df750a39380800195"}, - {file = "safetensors-0.3.2-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:564f42838721925b5313ae864ba6caa6f4c80a9fbe63cf24310c3be98ab013cd"}, - {file = "safetensors-0.3.2-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:7f80af7e4ab3188daaff12d43d078da3017a90d732d38d7af4eb08b6ca2198a5"}, - {file = "safetensors-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec30d78f20f1235b252d59cbb9755beb35a1fde8c24c89b3c98e6a1804cfd432"}, - {file = "safetensors-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16063d94d8f600768d3c331b1e97964b1bf3772e19710105fe24ec5a6af63770"}, - {file = "safetensors-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb44e140bf2aeda98d9dde669dbec15f7b77f96a9274469b91a6cf4bcc5ec3b"}, - {file = "safetensors-0.3.2-cp310-cp310-win32.whl", hash = "sha256:2961c1243fd0da46aa6a1c835305cc4595486f8ac64632a604d0eb5f2de76175"}, - {file = "safetensors-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c813920482c337d1424d306e1b05824a38e3ef94303748a0a287dea7a8c4f805"}, - {file = "safetensors-0.3.2-cp311-cp311-macosx_10_11_universal2.whl", hash = "sha256:707df34bd9b9047e97332136ad98e57028faeccdb9cfe1c3b52aba5964cc24bf"}, - {file = "safetensors-0.3.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:becc5bb85b2947eae20ed23b407ebfd5277d9a560f90381fe2c42e6c043677ba"}, - {file = "safetensors-0.3.2-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:30a75707be5cc9686490bde14b9a371cede4af53244ea72b340cfbabfffdf58a"}, - {file = "safetensors-0.3.2-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:54ad6af663e15e2b99e2ea3280981b7514485df72ba6d014dc22dae7ba6a5e6c"}, - {file = "safetensors-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37764b3197656ef507a266c453e909a3477dabc795962b38e3ad28226f53153b"}, - {file = "safetensors-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4939067736783acd8391d83cd97d6c202f94181951ce697d519f9746381b6a39"}, - {file = "safetensors-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0fac127ff8fb04834da5c6d85a8077e6a1c9180a11251d96f8068db922a17"}, - {file = "safetensors-0.3.2-cp311-cp311-win32.whl", hash = "sha256:155b82dbe2b0ebff18cde3f76b42b6d9470296e92561ef1a282004d449fa2b4c"}, - {file = "safetensors-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:a86428d196959619ce90197731be9391b5098b35100a7228ef4643957648f7f5"}, - {file = "safetensors-0.3.2-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:c1f8ab41ed735c5b581f451fd15d9602ff51aa88044bfa933c5fa4b1d0c644d1"}, - {file = "safetensors-0.3.2-cp37-cp37m-macosx_13_0_x86_64.whl", hash = "sha256:bc9cfb3c9ea2aec89685b4d656f9f2296f0f0d67ecf2bebf950870e3be89b3db"}, - {file = "safetensors-0.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ace5d471e3d78e0d93f952707d808b5ab5eac77ddb034ceb702e602e9acf2be9"}, - {file = "safetensors-0.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de3e20a388b444381bcda1a3193cce51825ddca277e4cf3ed1fe8d9b2d5722cd"}, - {file = "safetensors-0.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d7d70d48585fe8df00725aa788f2e64fd24a4c9ae07cd6be34f6859d0f89a9c"}, - {file = "safetensors-0.3.2-cp37-cp37m-win32.whl", hash = "sha256:6ff59bc90cdc857f68b1023be9085fda6202bbe7f2fd67d06af8f976d6adcc10"}, - {file = "safetensors-0.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8b05c93da15fa911763a89281906ca333ed800ab0ef1c7ce53317aa1a2322f19"}, - {file = "safetensors-0.3.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:8969cfd9e8d904e8d3c67c989e1bd9a95e3cc8980d4f95e4dcd43c299bb94253"}, - {file = "safetensors-0.3.2-cp38-cp38-macosx_13_0_x86_64.whl", hash = "sha256:f54148ac027556eb02187e9bc1556c4d916c99ca3cb34ca36a7d304d675035c1"}, - {file = "safetensors-0.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caec25fedbcf73f66c9261984f07885680f71417fc173f52279276c7f8a5edd3"}, - {file = "safetensors-0.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50224a1d99927ccf3b75e27c3d412f7043280431ab100b4f08aad470c37cf99a"}, - {file = "safetensors-0.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa98f49e95f02eb750d32c4947e7d5aa43883149ebd0414920866446525b70f0"}, - {file = "safetensors-0.3.2-cp38-cp38-win32.whl", hash = "sha256:33409df5e28a83dc5cc5547a3ac17c0f1b13a1847b1eb3bc4b3be0df9915171e"}, - {file = "safetensors-0.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:e04a7cbbb3856159ab99e3adb14521544f65fcb8548cce773a1435a0f8d78d27"}, - {file = "safetensors-0.3.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:7c864cf5dcbfb608c5378f83319c60cc9c97263343b57c02756b7613cd5ab4dd"}, - {file = "safetensors-0.3.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:14e8c19d6dc51d4f70ee33c46aff04c8ba3f95812e74daf8036c24bc86e75cae"}, - {file = "safetensors-0.3.2-cp39-cp39-macosx_13_0_arm64.whl", hash = "sha256:042a60f633c3c7009fdf6a7c182b165cb7283649d2a1e9c7a4a1c23454bd9a5b"}, - {file = "safetensors-0.3.2-cp39-cp39-macosx_13_0_x86_64.whl", hash = "sha256:fafd95e5ef41e8f312e2a32b7031f7b9b2a621b255f867b221f94bb2e9f51ae8"}, - {file = "safetensors-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ed77cf358abce2307f03634694e0b2a29822e322a1623e0b1aa4b41e871bf8b"}, - {file = "safetensors-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d344e8b2681a33aafc197c90b0def3229b3317d749531c72fa6259d0caa5c8c"}, - {file = "safetensors-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87ff0024ef2e5722a79af24688ce4a430f70601d0cf712a744105ed4b8f67ba5"}, - {file = "safetensors-0.3.2-cp39-cp39-win32.whl", hash = "sha256:827af9478b78977248ba93e2fd97ea307fb63f463f80cef4824460f8c2542a52"}, - {file = "safetensors-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9b09f27c456efa301f98681ea14b12f81f2637889f6336223ccab71e42c34541"}, - {file = "safetensors-0.3.2.tar.gz", hash = "sha256:2dbd34554ed3b99435a0e84df077108f5334c8336b5ed9cb8b6b98f7b10da2f6"}, -] - -[package.extras] -all = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "flax (>=0.6.3)", "h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "isort (>=5.5.4)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "numpy (>=1.21.6)", "paddlepaddle (>=2.4.1)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)", "tensorflow (==2.11.0)", "torch (>=1.10)"] -dev = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "flax (>=0.6.3)", "h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "isort (>=5.5.4)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "numpy (>=1.21.6)", "paddlepaddle (>=2.4.1)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)", "tensorflow (==2.11.0)", "torch (>=1.10)"] -jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)"] -numpy = ["numpy (>=1.21.6)"] -paddlepaddle = ["paddlepaddle (>=2.4.1)"] -pinned-tf = ["tensorflow (==2.11.0)"] -quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] -tensorflow = ["tensorflow (>=2.11.0)"] -testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "numpy (>=1.21.6)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "setuptools-rust (>=1.5.2)"] -torch = ["torch (>=1.10)"] - -[[package]] -name = "scikit-image" -version = "0.21.0" -description = "Image processing in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "scikit_image-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:978ac3302252155a8556cdfe067bad2d18d5ccef4e91c2f727bc564ed75566bc"}, - {file = "scikit_image-0.21.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:82c22e008527e5ee26ab08e3ce919998ef164d538ff30b9e5764b223cfda06b1"}, - {file = "scikit_image-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd29d2631d3e975c377066acfc1f4cb2cc95e2257cf70e7fedfcb96441096e88"}, - {file = "scikit_image-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6c12925ceb9f3aede555921e26642d601b2d37d1617002a2636f2cb5178ae2f"}, - {file = "scikit_image-0.21.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f538d4de77e4f3225d068d9ea2965bed3f7dda7f457a8f89634fa22ffb9ad8c"}, - {file = "scikit_image-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ec9bab6920ac43037d7434058b67b5778d42c60f67b8679239f48a471e7ed6f8"}, - {file = "scikit_image-0.21.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:a54720430dba833ffbb6dedd93d9f0938c5dd47d20ab9ba3e4e61c19d95f6f19"}, - {file = "scikit_image-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e40dd102da14cdadc09210f930b4556c90ff8f99cd9d8bcccf9f73a86c44245"}, - {file = "scikit_image-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff5719c7eb99596a39c3e1d9b564025bae78ecf1da3ee6842d34f6965b5f1474"}, - {file = "scikit_image-0.21.0-cp311-cp311-win_amd64.whl", hash = "sha256:146c3824253eee9ff346c4ad10cb58376f91aefaf4a4bb2fe11aa21691f7de76"}, - {file = "scikit_image-0.21.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4e1b09f81a99c9c390215929194847b3cd358550b4b65bb6e42c5393d69cb74a"}, - {file = "scikit_image-0.21.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9f7b5fb4a22f0d5ae0fa13beeb887c925280590145cd6d8b2630794d120ff7c7"}, - {file = "scikit_image-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4814033717f0b6491fee252facb9df92058d6a72ab78dd6408a50f3915a88b8"}, - {file = "scikit_image-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b0d6ed6502cca0c9719c444caafa0b8cda0f9e29e01ca42f621a240073284be"}, - {file = "scikit_image-0.21.0-cp38-cp38-win_amd64.whl", hash = "sha256:9194cb7bc21215fde6c1b1e9685d312d2aa8f65ea9736bc6311126a91c860032"}, - {file = "scikit_image-0.21.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54df1ddc854f37a912d42bc724e456e86858107e94048a81a27720bc588f9937"}, - {file = "scikit_image-0.21.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:c01e3ab0a1fabfd8ce30686d4401b7ed36e6126c9d4d05cb94abf6bdc46f7ac9"}, - {file = "scikit_image-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ef5d8d1099317b7b315b530348cbfa68ab8ce32459de3c074d204166951025c"}, - {file = "scikit_image-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b1e96c59cab640ca5c5b22c501524cfaf34cbe0cb51ba73bd9a9ede3fb6e1d"}, - {file = "scikit_image-0.21.0-cp39-cp39-win_amd64.whl", hash = "sha256:9cffcddd2a5594c0a06de2ae3e1e25d662745a26f94fda31520593669677c010"}, - {file = "scikit_image-0.21.0.tar.gz", hash = "sha256:b33e823c54e6f11873ea390ee49ef832b82b9f70752c8759efd09d5a4e3d87f0"}, -] - -[package.dependencies] -imageio = ">=2.27" -lazy_loader = ">=0.2" -networkx = ">=2.8" -numpy = ">=1.21.1" -packaging = ">=21" -pillow = ">=9.0.1" -PyWavelets = ">=1.1.1" -scipy = ">=1.8" -tifffile = ">=2022.8.12" - -[package.extras] -build = ["Cython (>=0.29.32)", "build", "meson-python (>=0.13)", "ninja", "numpy (>=1.21.1)", "packaging (>=21)", "pythran", "setuptools (>=67)", "spin (==0.3)", "wheel"] -data = ["pooch (>=1.6.0)"] -default = ["PyWavelets (>=1.1.1)", "imageio (>=2.27)", "lazy_loader (>=0.2)", "networkx (>=2.8)", "numpy (>=1.21.1)", "packaging (>=21)", "pillow (>=9.0.1)", "scipy (>=1.8)", "tifffile (>=2022.8.12)"] -developer = ["pre-commit", "rtoml"] -docs = ["dask[array] (>=2022.9.2)", "ipykernel", "ipywidgets", "kaleido", "matplotlib (>=3.5)", "myst-parser", "numpydoc (>=1.5)", "pandas (>=1.5)", "plotly (>=5.10)", "pooch (>=1.6)", "pydata-sphinx-theme (>=0.13)", "pytest-runner", "scikit-learn (>=0.24.0)", "seaborn (>=0.11)", "sphinx (>=5.0)", "sphinx-copybutton", "sphinx-gallery (>=0.11)", "sphinx_design (>=0.3)", "tifffile (>=2022.8.12)"] -optional = ["SimpleITK", "astropy (>=5.0)", "cloudpickle (>=0.2.1)", "dask[array] (>=2021.1.0)", "matplotlib (>=3.5)", "pooch (>=1.6.0)", "pyamg", "scikit-learn (>=0.24.0)"] -test = ["asv", "matplotlib (>=3.5)", "pooch (>=1.6.0)", "pytest (>=7.0)", "pytest-cov (>=2.11.0)", "pytest-faulthandler", "pytest-localserver"] - -[[package]] -name = "scikit-learn" -version = "1.3.0" -description = "A set of python modules for machine learning and data mining" -optional = false -python-versions = ">=3.8" -files = [ - {file = "scikit-learn-1.3.0.tar.gz", hash = "sha256:8be549886f5eda46436b6e555b0e4873b4f10aa21c07df45c4bc1735afbccd7a"}, - {file = "scikit_learn-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:981287869e576d42c682cf7ca96af0c6ac544ed9316328fd0d9292795c742cf5"}, - {file = "scikit_learn-1.3.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:436aaaae2c916ad16631142488e4c82f4296af2404f480e031d866863425d2a2"}, - {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e28d8fa47a0b30ae1bd7a079519dd852764e31708a7804da6cb6f8b36e3630"}, - {file = "scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80c08834a473d08a204d966982a62e11c976228d306a2648c575e3ead12111"}, - {file = "scikit_learn-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:552fd1b6ee22900cf1780d7386a554bb96949e9a359999177cf30211e6b20df6"}, - {file = "scikit_learn-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79970a6d759eb00a62266a31e2637d07d2d28446fca8079cf9afa7c07b0427f8"}, - {file = "scikit_learn-1.3.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:850a00b559e636b23901aabbe79b73dc604b4e4248ba9e2d6e72f95063765603"}, - {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee04835fb016e8062ee9fe9074aef9b82e430504e420bff51e3e5fffe72750ca"}, - {file = "scikit_learn-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d953531f5d9f00c90c34fa3b7d7cfb43ecff4c605dac9e4255a20b114a27369"}, - {file = "scikit_learn-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:151ac2bf65ccf363664a689b8beafc9e6aae36263db114b4ca06fbbbf827444a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a885a9edc9c0a341cab27ec4f8a6c58b35f3d449c9d2503a6fd23e06bbd4f6a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:9877af9c6d1b15486e18a94101b742e9d0d2f343d35a634e337411ddb57783f3"}, - {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c470f53cea065ff3d588050955c492793bb50c19a92923490d18fcb637f6383a"}, - {file = "scikit_learn-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd6e2d7389542eae01077a1ee0318c4fec20c66c957f45c7aac0c6eb0fe3c612"}, - {file = "scikit_learn-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:3a11936adbc379a6061ea32fa03338d4ca7248d86dd507c81e13af428a5bc1db"}, - {file = "scikit_learn-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:998d38fcec96584deee1e79cd127469b3ad6fefd1ea6c2dfc54e8db367eb396b"}, - {file = "scikit_learn-1.3.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:ded35e810438a527e17623ac6deae3b360134345b7c598175ab7741720d7ffa7"}, - {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8102d5036e28d08ab47166b48c8d5e5810704daecf3a476a4282d562be9a28"}, - {file = "scikit_learn-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7617164951c422747e7c32be4afa15d75ad8044f42e7d70d3e2e0429a50e6718"}, - {file = "scikit_learn-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:1d54fb9e6038284548072df22fd34777e434153f7ffac72c8596f2d6987110dd"}, -] - -[package.dependencies] -joblib = ">=1.1.1" -numpy = ">=1.17.3" -scipy = ">=1.5.0" -threadpoolctl = ">=2.0.0" - -[package.extras] -benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] -docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=6.0.0)", "sphinx-copybutton (>=0.5.2)", "sphinx-gallery (>=0.10.1)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.14.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] -tests = ["black (>=23.3.0)", "matplotlib (>=3.1.3)", "mypy (>=1.3)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=7.1.2)", "pytest-cov (>=2.9.0)", "ruff (>=0.0.272)", "scikit-image (>=0.16.2)"] - [[package]] name = "scipy" -version = "1.9.3" +version = "1.11.1" description = "Fundamental algorithms for scientific computing in Python" optional = false -python-versions = ">=3.8" +python-versions = "<3.13,>=3.9" files = [ - {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, - {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, - {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, - {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, - {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, - {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, - {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, - {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, - {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, - {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, - {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, - {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, - {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, - {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, - {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, - {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, - {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, - {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, - {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, - {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, - {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, + {file = "scipy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aec8c62fbe52914f9cf28d846cf0401dd80ab80788bbab909434eb336ed07c04"}, + {file = "scipy-1.11.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:3b9963798df1d8a52db41a6fc0e6fa65b1c60e85d73da27ae8bb754de4792481"}, + {file = "scipy-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e8eb42db36526b130dfbc417609498a6192381abc1975b91e3eb238e0b41c1a"}, + {file = "scipy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:366a6a937110d80dca4f63b3f5b00cc89d36f678b2d124a01067b154e692bab1"}, + {file = "scipy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:08d957ca82d3535b3b9ba6c8ff355d78fe975271874e2af267cb5add5bd78625"}, + {file = "scipy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:e866514bc2d660608447b6ba95c8900d591f2865c07cca0aa4f7ff3c4ca70f30"}, + {file = "scipy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba94eeef3c9caa4cea7b402a35bb02a5714ee1ee77eb98aca1eed4543beb0f4c"}, + {file = "scipy-1.11.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:512fdc18c65f76dadaca139348e525646d440220d8d05f6d21965b8d4466bccd"}, + {file = "scipy-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cce154372f0ebe88556ed06d7b196e9c2e0c13080ecb58d0f35062dc7cc28b47"}, + {file = "scipy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4bb943010203465ac81efa392e4645265077b4d9e99b66cf3ed33ae12254173"}, + {file = "scipy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:249cfa465c379c9bb2c20123001e151ff5e29b351cbb7f9c91587260602c58d0"}, + {file = "scipy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:ffb28e3fa31b9c376d0fb1f74c1f13911c8c154a760312fbee87a21eb21efe31"}, + {file = "scipy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:39154437654260a52871dfde852adf1b93b1d1bc5dc0ffa70068f16ec0be2624"}, + {file = "scipy-1.11.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b588311875c58d1acd4ef17c983b9f1ab5391755a47c3d70b6bd503a45bfaf71"}, + {file = "scipy-1.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d51565560565a0307ed06fa0ec4c6f21ff094947d4844d6068ed04400c72d0c3"}, + {file = "scipy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b41a0f322b4eb51b078cb3441e950ad661ede490c3aca66edef66f4b37ab1877"}, + {file = "scipy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:396fae3f8c12ad14c5f3eb40499fd06a6fef8393a6baa352a652ecd51e74e029"}, + {file = "scipy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:be8c962a821957fdde8c4044efdab7a140c13294997a407eaee777acf63cbf0c"}, + {file = "scipy-1.11.1.tar.gz", hash = "sha256:fb5b492fa035334fd249f0973cc79ecad8b09c604b42a127a677b45a9a3d4289"}, ] [package.dependencies] -numpy = ">=1.18.5,<1.26.0" +numpy = ">=1.21.6,<1.28.0" [package.extras] -dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] -doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] -test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +dev = ["click", "cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] +doc = ["jupytext", "matplotlib (>2)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "scons" @@ -8355,59 +3413,6 @@ url = "https://github.com/SCons/scons-contrib.git" reference = "HEAD" resolved_reference = "f3b0100d3a628e4d18f496815903660a99489bae" -[[package]] -name = "secretstorage" -version = "3.3.3" -description = "Python bindings to FreeDesktop.org Secret Service API" -optional = false -python-versions = ">=3.6" -files = [ - {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, - {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, -] - -[package.dependencies] -cryptography = ">=2.0" -jeepney = ">=0.6" - -[[package]] -name = "segmentation-models-pytorch" -version = "0.3.3" -description = "Image segmentation models with pre-trained backbones. PyTorch." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "segmentation_models_pytorch-0.3.3-py3-none-any.whl", hash = "sha256:b4317d6f72cb1caf4b7e1d384096970e202600275f54deb8e774fc04d6c8b82e"}, - {file = "segmentation_models_pytorch-0.3.3.tar.gz", hash = "sha256:b3b21ab4cd26a6b2b9e7a6ed466ace6452eb26ed3c31ae491ea2d7cbb01e384b"}, -] - -[package.dependencies] -efficientnet-pytorch = "0.7.1" -pillow = "*" -pretrainedmodels = "0.7.4" -timm = "0.9.2" -torchvision = ">=0.5.0" -tqdm = "*" - -[package.extras] -test = ["black (==22.3.0)", "flake8 (==4.0.1)", "flake8-docstrings (==1.6.0)", "mock", "pre-commit", "pytest"] - -[[package]] -name = "send2trash" -version = "1.8.2" -description = "Send file to trash natively under Mac OS X, Windows and Linux" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "Send2Trash-1.8.2-py3-none-any.whl", hash = "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679"}, - {file = "Send2Trash-1.8.2.tar.gz", hash = "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312"}, -] - -[package.extras] -nativelib = ["pyobjc-framework-Cocoa", "pywin32"] -objc = ["pyobjc-framework-Cocoa"] -win32 = ["pywin32"] - [[package]] name = "sentry-sdk" version = "1.28.1" @@ -8550,167 +3555,6 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] -[[package]] -name = "shapely" -version = "1.8.5.post1" -description = "Geometric objects, predicates, and operations" -optional = false -python-versions = ">=3.6" -files = [ - {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d048f93e42ba578b82758c15d8ae037d08e69d91d9872bca5a1895b118f4e2b0"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99ab0ddc05e44acabdbe657c599fdb9b2d82e86c5493bdae216c0c4018a82dee"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a2f0da0109e81e0c101a2b4cd8412f73f5f299e7b5b2deaf64cd2a100ac118"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6fe855e7d45685926b6ba00aaeb5eba5862611f7465775dacd527e081a8ced6d"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec14ceca36f67cb48b34d02d7f65a9acae15cd72b48e303531893ba4a960f3ea"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a2b2a65fa7f97115c1cd989fe9d6f39281ca2a8a014f1d4904c1a6e34d7f25"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-win32.whl", hash = "sha256:21776184516a16bf82a0c3d6d6a312b3cd15a4cabafc61ee01cf2714a82e8396"}, - {file = "Shapely-1.8.5.post1-cp310-cp310-win_amd64.whl", hash = "sha256:a354199219c8d836f280b88f2c5102c81bb044ccea45bd361dc38a79f3873714"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:783bad5f48e2708a0e2f695a34ed382e4162c795cb2f0368b39528ac1d6db7ed"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a23ef3882d6aa203dd3623a3d55d698f59bfbd9f8a3bfed52c2da05a7f0f8640"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab38f7b5196ace05725e407cb8cab9ff66edb8e6f7bb36a398e8f73f52a7aaa2"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d086591f744be483b34628b391d741e46f2645fe37594319e0a673cc2c26bcf"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4728666fff8cccc65a07448cae72c75a8773fea061c3f4f139c44adc429b18c3"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-win32.whl", hash = "sha256:84010db15eb364a52b74ea8804ef92a6a930dfc1981d17a369444b6ddec66efd"}, - {file = "Shapely-1.8.5.post1-cp311-cp311-win_amd64.whl", hash = "sha256:48dcfffb9e225c0481120f4bdf622131c8c95f342b00b158cdbe220edbbe20b6"}, - {file = "Shapely-1.8.5.post1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2fd15397638df291c427a53d641d3e6fd60458128029c8c4f487190473a69a91"}, - {file = "Shapely-1.8.5.post1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a74631e511153366c6dbe3229fa93f877e3c87ea8369cd00f1d38c76b0ed9ace"}, - {file = "Shapely-1.8.5.post1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:66bdac74fbd1d3458fa787191a90fa0ae610f09e2a5ec398c36f968cc0ed743f"}, - {file = "Shapely-1.8.5.post1-cp36-cp36m-win32.whl", hash = "sha256:6d388c0c1bd878ed1af4583695690aa52234b02ed35f93a1c8486ff52a555838"}, - {file = "Shapely-1.8.5.post1-cp36-cp36m-win_amd64.whl", hash = "sha256:be9423d5a3577ac2e92c7e758bd8a2b205f5e51a012177a590bc46fc51eb4834"}, - {file = "Shapely-1.8.5.post1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5d7f85c2d35d39ff53c9216bc76b7641c52326f7e09aaad1789a3611a0f812f2"}, - {file = "Shapely-1.8.5.post1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:adcf8a11b98af9375e32bff91de184f33a68dc48b9cb9becad4f132fa25cfa3c"}, - {file = "Shapely-1.8.5.post1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:753ed0e21ab108bd4282405b9b659f2e985e8502b1a72b978eaa51d3496dee19"}, - {file = "Shapely-1.8.5.post1-cp37-cp37m-win32.whl", hash = "sha256:65b21243d8f6bcd421210daf1fabb9de84de2c04353c5b026173b88d17c1a581"}, - {file = "Shapely-1.8.5.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:370b574c78dc5af3a198a6da5d9b3d7c04654bd2ef7e80e80a3a0992dfb2d9cd"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:532a55ee2a6c52d23d6f7d1567c8f0473635f3b270262c44e1b0c88096827e22"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3480657460e939f45a7d359ef0e172a081f249312557fe9aa78c4fd3a362d993"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b65f5d530ba91e49ffc7c589255e878d2506a8b96ffce69d3b7c4500a9a9eaf8"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:147066da0be41b147a61f8eb805dea3b13709dbc873a431ccd7306e24d712bc0"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c2822111ddc5bcfb116e6c663e403579d0fe3f147d2a97426011a191c43a7458"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b47bb6f9369e8bf3e6dbd33e6a25a47ee02b2874792a529fe04a49bf8bc0df6"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-win32.whl", hash = "sha256:2e0a8c2e55f1be1312b51c92b06462ea89e6bb703fab4b114e7a846d941cfc40"}, - {file = "Shapely-1.8.5.post1-cp38-cp38-win_amd64.whl", hash = "sha256:0d885cb0cf670c1c834df3f371de8726efdf711f18e2a75da5cfa82843a7ab65"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0b4ee3132ee90f07d63db3aea316c4c065ed7a26231458dda0874414a09d6ba3"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:02dd5d7dc6e46515d88874134dc8fcdc65826bca93c3eecee59d1910c42c1b17"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c6a9a4a31cd6e86d0fbe8473ceed83d4fe760b19d949fb557ef668defafea0f6"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:38f0fbbcb8ca20c16451c966c1f527cc43968e121c8a048af19ed3e339a921cd"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78fb9d929b8ee15cfd424b6c10879ce1907f24e05fb83310fc47d2cd27088e40"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89164e7a9776a19e29f01369a98529321994e2e4d852b92b7e01d4d9804c55bf"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-win32.whl", hash = "sha256:8e59817b0fe63d34baedaabba8c393c0090f061917d18fc0bcc2f621937a8f73"}, - {file = "Shapely-1.8.5.post1-cp39-cp39-win_amd64.whl", hash = "sha256:e9c30b311de2513555ab02464ebb76115d242842b29c412f5a9aa0cac57be9f6"}, - {file = "Shapely-1.8.5.post1.tar.gz", hash = "sha256:ef3be705c3eac282a28058e6c6e5503419b250f482320df2172abcbea642c831"}, -] - -[package.extras] -all = ["numpy", "pytest", "pytest-cov"] -test = ["pytest", "pytest-cov"] -vectorized = ["numpy"] - -[[package]] -name = "shellingham" -version = "1.5.0.post1" -description = "Tool to Detect Surrounding Shell" -optional = false -python-versions = ">=3.7" -files = [ - {file = "shellingham-1.5.0.post1-py2.py3-none-any.whl", hash = "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744"}, - {file = "shellingham-1.5.0.post1.tar.gz", hash = "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28"}, -] - -[[package]] -name = "simplejson" -version = "3.19.1" -description = "Simple, fast, extensible JSON encoder/decoder for Python" -optional = false -python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "simplejson-3.19.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:412e58997a30c5deb8cab5858b8e2e5b40ca007079f7010ee74565cc13d19665"}, - {file = "simplejson-3.19.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e765b1f47293dedf77946f0427e03ee45def2862edacd8868c6cf9ab97c8afbd"}, - {file = "simplejson-3.19.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3231100edee292da78948fa0a77dee4e5a94a0a60bcba9ed7a9dc77f4d4bb11e"}, - {file = "simplejson-3.19.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:081ea6305b3b5e84ae7417e7f45956db5ea3872ec497a584ec86c3260cda049e"}, - {file = "simplejson-3.19.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f253edf694ce836631b350d758d00a8c4011243d58318fbfbe0dd54a6a839ab4"}, - {file = "simplejson-3.19.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:5db86bb82034e055257c8e45228ca3dbce85e38d7bfa84fa7b2838e032a3219c"}, - {file = "simplejson-3.19.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:69a8b10a4f81548bc1e06ded0c4a6c9042c0be0d947c53c1ed89703f7e613950"}, - {file = "simplejson-3.19.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:58ee5e24d6863b22194020eb62673cf8cc69945fcad6b283919490f6e359f7c5"}, - {file = "simplejson-3.19.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:73d0904c2471f317386d4ae5c665b16b5c50ab4f3ee7fd3d3b7651e564ad74b1"}, - {file = "simplejson-3.19.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:66d780047c31ff316ee305c3f7550f352d87257c756413632303fc59fef19eac"}, - {file = "simplejson-3.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd4d50a27b065447c9c399f0bf0a993bd0e6308db8bbbfbc3ea03b41c145775a"}, - {file = "simplejson-3.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c16ec6a67a5f66ab004190829eeede01c633936375edcad7cbf06d3241e5865"}, - {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17a963e8dd4d81061cc05b627677c1f6a12e81345111fbdc5708c9f088d752c9"}, - {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e78d79b10aa92f40f54178ada2b635c960d24fc6141856b926d82f67e56d169"}, - {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad071cd84a636195f35fa71de2186d717db775f94f985232775794d09f8d9061"}, - {file = "simplejson-3.19.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e7c70f19405e5f99168077b785fe15fcb5f9b3c0b70b0b5c2757ce294922c8c"}, - {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54fca2b26bcd1c403146fd9461d1da76199442297160721b1d63def2a1b17799"}, - {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:48600a6e0032bed17c20319d91775f1797d39953ccfd68c27f83c8d7fc3b32cb"}, - {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:93f5ac30607157a0b2579af59a065bcfaa7fadeb4875bf927a8f8b6739c8d910"}, - {file = "simplejson-3.19.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b79642a599740603ca86cf9df54f57a2013c47e1dd4dd2ae4769af0a6816900"}, - {file = "simplejson-3.19.1-cp310-cp310-win32.whl", hash = "sha256:d9f2c27f18a0b94107d57294aab3d06d6046ea843ed4a45cae8bd45756749f3a"}, - {file = "simplejson-3.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:5673d27806085d2a413b3be5f85fad6fca4b7ffd31cfe510bbe65eea52fff571"}, - {file = "simplejson-3.19.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:79c748aa61fd8098d0472e776743de20fae2686edb80a24f0f6593a77f74fe86"}, - {file = "simplejson-3.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:390f4a8ca61d90bcf806c3ad644e05fa5890f5b9a72abdd4ca8430cdc1e386fa"}, - {file = "simplejson-3.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d61482b5d18181e6bb4810b4a6a24c63a490c3a20e9fbd7876639653e2b30a1a"}, - {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2541fdb7467ef9bfad1f55b6c52e8ea52b3ce4a0027d37aff094190a955daa9d"}, - {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46133bc7dd45c9953e6ee4852e3de3d5a9a4a03b068bd238935a5c72f0a1ce34"}, - {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f96def94576f857abf58e031ce881b5a3fc25cbec64b2bc4824824a8a4367af9"}, - {file = "simplejson-3.19.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f14ecca970d825df0d29d5c6736ff27999ee7bdf5510e807f7ad8845f7760ce"}, - {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:66389b6b6ee46a94a493a933a26008a1bae0cfadeca176933e7ff6556c0ce998"}, - {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:22b867205cd258050c2625325fdd9a65f917a5aff22a23387e245ecae4098e78"}, - {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c39fa911e4302eb79c804b221ddec775c3da08833c0a9120041dd322789824de"}, - {file = "simplejson-3.19.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:65dafe413b15e8895ad42e49210b74a955c9ae65564952b0243a18fb35b986cc"}, - {file = "simplejson-3.19.1-cp311-cp311-win32.whl", hash = "sha256:f05d05d99fce5537d8f7a0af6417a9afa9af3a6c4bb1ba7359c53b6257625fcb"}, - {file = "simplejson-3.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:b46aaf0332a8a9c965310058cf3487d705bf672641d2c43a835625b326689cf4"}, - {file = "simplejson-3.19.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b438e5eaa474365f4faaeeef1ec3e8d5b4e7030706e3e3d6b5bee6049732e0e6"}, - {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9d614a612ad02492f704fbac636f666fa89295a5d22b4facf2d665fc3b5ea9"}, - {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46e89f58e4bed107626edce1cf098da3664a336d01fc78fddcfb1f397f553d44"}, - {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96ade243fb6f3b57e7bd3b71e90c190cd0f93ec5dce6bf38734a73a2e5fa274f"}, - {file = "simplejson-3.19.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed18728b90758d171f0c66c475c24a443ede815cf3f1a91e907b0db0ebc6e508"}, - {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6a561320485017ddfc21bd2ed5de2d70184f754f1c9b1947c55f8e2b0163a268"}, - {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:2098811cd241429c08b7fc5c9e41fcc3f59f27c2e8d1da2ccdcf6c8e340ab507"}, - {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8f8d179393e6f0cf6c7c950576892ea6acbcea0a320838c61968ac7046f59228"}, - {file = "simplejson-3.19.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:eff87c68058374e45225089e4538c26329a13499bc0104b52b77f8428eed36b2"}, - {file = "simplejson-3.19.1-cp36-cp36m-win32.whl", hash = "sha256:d300773b93eed82f6da138fd1d081dc96fbe53d96000a85e41460fe07c8d8b33"}, - {file = "simplejson-3.19.1-cp36-cp36m-win_amd64.whl", hash = "sha256:37724c634f93e5caaca04458f267836eb9505d897ab3947b52f33b191bf344f3"}, - {file = "simplejson-3.19.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:74bf802debe68627227ddb665c067eb8c73aa68b2476369237adf55c1161b728"}, - {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70128fb92932524c89f373e17221cf9535d7d0c63794955cc3cd5868e19f5d38"}, - {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8090e75653ea7db75bc21fa5f7bcf5f7bdf64ea258cbbac45c7065f6324f1b50"}, - {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a755f7bfc8adcb94887710dc70cc12a69a454120c6adcc6f251c3f7b46ee6aac"}, - {file = "simplejson-3.19.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ccb2c1877bc9b25bc4f4687169caa925ffda605d7569c40e8e95186e9a5e58b"}, - {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:919bc5aa4d8094cf8f1371ea9119e5d952f741dc4162810ab714aec948a23fe5"}, - {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e333c5b62e93949f5ac27e6758ba53ef6ee4f93e36cc977fe2e3df85c02f6dc4"}, - {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3a4480e348000d89cf501b5606415f4d328484bbb431146c2971123d49fd8430"}, - {file = "simplejson-3.19.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cb502cde018e93e75dc8fc7bb2d93477ce4f3ac10369f48866c61b5e031db1fd"}, - {file = "simplejson-3.19.1-cp37-cp37m-win32.whl", hash = "sha256:f41915a4e1f059dfad614b187bc06021fefb5fc5255bfe63abf8247d2f7a646a"}, - {file = "simplejson-3.19.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3844305bc33d52c4975da07f75b480e17af3558c0d13085eaa6cc2f32882ccf7"}, - {file = "simplejson-3.19.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1cb19eacb77adc5a9720244d8d0b5507421d117c7ed4f2f9461424a1829e0ceb"}, - {file = "simplejson-3.19.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:926957b278de22797bfc2f004b15297013843b595b3cd7ecd9e37ccb5fad0b72"}, - {file = "simplejson-3.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b0e9a5e66969f7a47dc500e3dba8edc3b45d4eb31efb855c8647700a3493dd8a"}, - {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79d46e7e33c3a4ef853a1307b2032cfb7220e1a079d0c65488fbd7118f44935a"}, - {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344a5093b71c1b370968d0fbd14d55c9413cb6f0355fdefeb4a322d602d21776"}, - {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23fbb7b46d44ed7cbcda689295862851105c7594ae5875dce2a70eeaa498ff86"}, - {file = "simplejson-3.19.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d3025e7e9ddb48813aec2974e1a7e68e63eac911dd5e0a9568775de107ac79a"}, - {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:87b190e6ceec286219bd6b6f13547ca433f977d4600b4e81739e9ac23b5b9ba9"}, - {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dc935d8322ba9bc7b84f99f40f111809b0473df167bf5b93b89fb719d2c4892b"}, - {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3b652579c21af73879d99c8072c31476788c8c26b5565687fd9db154070d852a"}, - {file = "simplejson-3.19.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6aa7ca03f25b23b01629b1c7f78e1cd826a66bfb8809f8977a3635be2ec48f1a"}, - {file = "simplejson-3.19.1-cp38-cp38-win32.whl", hash = "sha256:08be5a241fdf67a8e05ac7edbd49b07b638ebe4846b560673e196b2a25c94b92"}, - {file = "simplejson-3.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:ca56a6c8c8236d6fe19abb67ef08d76f3c3f46712c49a3b6a5352b6e43e8855f"}, - {file = "simplejson-3.19.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6424d8229ba62e5dbbc377908cfee9b2edf25abd63b855c21f12ac596cd18e41"}, - {file = "simplejson-3.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:547ea86ca408a6735335c881a2e6208851027f5bfd678d8f2c92a0f02c7e7330"}, - {file = "simplejson-3.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:889328873c35cb0b2b4c83cbb83ec52efee5a05e75002e2c0c46c4e42790e83c"}, - {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44cdb4e544134f305b033ad79ae5c6b9a32e7c58b46d9f55a64e2a883fbbba01"}, - {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2b3f06430cbd4fac0dae5b2974d2bf14f71b415fb6de017f498950da8159b1"}, - {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d125e754d26c0298715bdc3f8a03a0658ecbe72330be247f4b328d229d8cf67f"}, - {file = "simplejson-3.19.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:476c8033abed7b1fd8db62a7600bf18501ce701c1a71179e4ce04ac92c1c5c3c"}, - {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:199a0bcd792811c252d71e3eabb3d4a132b3e85e43ebd93bfd053d5b59a7e78b"}, - {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a79b439a6a77649bb8e2f2644e6c9cc0adb720fc55bed63546edea86e1d5c6c8"}, - {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:203412745fed916fc04566ecef3f2b6c872b52f1e7fb3a6a84451b800fb508c1"}, - {file = "simplejson-3.19.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca922c61d87b4c38f37aa706520328ffe22d7ac1553ef1cadc73f053a673553"}, - {file = "simplejson-3.19.1-cp39-cp39-win32.whl", hash = "sha256:3e0902c278243d6f7223ba3e6c5738614c971fd9a887fff8feaa8dcf7249c8d4"}, - {file = "simplejson-3.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:d396b610e77b0c438846607cd56418bfc194973b9886550a98fd6724e8c6cfec"}, - {file = "simplejson-3.19.1-py3-none-any.whl", hash = "sha256:4710806eb75e87919b858af0cba4ffedc01b463edc3982ded7b55143f39e41e1"}, - {file = "simplejson-3.19.1.tar.gz", hash = "sha256:6277f60848a7d8319d27d2be767a7546bc965535b28070e310b3a9af90604a4c"}, -] - [[package]] name = "six" version = "1.16.0" @@ -8738,17 +3582,6 @@ docs = ["sphinx (>=1.5.3)"] qa = ["flake8"] test = ["mock", "nose"] -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, -] - [[package]] name = "snowballstemmer" version = "2.2.0" @@ -8791,17 +3624,6 @@ CFFI = ">=1.0" [package.extras] numpy = ["NumPy"] -[[package]] -name = "soupsieve" -version = "2.4.1" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.7" -files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, -] - [[package]] name = "sphinx" version = "6.2.1" @@ -9011,103 +3833,6 @@ files = [ [package.dependencies] ioctl-opt = "*" -[[package]] -name = "sqlalchemy" -version = "2.0.19" -description = "Database Abstraction Library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9deaae357edc2091a9ed5d25e9ee8bba98bcfae454b3911adeaf159c2e9ca9e3"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0bf0fd65b50a330261ec7fe3d091dfc1c577483c96a9fa1e4323e932961aa1b5"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d90ccc15ba1baa345796a8fb1965223ca7ded2d235ccbef80a47b85cea2d71a"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4e688f6784427e5f9479d1a13617f573de8f7d4aa713ba82813bcd16e259d1"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:584f66e5e1979a7a00f4935015840be627e31ca29ad13f49a6e51e97a3fb8cae"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c69ce70047b801d2aba3e5ff3cba32014558966109fecab0c39d16c18510f15"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-win32.whl", hash = "sha256:96f0463573469579d32ad0c91929548d78314ef95c210a8115346271beeeaaa2"}, - {file = "SQLAlchemy-2.0.19-cp310-cp310-win_amd64.whl", hash = "sha256:22bafb1da60c24514c141a7ff852b52f9f573fb933b1e6b5263f0daa28ce6db9"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d6894708eeb81f6d8193e996257223b6bb4041cb05a17cd5cf373ed836ef87a2"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8f2afd1aafded7362b397581772c670f20ea84d0a780b93a1a1529da7c3d369"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15afbf5aa76f2241184c1d3b61af1a72ba31ce4161013d7cb5c4c2fca04fd6e"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc05b59142445a4efb9c1fd75c334b431d35c304b0e33f4fa0ff1ea4890f92e"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5831138f0cc06b43edf5f99541c64adf0ab0d41f9a4471fd63b54ae18399e4de"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3afa8a21a9046917b3a12ffe016ba7ebe7a55a6fc0c7d950beb303c735c3c3ad"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-win32.whl", hash = "sha256:c896d4e6ab2eba2afa1d56be3d0b936c56d4666e789bfc59d6ae76e9fcf46145"}, - {file = "SQLAlchemy-2.0.19-cp311-cp311-win_amd64.whl", hash = "sha256:024d2f67fb3ec697555e48caeb7147cfe2c08065a4f1a52d93c3d44fc8e6ad1c"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:89bc2b374ebee1a02fd2eae6fd0570b5ad897ee514e0f84c5c137c942772aa0c"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd4d410a76c3762511ae075d50f379ae09551d92525aa5bb307f8343bf7c2c12"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f469f15068cd8351826df4080ffe4cc6377c5bf7d29b5a07b0e717dddb4c7ea2"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cda283700c984e699e8ef0fcc5c61f00c9d14b6f65a4f2767c97242513fcdd84"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:43699eb3f80920cc39a380c159ae21c8a8924fe071bccb68fc509e099420b148"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-win32.whl", hash = "sha256:61ada5831db36d897e28eb95f0f81814525e0d7927fb51145526c4e63174920b"}, - {file = "SQLAlchemy-2.0.19-cp37-cp37m-win_amd64.whl", hash = "sha256:57d100a421d9ab4874f51285c059003292433c648df6abe6c9c904e5bd5b0828"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:16a310f5bc75a5b2ce7cb656d0e76eb13440b8354f927ff15cbaddd2523ee2d1"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf7b5e3856cbf1876da4e9d9715546fa26b6e0ba1a682d5ed2fc3ca4c7c3ec5b"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e7b69d9ced4b53310a87117824b23c509c6fc1f692aa7272d47561347e133b6"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9eb4575bfa5afc4b066528302bf12083da3175f71b64a43a7c0badda2be365"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6b54d1ad7a162857bb7c8ef689049c7cd9eae2f38864fc096d62ae10bc100c7d"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5d6afc41ca0ecf373366fd8e10aee2797128d3ae45eb8467b19da4899bcd1ee0"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-win32.whl", hash = "sha256:430614f18443b58ceb9dedec323ecddc0abb2b34e79d03503b5a7579cd73a531"}, - {file = "SQLAlchemy-2.0.19-cp38-cp38-win_amd64.whl", hash = "sha256:eb60699de43ba1a1f77363f563bb2c652f7748127ba3a774f7cf2c7804aa0d3d"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a752b7a9aceb0ba173955d4f780c64ee15a1a991f1c52d307d6215c6c73b3a4c"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7351c05db355da112e056a7b731253cbeffab9dfdb3be1e895368513c7d70106"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa51ce4aea583b0c6b426f4b0563d3535c1c75986c4373a0987d84d22376585b"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae7473a67cd82a41decfea58c0eac581209a0aa30f8bc9190926fbf628bb17f7"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851a37898a8a39783aab603c7348eb5b20d83c76a14766a43f56e6ad422d1ec8"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539010665c90e60c4a1650afe4ab49ca100c74e6aef882466f1de6471d414be7"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-win32.whl", hash = "sha256:f82c310ddf97b04e1392c33cf9a70909e0ae10a7e2ddc1d64495e3abdc5d19fb"}, - {file = "SQLAlchemy-2.0.19-cp39-cp39-win_amd64.whl", hash = "sha256:8e712cfd2e07b801bc6b60fdf64853bc2bd0af33ca8fa46166a23fe11ce0dbb0"}, - {file = "SQLAlchemy-2.0.19-py3-none-any.whl", hash = "sha256:314145c1389b021a9ad5aa3a18bac6f5d939f9087d7fc5443be28cba19d2c972"}, - {file = "SQLAlchemy-2.0.19.tar.gz", hash = "sha256:77a14fa20264af73ddcdb1e2b9c5a829b8cc6b8304d0f093271980e36c200a3f"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} -typing-extensions = ">=4.2.0" - -[package.extras] -aiomysql = ["aiomysql", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx-oracle (>=7)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3-binary"] - -[[package]] -name = "stack-data" -version = "0.6.2" -description = "Extract data from python stack frames and tracebacks for informative displays" -optional = false -python-versions = "*" -files = [ - {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, - {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, -] - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - [[package]] name = "sympy" version = "1.12" @@ -9150,54 +3875,6 @@ files = [ [package.extras] doc = ["reno", "sphinx", "tornado (>=4.5)"] -[[package]] -name = "terminado" -version = "0.17.1" -description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -optional = false -python-versions = ">=3.7" -files = [ - {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, - {file = "terminado-0.17.1.tar.gz", hash = "sha256:6ccbbcd3a4f8a25a5ec04991f39a0b8db52dfcd487ea0e578d977e6752380333"}, -] - -[package.dependencies] -ptyprocess = {version = "*", markers = "os_name != \"nt\""} -pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} -tornado = ">=6.1.0" - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] - -[[package]] -name = "threadpoolctl" -version = "3.2.0" -description = "threadpoolctl" -optional = false -python-versions = ">=3.8" -files = [ - {file = "threadpoolctl-3.2.0-py3-none-any.whl", hash = "sha256:2b7818516e423bdaebb97c723f86a7c6b0a83d3f3b0970328d66f4d9104dc032"}, - {file = "threadpoolctl-3.2.0.tar.gz", hash = "sha256:c96a0ba3bdddeaca37dc4cc7344aafad41cdb8c313f74fdfe387a867bba93355"}, -] - -[[package]] -name = "tifffile" -version = "2023.7.18" -description = "Read and write TIFF files" -optional = false -python-versions = ">=3.9" -files = [ - {file = "tifffile-2023.7.18-py3-none-any.whl", hash = "sha256:a9449ab688b82b69f3ddf80e4e0b4de7b5b02549974a56e112061b816b3c5585"}, - {file = "tifffile-2023.7.18.tar.gz", hash = "sha256:5a5a624b2f7ab7f37e9ec4174ae2df1805b9658f89013f9b4b5550672f65f2a1"}, -] - -[package.dependencies] -numpy = "*" - -[package.extras] -all = ["defusedxml", "fsspec", "imagecodecs (>=2023.1.23)", "lxml", "matplotlib", "zarr"] - [[package]] name = "timezonefinder" version = "6.2.0" @@ -9219,195 +3896,15 @@ setuptools = ">=65.5" numba = ["numba (>=0.56,<1)"] pytz = ["pytz (>=2022.7.1)"] -[[package]] -name = "timm" -version = "0.9.2" -description = "PyTorch Image Models" -optional = false -python-versions = ">=3.7" -files = [ - {file = "timm-0.9.2-py3-none-any.whl", hash = "sha256:8da40cc58ed32b0622bf87d8714f9b7023398ba4cfa8fa678578d2aefde4a909"}, - {file = "timm-0.9.2.tar.gz", hash = "sha256:d0977cc5e02c69bda979fca8b52aa315a5f2cb64ebf8ad2c4631b1e452762c14"}, -] - -[package.dependencies] -huggingface-hub = "*" -pyyaml = "*" -safetensors = "*" -torch = ">=1.7" -torchvision = "*" - -[[package]] -name = "tinycss2" -version = "1.2.1" -description = "A tiny CSS parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, - {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, -] - -[package.dependencies] -webencodings = ">=0.4" - -[package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] -test = ["flake8", "isort", "pytest"] - -[[package]] -name = "tokenizers" -version = "0.13.3" -description = "Fast and Customizable Tokenizers" -optional = false -python-versions = "*" -files = [ - {file = "tokenizers-0.13.3-cp310-cp310-macosx_10_11_x86_64.whl", hash = "sha256:f3835c5be51de8c0a092058a4d4380cb9244fb34681fd0a295fbf0a52a5fdf33"}, - {file = "tokenizers-0.13.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4ef4c3e821730f2692489e926b184321e887f34fb8a6b80b8096b966ba663d07"}, - {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5fd1a6a25353e9aa762e2aae5a1e63883cad9f4e997c447ec39d071020459bc"}, - {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee0b1b311d65beab83d7a41c56a1e46ab732a9eed4460648e8eb0bd69fc2d059"}, - {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ef4215284df1277dadbcc5e17d4882bda19f770d02348e73523f7e7d8b8d396"}, - {file = "tokenizers-0.13.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4d53976079cff8a033f778fb9adca2d9d69d009c02fa2d71a878b5f3963ed30"}, - {file = "tokenizers-0.13.3-cp310-cp310-win32.whl", hash = "sha256:1f0e3b4c2ea2cd13238ce43548959c118069db7579e5d40ec270ad77da5833ce"}, - {file = "tokenizers-0.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:89649c00d0d7211e8186f7a75dfa1db6996f65edce4b84821817eadcc2d3c79e"}, - {file = "tokenizers-0.13.3-cp311-cp311-macosx_10_11_universal2.whl", hash = "sha256:56b726e0d2bbc9243872b0144515ba684af5b8d8cd112fb83ee1365e26ec74c8"}, - {file = "tokenizers-0.13.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:cc5c022ce692e1f499d745af293ab9ee6f5d92538ed2faf73f9708c89ee59ce6"}, - {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f55c981ac44ba87c93e847c333e58c12abcbb377a0c2f2ef96e1a266e4184ff2"}, - {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f247eae99800ef821a91f47c5280e9e9afaeed9980fc444208d5aa6ba69ff148"}, - {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b3e3215d048e94f40f1c95802e45dcc37c5b05eb46280fc2ccc8cd351bff839"}, - {file = "tokenizers-0.13.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ba2b0bf01777c9b9bc94b53764d6684554ce98551fec496f71bc5be3a03e98b"}, - {file = "tokenizers-0.13.3-cp311-cp311-win32.whl", hash = "sha256:cc78d77f597d1c458bf0ea7c2a64b6aa06941c7a99cb135b5969b0278824d808"}, - {file = "tokenizers-0.13.3-cp311-cp311-win_amd64.whl", hash = "sha256:ecf182bf59bd541a8876deccf0360f5ae60496fd50b58510048020751cf1724c"}, - {file = "tokenizers-0.13.3-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:0527dc5436a1f6bf2c0327da3145687d3bcfbeab91fed8458920093de3901b44"}, - {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07cbb2c307627dc99b44b22ef05ff4473aa7c7cc1fec8f0a8b37d8a64b1a16d2"}, - {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4560dbdeaae5b7ee0d4e493027e3de6d53c991b5002d7ff95083c99e11dd5ac0"}, - {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64064bd0322405c9374305ab9b4c07152a1474370327499911937fd4a76d004b"}, - {file = "tokenizers-0.13.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8c6e2ab0f2e3d939ca66aa1d596602105fe33b505cd2854a4c1717f704c51de"}, - {file = "tokenizers-0.13.3-cp37-cp37m-win32.whl", hash = "sha256:6cc29d410768f960db8677221e497226e545eaaea01aa3613fa0fdf2cc96cff4"}, - {file = "tokenizers-0.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fc2a7fdf864554a0dacf09d32e17c0caa9afe72baf9dd7ddedc61973bae352d8"}, - {file = "tokenizers-0.13.3-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:8791dedba834c1fc55e5f1521be325ea3dafb381964be20684b92fdac95d79b7"}, - {file = "tokenizers-0.13.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:d607a6a13718aeb20507bdf2b96162ead5145bbbfa26788d6b833f98b31b26e1"}, - {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3791338f809cd1bf8e4fee6b540b36822434d0c6c6bc47162448deee3f77d425"}, - {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2f35f30e39e6aab8716f07790f646bdc6e4a853816cc49a95ef2a9016bf9ce6"}, - {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310204dfed5aa797128b65d63538a9837cbdd15da2a29a77d67eefa489edda26"}, - {file = "tokenizers-0.13.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0f9b92ea052305166559f38498b3b0cae159caea712646648aaa272f7160963"}, - {file = "tokenizers-0.13.3-cp38-cp38-win32.whl", hash = "sha256:9a3fa134896c3c1f0da6e762d15141fbff30d094067c8f1157b9fdca593b5806"}, - {file = "tokenizers-0.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:8e7b0cdeace87fa9e760e6a605e0ae8fc14b7d72e9fc19c578116f7287bb873d"}, - {file = "tokenizers-0.13.3-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:00cee1e0859d55507e693a48fa4aef07060c4bb6bd93d80120e18fea9371c66d"}, - {file = "tokenizers-0.13.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a23ff602d0797cea1d0506ce69b27523b07e70f6dda982ab8cf82402de839088"}, - {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ce07445050b537d2696022dafb115307abdffd2a5c106f029490f84501ef97"}, - {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:280ffe95f50eaaf655b3a1dc7ff1d9cf4777029dbbc3e63a74e65a056594abc3"}, - {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97acfcec592f7e9de8cadcdcda50a7134423ac8455c0166b28c9ff04d227b371"}, - {file = "tokenizers-0.13.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd7730c98a3010cd4f523465867ff95cd9d6430db46676ce79358f65ae39797b"}, - {file = "tokenizers-0.13.3-cp39-cp39-win32.whl", hash = "sha256:48625a108029cb1ddf42e17a81b5a3230ba6888a70c9dc14e81bc319e812652d"}, - {file = "tokenizers-0.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:bc0a6f1ba036e482db6453571c9e3e60ecd5489980ffd95d11dc9f960483d783"}, - {file = "tokenizers-0.13.3.tar.gz", hash = "sha256:2e546dbb68b623008a5442353137fbb0123d311a6d7ba52f2667c8862a75af2e"}, -] - -[package.extras] -dev = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] -docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] -testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests"] - -[[package]] -name = "tomlkit" -version = "0.12.1" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"}, - {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"}, -] - -[[package]] -name = "torch" -version = "2.0.1+cu118" -description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "torch-2.0.1+cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:143b6c658c17d43376e2dfbaa2c106d35639d615e5e8dec4429cf1e510dd8d61"}, -] - -[package.dependencies] -filelock = "*" -jinja2 = "*" -networkx = "*" -sympy = "*" -triton = {version = "2.0.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -typing-extensions = "*" - -[package.extras] -opt-einsum = ["opt-einsum (>=3.3)"] - -[package.source] -type = "url" -url = "https://download.pytorch.org/whl/cu118/torch-2.0.1%2Bcu118-cp311-cp311-linux_x86_64.whl" - -[[package]] -name = "torchsummary" -version = "1.5.1" -description = "Model summary in PyTorch similar to `model.summary()` in Keras" -optional = false -python-versions = "*" -files = [ - {file = "torchsummary-1.5.1-py3-none-any.whl", hash = "sha256:10f41d1743fb918f83293f13183f532ab1bb8f6639a1b89e5f8592ec1919a976"}, - {file = "torchsummary-1.5.1.tar.gz", hash = "sha256:981bf689e22e0cf7f95c746002f20a24ad26aa6b9d861134a14bc6ce92230590"}, -] - -[[package]] -name = "torchvision" -version = "0.15.2+cu118" -description = "image and video datasets and models for torch deep learning" -optional = false -python-versions = ">=3.8" -files = [ - {file = "torchvision-0.15.2+cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:def9af47ebc2cad55c5aa2dad1230dcf4261833ed6df8a73e839bc233764f09e"}, -] - -[package.dependencies] -numpy = "*" -pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" -requests = "*" -torch = "2.0.1" - -[package.extras] -scipy = ["scipy"] - -[package.source] -type = "url" -url = "https://download.pytorch.org/whl/cu118/torchvision-0.15.2%2Bcu118-cp311-cp311-linux_x86_64.whl" - -[[package]] -name = "tornado" -version = "6.3.2" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">= 3.8" -files = [ - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, - {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, - {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, - {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, - {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, - {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, - {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, -] - [[package]] name = "tqdm" -version = "4.66.0" +version = "4.66.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" files = [ - {file = "tqdm-4.66.0-py3-none-any.whl", hash = "sha256:39d459c7140b7890174e69d4d68d6291bc774a55b4bc5d93c0b760798ac5a03e"}, - {file = "tqdm-4.66.0.tar.gz", hash = "sha256:cc6e7e52202d894e66632c5c8a9330bd0e3ff35d2965c93ca832114a3d865362"}, + {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, + {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, ] [package.dependencies] @@ -9419,160 +3916,6 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] -[[package]] -name = "traitlets" -version = "5.9.0" -description = "Traitlets Python configuration system" -optional = false -python-versions = ">=3.7" -files = [ - {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, - {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] - -[[package]] -name = "transformers" -version = "4.31.0" -description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "transformers-4.31.0-py3-none-any.whl", hash = "sha256:8487aab0195ce1c2a5ae189305118b9720daddbc7b688edb09ccd79e3b149f6b"}, - {file = "transformers-4.31.0.tar.gz", hash = "sha256:4302fba920a1c24d3a429a29efff6a63eac03f3f3cf55b55927fc795d01cb273"}, -] - -[package.dependencies] -filelock = "*" -huggingface-hub = ">=0.14.1,<1.0" -numpy = ">=1.17" -packaging = ">=20.0" -pyyaml = ">=5.1" -regex = "!=2019.12.17" -requests = "*" -safetensors = ">=0.3.1" -tokenizers = ">=0.11.1,<0.11.3 || >0.11.3,<0.14" -tqdm = ">=4.27" - -[package.extras] -accelerate = ["accelerate (>=0.20.3)"] -agents = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "datasets (!=2.5.0)", "diffusers", "opencv-python", "sentencepiece (>=0.1.91,!=0.1.92)", "torch (>=1.9,!=1.12.0)"] -all = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] -audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -codecarbon = ["codecarbon (==1.2.0)"] -deepspeed = ["accelerate (>=0.20.3)", "deepspeed (>=0.9.3)"] -deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"] -dev = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"] -dev-torch = ["GitPython (<3.1.19)", "Pillow (<10.0.0)", "accelerate (>=0.20.3)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0,<1.3.1)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -docs = ["Pillow (<10.0.0)", "accelerate (>=0.20.3)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.7.0)", "hf-doc-builder", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] -docs-specific = ["hf-doc-builder"] -fairscale = ["fairscale (>0.3)"] -flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.2.8,!=0.3.2,<=0.4.13)", "jaxlib (>=0.1.65,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)"] -flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -ftfy = ["ftfy"] -integrations = ["optuna", "ray[tune]", "sigopt"] -ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] -modelcreation = ["cookiecutter (==1.7.3)"] -natten = ["natten (>=0.14.6)"] -onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] -onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] -optuna = ["optuna"] -quality = ["GitPython (<3.1.19)", "black (>=23.1,<24.0)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (>=0.0.241,<=0.0.259)", "urllib3 (<2.0.0)"] -ray = ["ray[tune]"] -retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] -sagemaker = ["sagemaker (>=2.31.0)"] -sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] -serving = ["fastapi", "pydantic (<2)", "starlette", "uvicorn"] -sigopt = ["sigopt"] -sklearn = ["scikit-learn"] -speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -testing = ["GitPython (<3.1.19)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf", "psutil", "pytest (>=7.2.0)", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "timeout-decorator"] -tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx"] -tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.6,<2.14)", "tensorflow-text (<2.14)", "tf2onnx"] -tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -timm = ["timm"] -tokenizers = ["tokenizers (>=0.11.1,!=0.11.3,<0.14)"] -torch = ["accelerate (>=0.20.3)", "torch (>=1.9,!=1.12.0)"] -torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -torch-vision = ["Pillow (<10.0.0)", "torchvision"] -torchhub = ["filelock", "huggingface-hub (>=0.14.1,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"] -video = ["av (==9.2.0)", "decord (==0.6.0)"] -vision = ["Pillow (<10.0.0)"] - -[[package]] -name = "triton" -version = "2.0.0" -description = "A language and compiler for custom Deep Learning operations" -optional = false -python-versions = "*" -files = [ - {file = "triton-2.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38806ee9663f4b0f7cd64790e96c579374089e58f49aac4a6608121aa55e2505"}, - {file = "triton-2.0.0-1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:226941c7b8595219ddef59a1fdb821e8c744289a132415ddd584facedeb475b1"}, - {file = "triton-2.0.0-1-cp36-cp36m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4c9fc8c89874bc48eb7e7b2107a9b8d2c0bf139778637be5bfccb09191685cfd"}, - {file = "triton-2.0.0-1-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d2684b6a60b9f174f447f36f933e9a45f31db96cb723723ecd2dcfd1c57b778b"}, - {file = "triton-2.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9d4978298b74fcf59a75fe71e535c092b023088933b2f1df933ec32615e4beef"}, - {file = "triton-2.0.0-1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:74f118c12b437fb2ca25e1a04759173b517582fcf4c7be11913316c764213656"}, - {file = "triton-2.0.0-1-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9618815a8da1d9157514f08f855d9e9ff92e329cd81c0305003eb9ec25cc5add"}, - {file = "triton-2.0.0-1-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aca3303629cd3136375b82cb9921727f804e47ebee27b2677fef23005c3851a"}, - {file = "triton-2.0.0-1-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e3e13aa8b527c9b642e3a9defcc0fbd8ffbe1c80d8ac8c15a01692478dc64d8a"}, - {file = "triton-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f05a7e64e4ca0565535e3d5d3405d7e49f9d308505bb7773d21fb26a4c008c2"}, - {file = "triton-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4b99ca3c6844066e516658541d876c28a5f6e3a852286bbc97ad57134827fd"}, - {file = "triton-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47b4d70dc92fb40af553b4460492c31dc7d3a114a979ffb7a5cdedb7eb546c08"}, - {file = "triton-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fedce6a381901b1547e0e7e1f2546e4f65dca6d91e2d8a7305a2d1f5551895be"}, - {file = "triton-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75834f27926eab6c7f00ce73aaf1ab5bfb9bec6eb57ab7c0bfc0a23fac803b4c"}, - {file = "triton-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0117722f8c2b579cd429e0bee80f7731ae05f63fe8e9414acd9a679885fcbf42"}, - {file = "triton-2.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd9be5d0c2e45d2b7e6ddc6da20112b6862d69741576f9c3dbaf941d745ecae"}, - {file = "triton-2.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a0d2c3fc2eab4ba71384f2e785fbfd47aa41ae05fa58bf12cb31dcbd0aeceb"}, - {file = "triton-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c47b72c72693198163ece9d90a721299e4fb3b8e24fd13141e384ad952724f"}, -] - -[package.dependencies] -cmake = "*" -filelock = "*" -lit = "*" -torch = "*" - -[package.extras] -tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"] -tutorials = ["matplotlib", "pandas", "tabulate"] - -[[package]] -name = "tritonclient" -version = "2.28.0" -description = "Python client library and utilities for communicating with Triton Inference Server" -optional = false -python-versions = "*" -files = [ - {file = "tritonclient-2.28.0-py3-none-any.whl", hash = "sha256:1f58bbe09a88c35f7979de8ab6579a5337372951f723c0aba31e8bee3e8d79da"}, - {file = "tritonclient-2.28.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:47d93197a0876a743012db4c03f1100f7b225b9aaf8d5f8025bf4a5d9e61bfd2"}, -] - -[package.dependencies] -aiohttp = {version = ">=3.8.1", optional = true, markers = "extra == \"http\""} -geventhttpclient = {version = ">=1.4.4,<=2.0.2", optional = true, markers = "extra == \"http\""} -numpy = ">=1.19.1" -python-rapidjson = ">=0.9.1" - -[package.extras] -all = ["aiohttp (>=3.8.1)", "geventhttpclient (>=1.4.4,<=2.0.2)", "grpcio (==1.41.0)", "numpy (>=1.19.1)", "protobuf (>=3.5.0,<3.20)", "python-rapidjson (>=0.9.1)"] -grpc = ["grpcio (==1.41.0)", "numpy (>=1.19.1)", "protobuf (>=3.5.0,<3.20)", "python-rapidjson (>=0.9.1)"] -http = ["aiohttp (>=3.8.1)", "geventhttpclient (>=1.4.4,<=2.0.2)", "numpy (>=1.19.1)", "python-rapidjson (>=0.9.1)"] - -[[package]] -name = "trove-classifiers" -version = "2023.8.7" -description = "Canonical source for classifiers on PyPI (pypi.org)." -optional = false -python-versions = "*" -files = [ - {file = "trove-classifiers-2023.8.7.tar.gz", hash = "sha256:c9f2a0a85d545e5362e967e4f069f56fddfd91215e22ffa48c66fb283521319a"}, - {file = "trove_classifiers-2023.8.7-py3-none-any.whl", hash = "sha256:a676626a31286130d56de2ea1232484df97c567eb429d56cfcb0637e681ecf09"}, -] - [[package]] name = "types-atomicwrites" version = "1.4.5.1" @@ -9606,17 +3949,6 @@ files = [ {file = "types_pycurl-7.45.2.4-py3-none-any.whl", hash = "sha256:d10efc8b71bfcd2fc4745a2f08967baa441a8c74bc6028829e5b65899affc40b"}, ] -[[package]] -name = "types-python-dateutil" -version = "2.8.19.14" -description = "Typing stubs for python-dateutil" -optional = false -python-versions = "*" -files = [ - {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, - {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, -] - [[package]] name = "types-pyyaml" version = "6.0.12.11" @@ -9687,54 +4019,31 @@ files = [ ] [[package]] -name = "uri-template" -version = "1.3.0" -description = "RFC 6570 URI Template Processor" +name = "urllib3" +version = "2.0.4" +description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.7" files = [ - {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, - {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, ] [package.extras] -dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] - -[[package]] -name = "urllib3" -version = "1.26.16" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, - {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "utm" -version = "0.7.0" -description = "Bidirectional UTM-WGS84 converter for python" -optional = false -python-versions = "*" -files = [ - {file = "utm-0.7.0.tar.gz", hash = "sha256:3c9a3650e98bb6eecec535418d0dfd4db8f88c8ceaca112a0ff0787e116566e2"}, -] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.24.2" +version = "20.24.3" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.24.2-py3-none-any.whl", hash = "sha256:43a3052be36080548bdee0b42919c88072037d50d56c28bd3f853cbe92b953ff"}, - {file = "virtualenv-20.24.2.tar.gz", hash = "sha256:fd8a78f46f6b99a67b7ec5cf73f92357891a7b3a40fd97637c27f854aae3b9e0"}, + {file = "virtualenv-20.24.3-py3-none-any.whl", hash = "sha256:95a6e9398b4967fbcb5fef2acec5efaf9aa4972049d9ae41f95e0972a683fd02"}, + {file = "virtualenv-20.24.3.tar.gz", hash = "sha256:e5c3b4ce817b0b328af041506a2a299418c98747c4b1e68cb7527e74ced23efc"}, ] [package.dependencies] @@ -9746,54 +4055,6 @@ platformdirs = ">=3.9.1,<4" docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] -[[package]] -name = "virtualenv-clone" -version = "0.5.7" -description = "script to clone virtualenvs." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "virtualenv-clone-0.5.7.tar.gz", hash = "sha256:418ee935c36152f8f153c79824bb93eaf6f0f7984bae31d3f48f350b9183501a"}, - {file = "virtualenv_clone-0.5.7-py3-none-any.whl", hash = "sha256:44d5263bceed0bac3e1424d64f798095233b64def1c5689afa43dc3223caf5b0"}, -] - -[[package]] -name = "wcwidth" -version = "0.2.6" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = "*" -files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, -] - -[[package]] -name = "webcolors" -version = "1.13" -description = "A library for working with the color formats defined by HTML and CSS." -optional = false -python-versions = ">=3.7" -files = [ - {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, - {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, -] - -[package.extras] -docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] -tests = ["pytest", "pytest-cov"] - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - [[package]] name = "websocket-client" version = "1.6.1" @@ -9810,202 +4071,6 @@ docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] optional = ["python-socks", "wsaccel"] test = ["websockets"] -[[package]] -name = "werkzeug" -version = "2.3.6" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.8" -files = [ - {file = "Werkzeug-2.3.6-py3-none-any.whl", hash = "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890"}, - {file = "Werkzeug-2.3.6.tar.gz", hash = "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330"}, -] - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog (>=2.3)"] - -[[package]] -name = "widgetsnbextension" -version = "4.0.8" -description = "Jupyter interactive widgets for Jupyter Notebook" -optional = false -python-versions = ">=3.7" -files = [ - {file = "widgetsnbextension-4.0.8-py3-none-any.whl", hash = "sha256:2e37f0ce9da11651056280c7efe96f2db052fe8fc269508e3724f5cbd6c93018"}, - {file = "widgetsnbextension-4.0.8.tar.gz", hash = "sha256:9ec291ba87c2dfad42c3d5b6f68713fa18be1acd7476569516b2431682315c17"}, -] - -[[package]] -name = "wrapt" -version = "1.15.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, - {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, - {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, - {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, - {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, - {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, - {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, - {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, - {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, - {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, - {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, - {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, - {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, - {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, - {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, - {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, - {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, - {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, - {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, - {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, - {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, - {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, - {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, - {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, - {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, - {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, - {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, - {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, - {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, - {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, - {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, - {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, - {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, - {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, - {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, - {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, - {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, - {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, -] - -[[package]] -name = "xattr" -version = "0.10.1" -description = "Python wrapper for extended filesystem attributes" -optional = false -python-versions = "*" -files = [ - {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, - {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, - {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, - {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, -] - -[package.dependencies] -cffi = ">=1.0" - [[package]] name = "yarl" version = "1.9.2" @@ -10093,109 +4158,7 @@ files = [ idna = ">=2.0" multidict = ">=4.0" -[[package]] -name = "zerorpc" -version = "0.6.3" -description = "zerorpc is a flexible RPC based on zeromq." -optional = false -python-versions = "*" -files = [] -develop = false - -[package.dependencies] -future = "*" -gevent = ">=1.1" -msgpack = ">=0.5.2" -msgpack-numpy = ">=0.4.3" -pyzmq = ">=13.1.0" - -[package.source] -type = "git" -url = "https://github.com/commaai/zerorpc-python.git" -reference = "master" -resolved_reference = "0e27fd795bb9a7ec9cab81a771a2e35a91e397c9" - -[[package]] -name = "zipp" -version = "3.16.2" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] - -[[package]] -name = "zope-event" -version = "5.0" -description = "Very basic event publishing system" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26"}, - {file = "zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd"}, -] - -[package.dependencies] -setuptools = "*" - -[package.extras] -docs = ["Sphinx"] -test = ["zope.testrunner"] - -[[package]] -name = "zope-interface" -version = "6.0" -description = "Interfaces for Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zope.interface-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990"}, - {file = "zope.interface-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d"}, - {file = "zope.interface-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85"}, - {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995"}, - {file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f"}, - {file = "zope.interface-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410"}, - {file = "zope.interface-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28"}, - {file = "zope.interface-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52"}, - {file = "zope.interface-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30"}, - {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464"}, - {file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518"}, - {file = "zope.interface-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb"}, - {file = "zope.interface-6.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788"}, - {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca"}, - {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a"}, - {file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc"}, - {file = "zope.interface-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373"}, - {file = "zope.interface-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f"}, - {file = "zope.interface-6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8"}, - {file = "zope.interface-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58"}, - {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446"}, - {file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f"}, - {file = "zope.interface-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8"}, - {file = "zope.interface-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2"}, - {file = "zope.interface-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c"}, - {file = "zope.interface-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5"}, - {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8"}, - {file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2"}, - {file = "zope.interface-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5"}, - {file = "zope.interface-6.0.tar.gz", hash = "sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d"}, -] - -[package.dependencies] -setuptools = "*" - -[package.extras] -docs = ["Sphinx", "repoze.sphinx.autointerface"] -test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] -testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] - [metadata] lock-version = "2.0" python-versions = "~3.11" -content-hash = "083d63bfad18957e73451a6d6cc4d8ece4d404c47c08f74721bfe84aa7602286" +content-hash = "4b2510f1465520a9dc757f64861f4fcea9d9663c0ecdebd23b329ef5e0205863" diff --git a/pyproject.toml b/pyproject.toml index 74084cbc93..d9cc49bfd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ documentation = "https://docs.comma.ai" [tool.poetry.dependencies] python = "~3.11" -poetry = "~1.5.1" atomicwrites = "*" aiohttp = "*" aiortc = "*" @@ -26,19 +25,16 @@ cffi = "*" crcmod = "*" cryptography = "*" Cython = "*" -Flask = "*" future-fstrings = "*" # for acados -gunicorn = "*" hatanaka = "==2.4" hexdump = "*" Jinja2 = "*" json-rpc = "*" libusb1 = "*" -numpy = "==1.23.0" # locked pending deprecation fixes in xx +numpy = "*" onnx = ">=1.14.0" onnxruntime-gpu = { version = ">=1.15.1", platform = "linux", markers = "platform_machine == 'x86_64'" } pillow = "*" -protobuf = "==3.20.3" psutil = "*" pyaudio = "*" pycapnp = "*" @@ -47,12 +43,11 @@ pydub = "*" PyJWT = "*" pyopencl = "*" pyserial = "*" -python-dateutil = "*" PyYAML = "*" pyzmq = "*" requests = "*" scons = "*" -sentry-sdk = "~1.28" +sentry-sdk = "==1.28.1" # needs to be updated with AGNOS setproctitle = "*" smbus2 = "*" sounddevice = "*" @@ -62,7 +57,6 @@ sympy = "*" timezonefinder = "*" tqdm = "*" urllib3 = "*" -utm = "*" websocket_client = "*" polyline = "*" sconscontrib = {git = "https://github.com/SCons/scons-contrib.git"} @@ -73,26 +67,21 @@ av = "*" azure-storage-blob = "~2.1" breathe = "*" carla = { url = "https://github.com/commaai/carla/releases/download/3.11.4/carla-0.9.14-cp311-cp311-linux_x86_64.whl", platform = "linux", markers = "platform_machine == 'x86_64'" } -control = "*" coverage = "*" dictdiffer = "*" -fastcluster = "*" ft4222 = "*" -hexdump = "*" hypothesis = "==6.46.7" inputs = "*" lru-dict = "*" -lxml = "*" markdown-it-py = "*" matplotlib = "*" mpld3 = "*" mypy = "*" myst-parser = "*" natsort = "*" -opencv-python-headless = { url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu118-cp311/opencv_python_headless-4.5.5.64-cp311-cp311-manylinux_2_31_x86_64.whl", platform = "linux" } +opencv-python-headless = "*" pandas = "*" parameterized = "^0.8" -paramiko = "*" pprofile = "*" pre-commit = "*" pycurl = "*" @@ -100,8 +89,7 @@ pygame = "*" pyprof2calltree = "*" pytest = "*" pytest-xdist = "*" -reverse_geocoder = "*" -scipy = "==1.9.3" # pinned until xx refs changes can be checked +scipy = "*" sphinx = "*" sphinx-rtd-theme = "*" sphinx-sitemap = "*" @@ -110,85 +98,10 @@ tenacity = "*" types-atomicwrites = "*" types-certifi = "*" types-pycurl = "*" -types-python-dateutil = "*" types-PyYAML = "*" types-requests = "*" types-tabulate = "*" - - -[tool.poetry.group.xx] -optional = true - -[tool.poetry.group.xx.dependencies] -aenum = "*" -aiohttp = "*" -albumentations = "*" -azure-cli-core = "*" -azure-common = "*" -azure-core = "*" -azure-nspkg = "~3.0" -azure-storage-common = "~2.1" -azure-storage-nspkg = "~3.1" -blosc = "==1.9.2" -cloudpickle = "*" -configargparse = "*" -cupy-cuda11x = "*" -datadog = "*" -dotmap = "*" -einops = "*" -elasticsearch = "*" -flake8 = "*" -Flask-Cors = "*" -Flask-SocketIO = "*" -GeoAlchemy2 = "*" -imageio = "*" -influxdb-client = "*" -ipykernel = "*" -ipython = "*" -joblib = "*" -json-logging-py = "*" -jupyter = "*" -jupyterlab = "*" -jupyterlab-vim = "*" -Markdown = "*" -msgpack-python = "*" -networkx = "~2.8" -nvidia-ml-py3 = "*" -onnx2torch = "*" -onnxoptimizer = "*" -osmium = "*" -pillow-avif-plugin = "*" -pipenv = "==2022.10.12" -plotly = "*" -pycuda = "*" -Pygments = "*" -pylint = "*" -PyMySQL = "~0.9" -pyproj = "*" -python-logstash = "*" -redis = "*" -ruff = "*" -s2sphere = "*" -scikit-image = "*" -scikit-learn = "*" -segmentation-models-pytorch = "==0.3.3" -simplejson = "*" -SQLAlchemy = "*" -wrapt = "*" -torch = { url = "https://download.pytorch.org/whl/cu118/torch-2.0.1%2Bcu118-cp311-cp311-linux_x86_64.whl" } -torchsummary = "*" -torchvision = { url = "https://download.pytorch.org/whl/cu118/torchvision-0.15.2%2Bcu118-cp311-cp311-linux_x86_64.whl" } -triton = "*" -Werkzeug = "*" -zerorpc = { git = "https://github.com/commaai/zerorpc-python.git", branch = "master" } -omegaconf = "*" -osmnx = "==1.2.2" -tritonclient = {version = "2.28.0", extras = ["http"]} -transformers = "*" -timm = "==0.9.2" -PyNvCodec = { git = "https://github.com/NVIDIA/VideoProcessingFramework.git" } -apex = { url = "https://github.com/commaai/apex/releases/download/pytorch2.0.1%2Bcu11.8/apex-0.1-cp311-cp311-linux_x86_64.whl" } -opencv-python-headless = { url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu118-cp311/opencv_python_headless-4.5.5.64-cp311-cp311-manylinux_2_31_x86_64.whl", platform = "linux" } +pyqt5 = { version = "*", markers = "platform_machine == 'x86_64'" } # no aarch64 wheels for macOS/linux [build-system] @@ -197,8 +110,8 @@ build-backend = "poetry.core.masonry.api" # https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml [tool.ruff] -select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A"] -ignore = ["W292", "E741", "E402", "C408", "ISC003"] +select = ["E", "F", "W", "PIE", "C4", "ISC", "RUF100", "A", "B"] +ignore = ["W292", "E741", "E402", "C408", "ISC003", "B027", "B024"] line-length = 160 target-version="py311" exclude = [ diff --git a/release/files_common b/release/files_common index 223cab142e..bab298610b 100644 --- a/release/files_common +++ b/release/files_common @@ -418,8 +418,6 @@ selfdrive/assets/navigation/* third_party/.gitignore third_party/SConscript -third_party/cluster/* - third_party/linux/** third_party/opencl/** diff --git a/scripts/code_stats.py b/scripts/code_stats.py index 25e8950ccb..59b5724a68 100755 --- a/scripts/code_stats.py +++ b/scripts/code_stats.py @@ -8,7 +8,7 @@ fouts = {x.decode('utf-8') for x in subprocess.check_output(['git', 'ls-files']) pyf = [] for d in ["cereal", "common", "scripts", "selfdrive", "tools"]: - for root, dirs, files in os.walk(d): + for root, _, files in os.walk(d): for f in files: if f.endswith(".py"): pyf.append(os.path.join(root, f)) diff --git a/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png b/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png new file mode 100644 index 0000000000..37f1f83627 Binary files /dev/null and b/selfdrive/assets/navigation/direction_turn_slight_left_inactive.png differ diff --git a/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png b/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png new file mode 100644 index 0000000000..8be2245811 Binary files /dev/null and b/selfdrive/assets/navigation/direction_turn_slight_right_inactive.png differ diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index 6ef32f8a5b..d7ef064072 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -213,6 +213,16 @@ def retry_upload(tid: int, end_event: threading.Event, increase_count: bool = Tr break +def cb(sm, item, tid, sz: int, cur: int) -> None: + # Abort transfer if connection changed to metered after starting upload + sm.update(0) + metered = sm['deviceState'].networkMetered + if metered and (not item.allow_cellular): + raise AbortTransferException + + cur_upload_items[tid] = replace(item, progress=cur / sz if sz else 1) + + def upload_handler(end_event: threading.Event) -> None: sm = messaging.SubMaster(['deviceState']) tid = threading.get_ident() @@ -242,15 +252,6 @@ def upload_handler(end_event: threading.Event) -> None: continue try: - def cb(sz: int, cur: int) -> None: - # Abort transfer if connection changed to metered after starting upload - sm.update(0) - metered = sm['deviceState'].networkMetered - if metered and (not item.allow_cellular): - raise AbortTransferException - - cur_upload_items[tid] = replace(item, progress=cur / sz if sz else 1) - fn = item.path try: sz = os.path.getsize(fn) @@ -258,7 +259,7 @@ def upload_handler(end_event: threading.Event) -> None: sz = -1 cloudlog.event("athena.upload_handler.upload_start", fn=fn, sz=sz, network_type=network_type, metered=metered, retry_count=item.retry_count) - response = _do_upload(item, cb) + response = _do_upload(item, partial(cb, sm, item, tid)) if response.status_code not in (200, 201, 401, 403, 412): cloudlog.event("athena.upload_handler.retry", status_code=response.status_code, fn=fn, sz=sz, network_type=network_type, metered=metered) diff --git a/selfdrive/boardd/tests/test_boardd_loopback.py b/selfdrive/boardd/tests/test_boardd_loopback.py index 593ccf595f..74393c6eb1 100755 --- a/selfdrive/boardd/tests/test_boardd_loopback.py +++ b/selfdrive/boardd/tests/test_boardd_loopback.py @@ -10,7 +10,6 @@ from pprint import pprint import cereal.messaging as messaging from cereal import car, log from common.params import Params -from common.spinner import Spinner from common.timeout import Timeout from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import make_can_msg @@ -24,11 +23,6 @@ class TestBoardd(unittest.TestCase): def setUpClass(cls): os.environ['STARTED'] = '1' os.environ['BOARDD_LOOPBACK'] = '1' - cls.spinner = Spinner() - - @classmethod - def tearDownClass(cls): - cls.spinner.close() @phone_only @with_processes(['pandad']) @@ -67,7 +61,6 @@ class TestBoardd(unittest.TestCase): n = 200 for i in range(n): print(f"boardd loopback {i}/{n}") - self.spinner.update(f"boardd loopback {i}/{n}") sent_msgs = defaultdict(set) for _ in range(random.randrange(20, 100)): diff --git a/selfdrive/boardd/tests/test_boardd_usbprotocol.cc b/selfdrive/boardd/tests/test_boardd_usbprotocol.cc index 3b78eb7bd2..52cb11ec32 100644 --- a/selfdrive/boardd/tests/test_boardd_usbprotocol.cc +++ b/selfdrive/boardd/tests/test_boardd_usbprotocol.cc @@ -1,18 +1,11 @@ #define CATCH_CONFIG_MAIN #define CATCH_CONFIG_ENABLE_BENCHMARKING -#include #include "catch2/catch.hpp" #include "cereal/messaging/messaging.h" +#include "common/util.h" #include "selfdrive/boardd/panda.h" -int random_int(int min, int max) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(min, max); - return dist(rng); -} - struct PandaTest : public Panda { PandaTest(uint32_t bus_offset, int can_list_size, cereal::PandaState::PandaType hw_type); void test_can_send(); @@ -44,10 +37,10 @@ PandaTest::PandaTest(uint32_t bus_offset_, int can_list_size, cereal::PandaState auto can_list = msg.initEvent().initSendcan(can_list_size); for (uint8_t i = 0; i < can_list_size; ++i) { auto can = can_list[i]; - uint32_t id = random_int(0, std::size(dlc_to_len) - 1); + uint32_t id = util::random_int(0, std::size(dlc_to_len) - 1); const std::string &dat = test_data[dlc_to_len[id]]; can.setAddress(i); - can.setSrc(random_int(0, 3) + bus_offset); + can.setSrc(util::random_int(0, 3) + bus_offset); can.setDat(kj::ArrayPtr((uint8_t *)dat.data(), dat.size())); total_pakets_size += sizeof(can_header) + dat.size(); } diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index fdcbb98197..156161c796 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -40,9 +40,8 @@ def gen_empty_fingerprint(): return {i: {} for i in range(0, 8)} -# FIXME: hardcoding honda civic 2016 touring params so they can be used to -# scale unknown params for other cars -class CivicParams: +# these params were derived for the Civic and used to calculate params for other cars +class VehicleDynamicsParams: MASS = 1326. + STD_CARGO_KG WHEELBASE = 2.70 CENTER_TO_FRONT = WHEELBASE * 0.4 @@ -55,18 +54,18 @@ class CivicParams: # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase def scale_rot_inertia(mass, wheelbase): - return CivicParams.ROTATIONAL_INERTIA * mass * wheelbase ** 2 / (CivicParams.MASS * CivicParams.WHEELBASE ** 2) + return VehicleDynamicsParams.ROTATIONAL_INERTIA * mass * wheelbase ** 2 / (VehicleDynamicsParams.MASS * VehicleDynamicsParams.WHEELBASE ** 2) # TODO: start from empirically derived lateral slip stiffness for the civic and scale by # mass and CG position, so all cars will have approximately similar dyn behaviors -def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor=1.0): +def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor): center_to_rear = wheelbase - center_to_front - tire_stiffness_front = (CivicParams.TIRE_STIFFNESS_FRONT * tire_stiffness_factor) * mass / CivicParams.MASS * \ - (center_to_rear / wheelbase) / (CivicParams.CENTER_TO_REAR / CivicParams.WHEELBASE) + tire_stiffness_front = (VehicleDynamicsParams.TIRE_STIFFNESS_FRONT * tire_stiffness_factor) * mass / VehicleDynamicsParams.MASS * \ + (center_to_rear / wheelbase) / (VehicleDynamicsParams.CENTER_TO_REAR / VehicleDynamicsParams.WHEELBASE) - tire_stiffness_rear = (CivicParams.TIRE_STIFFNESS_REAR * tire_stiffness_factor) * mass / CivicParams.MASS * \ - (center_to_front / wheelbase) / (CivicParams.CENTER_TO_FRONT / CivicParams.WHEELBASE) + tire_stiffness_rear = (VehicleDynamicsParams.TIRE_STIFFNESS_REAR * tire_stiffness_factor) * mass / VehicleDynamicsParams.MASS * \ + (center_to_front / wheelbase) / (VehicleDynamicsParams.CENTER_TO_FRONT / VehicleDynamicsParams.WHEELBASE) return tire_stiffness_front, tire_stiffness_rear @@ -213,3 +212,24 @@ class CanBusBase: else: num = len(CP.safetyConfigs) self.offset = 4 * (num - 1) + + +class CanSignalRateCalculator: + """ + Calculates the instantaneous rate of a CAN signal by using the counter + variable and the known frequency of the CAN message that contains it. + """ + def __init__(self, frequency): + self.frequency = frequency + self.previous_counter = 0 + self.previous_value = 0 + self.rate = 0 + + def update(self, current_value, current_counter): + if current_counter != self.previous_counter: + self.rate = (current_value - self.previous_value) * self.frequency + + self.previous_counter = current_counter + self.previous_value = current_value + + return self.rate \ No newline at end of file diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 5bda64368b..652862de47 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,5 +1,5 @@ import os -from typing import Dict, List +from typing import Callable, Dict, List, Optional, Tuple from cereal import car from common.params import Params @@ -13,6 +13,8 @@ from system.swaglog import cloudlog import cereal.messaging as messaging from selfdrive.car import gen_empty_fingerprint +FRAME_FINGERPRINT = 100 # 1s + EventName = car.CarEvent.EventName @@ -75,6 +77,46 @@ interface_names = _get_interface_names() interfaces = load_interfaces(interface_names) +def can_fingerprint(next_can: Callable) -> Tuple[Optional[str], Dict[int, dict]]: + finger = gen_empty_fingerprint() + candidate_cars = {i: all_legacy_fingerprint_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1 + frame = 0 + car_fingerprint = None + done = False + + while not done: + a = next_can() + + for can in a.can: + # The fingerprint dict is generated for all buses, this way the car interface + # can use it to detect a (valid) multipanda setup and initialize accordingly + if can.src < 128: + if can.src not in finger: + finger[can.src] = {} + finger[can.src][can.address] = len(can.dat) + + for b in candidate_cars: + # Ignore extended messages and VIN query response. + if can.src == b and can.address < 0x800 and can.address not in (0x7df, 0x7e0, 0x7e8): + candidate_cars[b] = eliminate_incompatible_cars(can, candidate_cars[b]) + + # if we only have one car choice and the time since we got our first + # message has elapsed, exit + for b in candidate_cars: + if len(candidate_cars[b]) == 1 and frame > FRAME_FINGERPRINT: + # fingerprint done + car_fingerprint = candidate_cars[b][0] + + # bail if no cars left or we've been waiting for more than 2s + failed = (all(len(cc) == 0 for cc in candidate_cars.values()) and frame > FRAME_FINGERPRINT) or frame > 200 + succeeded = car_fingerprint is not None + done = failed or succeeded + + frame += 1 + + return car_fingerprint, finger + + # **** for use live only **** def fingerprint(logcan, sendcan, num_pandas): fixed_fingerprint = os.environ.get('FINGERPRINT', "") @@ -123,45 +165,10 @@ def fingerprint(logcan, sendcan, num_pandas): set_obd_multiplexing(params, False) params.put_bool("FirmwareQueryDone", True) - finger = gen_empty_fingerprint() - candidate_cars = {i: all_legacy_fingerprint_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1 - frame = 0 - frame_fingerprint = 100 # 1s - car_fingerprint = None - done = False - - # drain CAN socket so we always get the latest messages + # CAN fingerprint + # drain CAN socket so we get the latest messages messaging.drain_sock_raw(logcan) - - while not done: - a = get_one_can(logcan) - - for can in a.can: - # The fingerprint dict is generated for all buses, this way the car interface - # can use it to detect a (valid) multipanda setup and initialize accordingly - if can.src < 128: - if can.src not in finger: - finger[can.src] = {} - finger[can.src][can.address] = len(can.dat) - - for b in candidate_cars: - # Ignore extended messages and VIN query response. - if can.src == b and can.address < 0x800 and can.address not in (0x7df, 0x7e0, 0x7e8): - candidate_cars[b] = eliminate_incompatible_cars(can, candidate_cars[b]) - - # if we only have one car choice and the time since we got our first - # message has elapsed, exit - for b in candidate_cars: - if len(candidate_cars[b]) == 1 and frame > frame_fingerprint: - # fingerprint done - car_fingerprint = candidate_cars[b][0] - - # bail if no cars left or we've been waiting for more than 2s - failed = (all(len(cc) == 0 for cc in candidate_cars.values()) and frame > frame_fingerprint) or frame > 200 - succeeded = car_fingerprint is not None - done = failed or succeeded - - frame += 1 + car_fingerprint, finger = can_fingerprint(lambda: get_one_can(logcan)) exact_match = True source = car.CarParams.FingerprintSource.can diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 22b2073883..a3c0b0c7a1 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from cereal import car from panda import Panda -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags from selfdrive.car.interfaces import CarInterfaceBase @@ -35,7 +35,7 @@ class CarInterface(CarInterfaceBase): # Chrysler if candidate in (CAR.PACIFICA_2017_HYBRID, CAR.PACIFICA_2018, CAR.PACIFICA_2018_HYBRID, CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020): - ret.mass = 2242. + STD_CARGO_KG + ret.mass = 2242. ret.wheelbase = 3.089 ret.steerRatio = 16.2 # Pacifica Hybrid 2017 @@ -46,7 +46,7 @@ class CarInterface(CarInterfaceBase): # Jeep elif candidate in (CAR.JEEP_CHEROKEE, CAR.JEEP_CHEROKEE_2019): - ret.mass = 1778 + STD_CARGO_KG + ret.mass = 1778 ret.wheelbase = 2.71 ret.steerRatio = 16.7 ret.steerActuatorDelay = 0.2 @@ -61,7 +61,7 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 ret.wheelbase = 3.88 ret.steerRatio = 16.3 - ret.mass = 2493. + STD_CARGO_KG + ret.mass = 2493. ret.minSteerSpeed = 14.5 # Older EPS FW allow steer to zero if any(fw.ecu == 'eps' and fw.fwVersion[:4] <= b"6831" for fw in car_fw): @@ -71,7 +71,7 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 ret.wheelbase = 3.785 ret.steerRatio = 15.61 - ret.mass = 3405. + STD_CARGO_KG + ret.mass = 3405. ret.minSteerSpeed = 16 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, 1.0, False) diff --git a/selfdrive/car/chrysler/radar_interface.py b/selfdrive/car/chrysler/radar_interface.py index 380b95775e..fc795a36ca 100755 --- a/selfdrive/car/chrysler/radar_interface.py +++ b/selfdrive/car/chrysler/radar_interface.py @@ -25,7 +25,7 @@ def _create_radar_can_parser(car_fingerprint): messages = list(zip(RADAR_MSGS_C + RADAR_MSGS_D, [20] * msg_n + # 20Hz (0.05s) - [20] * msg_n)) # 20Hz (0.05s) + [20] * msg_n, strict=True)) # 20Hz (0.05s) return CANParser(DBC[car_fingerprint]['radar'], messages, 1) @@ -46,7 +46,7 @@ class RadarInterface(RadarInterfaceBase): def update(self, can_strings): if self.rcp is None or self.CP.radarUnavailable: - return super().update(None) + return None vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) diff --git a/selfdrive/car/ecu_addrs.py b/selfdrive/car/ecu_addrs.py index 868f12cdb8..25938f0d3c 100755 --- a/selfdrive/car/ecu_addrs.py +++ b/selfdrive/car/ecu_addrs.py @@ -1,16 +1,15 @@ #!/usr/bin/env python3 import capnp import time -from typing import Optional, Set, Tuple +from typing import Optional, Set import cereal.messaging as messaging from panda.python.uds import SERVICE_TYPE from selfdrive.car import make_can_msg +from selfdrive.car.fw_query_definitions import EcuAddrBusType from selfdrive.boardd.boardd import can_list_to_can_capnp from system.swaglog import cloudlog -EcuAddrBusType = Tuple[int, Optional[int], int] - def make_tester_present_msg(addr, bus, subaddr=None): dat = [0x02, SERVICE_TYPE.TESTER_PRESENT, 0x0] @@ -90,7 +89,7 @@ if __name__ == "__main__": print() print("Found ECUs on addresses:") - for addr, subaddr, bus in ecu_addrs: + for addr, subaddr, _ in ecu_addrs: msg = f" 0x{hex(addr)}" if subaddr is not None: msg += f" (sub-address: {hex(subaddr)})" diff --git a/selfdrive/car/fingerprints.py b/selfdrive/car/fingerprints.py index 1a9bb8c4e7..09ed30cc19 100644 --- a/selfdrive/car/fingerprints.py +++ b/selfdrive/car/fingerprints.py @@ -29,9 +29,8 @@ def eliminate_incompatible_cars(msg, candidate_cars): car_fingerprints = _FINGERPRINTS[car_name] for fingerprint in car_fingerprints: - fingerprint.update(_DEBUG_ADDRESS) # add alien debug address - - if is_valid_for_fingerprint(msg, fingerprint): + # add alien debug address + if is_valid_for_fingerprint(msg, fingerprint | _DEBUG_ADDRESS): compatible_cars.append(car_name) break diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index d74baa3ce4..990d14de93 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.ford.fordcan import CanBus from selfdrive.car.ford.values import CANFD_CAR, CAR, Ecu from selfdrive.car.interfaces import CarInterfaceBase @@ -39,33 +39,33 @@ class CarInterface(CarInterfaceBase): if candidate == CAR.BRONCO_SPORT_MK1: ret.wheelbase = 2.67 ret.steerRatio = 17.7 - ret.mass = 1625 + STD_CARGO_KG + ret.mass = 1625 elif candidate == CAR.ESCAPE_MK4: ret.wheelbase = 2.71 ret.steerRatio = 16.7 - ret.mass = 1750 + STD_CARGO_KG + ret.mass = 1750 elif candidate == CAR.EXPLORER_MK6: ret.wheelbase = 3.025 ret.steerRatio = 16.8 - ret.mass = 2050 + STD_CARGO_KG + ret.mass = 2050 elif candidate == CAR.F_150_MK14: # required trim only on SuperCrew ret.wheelbase = 3.69 ret.steerRatio = 17.0 - ret.mass = 2000 + STD_CARGO_KG + ret.mass = 2000 elif candidate == CAR.FOCUS_MK4: ret.wheelbase = 2.7 ret.steerRatio = 15.0 - ret.mass = 1350 + STD_CARGO_KG + ret.mass = 1350 elif candidate == CAR.MAVERICK_MK1: ret.wheelbase = 3.076 ret.steerRatio = 17.0 - ret.mass = 1650 + STD_CARGO_KG + ret.mass = 1650 else: raise ValueError(f"Unsupported car: {candidate}") diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index bf074ce8c8..39a62b9e43 100644 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -15,7 +15,7 @@ DELPHI_MRR_RADAR_MSG_COUNT = 64 def _create_delphi_esr_radar_can_parser(CP) -> CANParser: msg_n = len(DELPHI_ESR_RADAR_MSGS) - messages = list(zip(DELPHI_ESR_RADAR_MSGS, [20] * msg_n)) + messages = list(zip(DELPHI_ESR_RADAR_MSGS, [20] * msg_n, strict=True)) return CANParser(RADAR.DELPHI_ESR, messages, CanBus(CP).radar) @@ -51,7 +51,7 @@ class RadarInterface(RadarInterfaceBase): def update(self, can_strings): if self.rcp is None: - return super().update(None) + return None vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index eb4b7cca9a..01d1ae7b8a 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -156,6 +156,7 @@ FW_VERSIONS = { b'LX6C-2D053-NT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6C-2D053-NY\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6C-2D053-SA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LX6C-2D053-SD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'LB5T-14D049-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -163,11 +164,13 @@ FW_VERSIONS = { (Ecu.fwdCamera, 0x706, None): [ b'LJ6T-14F397-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LJ6T-14F397-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LV4T-14F397-GG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x7E0, None): [ b'LX6A-14C204-BJV\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6A-14C204-BJX\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6A-14C204-CNG\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LX6A-14C204-DPK\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6A-14C204-ESG\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'MX6A-14C204-BEF\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'MX6A-14C204-BEJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -201,6 +204,7 @@ FW_VERSIONS = { ], (Ecu.engine, 0x7E0, None): [ b'LB5A-14C204-ATJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LB5A-14C204-AUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LB5A-14C204-AZL\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LB5A-14C204-BUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LB5A-14C204-EAC\x00\x00\x00\x00\x00\x00\x00\x00\x00', diff --git a/selfdrive/car/fw_query_definitions.py b/selfdrive/car/fw_query_definitions.py index f9f8e30a68..1caedcd321 100755 --- a/selfdrive/car/fw_query_definitions.py +++ b/selfdrive/car/fw_query_definitions.py @@ -7,6 +7,9 @@ from typing import Callable, Dict, List, Optional, Set, Tuple import panda.python.uds as uds +AddrType = Tuple[int, Optional[int]] +EcuAddrBusType = Tuple[int, Optional[int], int] + def p16(val): return struct.pack("!H", val) @@ -76,7 +79,7 @@ class FwQueryConfig: extra_ecus: List[Tuple[capnp.lib.capnp._EnumModule, int, Optional[int]]] = field(default_factory=list) # Function a brand can implement to provide better fuzzy matching. Takes in FW versions, # returns set of candidates. Only will match if one candidate is returned - match_fw_to_car_fuzzy: Optional[Callable[[Dict[Tuple[int, Optional[int]], Set[bytes]]], Set[str]]] = None + match_fw_to_car_fuzzy: Optional[Callable[[Dict[AddrType, Set[bytes]]], Set[str]]] = None def __post_init__(self): for i in range(len(self.requests)): diff --git a/selfdrive/car/fw_versions.py b/selfdrive/car/fw_versions.py index 038c2e0869..7fa47da998 100755 --- a/selfdrive/car/fw_versions.py +++ b/selfdrive/car/fw_versions.py @@ -1,13 +1,14 @@ #!/usr/bin/env python3 from collections import defaultdict -from typing import Any, DefaultDict, Dict, List, Optional, Set, Tuple +from typing import Any, DefaultDict, Dict, List, Optional, Set from tqdm import tqdm import capnp import panda.python.uds as uds from cereal import car from common.params import Params -from selfdrive.car.ecu_addrs import EcuAddrBusType, get_ecu_addrs +from selfdrive.car.ecu_addrs import get_ecu_addrs +from selfdrive.car.fw_query_definitions import AddrType, EcuAddrBusType from selfdrive.car.interfaces import get_interface_attr from selfdrive.car.fingerprints import FW_VERSIONS from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery @@ -35,8 +36,8 @@ def is_brand(brand: str, filter_brand: Optional[str]) -> bool: def build_fw_dict(fw_versions: List[capnp.lib.capnp._DynamicStructBuilder], - filter_brand: Optional[str] = None) -> Dict[Tuple[int, Optional[int]], Set[bytes]]: - fw_versions_dict = defaultdict(set) + filter_brand: Optional[str] = None) -> Dict[AddrType, Set[bytes]]: + fw_versions_dict: DefaultDict[AddrType, Set[bytes]] = defaultdict(set) for fw in fw_versions: if is_brand(fw.brand, filter_brand) and not fw.logging: sub_addr = fw.subAddress if fw.subAddress != 0 else None @@ -44,8 +45,8 @@ def build_fw_dict(fw_versions: List[capnp.lib.capnp._DynamicStructBuilder], return dict(fw_versions_dict) -def get_brand_addrs() -> Dict[str, Set[Tuple[int, Optional[int]]]]: - brand_addrs: DefaultDict[str, Set[Tuple[int, Optional[int]]]] = defaultdict(set) +def get_brand_addrs() -> Dict[str, Set[AddrType]]: + brand_addrs: DefaultDict[str, Set[AddrType]] = defaultdict(set) for brand, cars in VERSIONS.items(): # Add ecus in database + extra ecus to match against brand_addrs[brand] |= {(addr, sub_addr) for _, addr, sub_addr in FW_QUERY_CONFIGS[brand].extra_ecus} @@ -54,7 +55,7 @@ def get_brand_addrs() -> Dict[str, Set[Tuple[int, Optional[int]]]]: return dict(brand_addrs) -def match_fw_to_car_fuzzy(live_fw_versions, log=True, exclude=None): +def match_fw_to_car_fuzzy(live_fw_versions, match_brand=None, log=True, exclude=None): """Do a fuzzy FW match. This function will return a match, and the number of firmware version that were matched uniquely to that specific car. If multiple ECUs uniquely match to different cars the match is rejected.""" @@ -62,6 +63,9 @@ def match_fw_to_car_fuzzy(live_fw_versions, log=True, exclude=None): # Build lookup table from (addr, sub_addr, fw) to list of candidate cars all_fw_versions = defaultdict(list) for candidate, fw_by_addr in FW_VERSIONS.items(): + if not is_brand(MODEL_TO_BRAND[candidate], match_brand): + continue + if candidate == exclude: continue @@ -101,13 +105,14 @@ def match_fw_to_car_fuzzy(live_fw_versions, log=True, exclude=None): return set() -def match_fw_to_car_exact(live_fw_versions, log=True) -> Set[str]: +def match_fw_to_car_exact(live_fw_versions, match_brand=None, log=True) -> Set[str]: """Do an exact FW match. Returns all cars that match the given FW versions for a list of "essential" ECUs. If an ECU is not considered essential the FW version can be missing to get a fingerprint, but if it's present it needs to match the database.""" invalid = set() - candidates = FW_VERSIONS + candidates = {c: f for c, f in FW_VERSIONS.items() if + is_brand(MODEL_TO_BRAND[c], match_brand)} for candidate, fws in candidates.items(): config = FW_QUERY_CONFIGS[MODEL_TO_BRAND[candidate]] @@ -149,7 +154,7 @@ def match_fw_to_car(fw_versions, allow_exact=True, allow_fuzzy=True, log=True): matches = set() for brand in VERSIONS.keys(): fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand) - matches |= match_func(fw_versions_dict, log=log) + matches |= match_func(fw_versions_dict, match_brand=brand, log=log) # If specified and no matches so far, fall back to brand's fuzzy fingerprinting function config = FW_QUERY_CONFIGS[brand] diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index e17346cfaf..8e139947a6 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -4,7 +4,7 @@ from math import fabs, exp from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config +from selfdrive.car import create_button_event, get_safety_config from selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus from selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD @@ -128,17 +128,17 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 ret.steerActuatorDelay = 0.1 # Default delay, not measured yet - tire_stiffness_factor = 0.444 # not optimized yet + ret.tireStiffnessFactor = 0.444 # not optimized yet ret.steerLimitTimer = 0.4 ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz ret.longitudinalActuatorDelayUpperBound = 0.5 # large delay to initially start braking if candidate == CAR.VOLT: - ret.mass = 1607. + STD_CARGO_KG + ret.mass = 1607. ret.wheelbase = 2.69 ret.steerRatio = 17.7 # Stock 15.7, LiveParameters - tire_stiffness_factor = 0.469 # Stock Michelin Energy Saver A/S, LiveParameters + ret.tireStiffnessFactor = 0.469 # Stock Michelin Energy Saver A/S, LiveParameters ret.centerToFront = ret.wheelbase * 0.45 # Volt Gen 1, TODO corner weigh ret.lateralTuning.pid.kpBP = [0., 40.] @@ -149,13 +149,13 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 elif candidate == CAR.MALIBU: - ret.mass = 1496. + STD_CARGO_KG + ret.mass = 1496. ret.wheelbase = 2.83 ret.steerRatio = 15.8 ret.centerToFront = ret.wheelbase * 0.4 # wild guess elif candidate == CAR.HOLDEN_ASTRA: - ret.mass = 1363. + STD_CARGO_KG + ret.mass = 1363. ret.wheelbase = 2.662 # Remaining parameters copied from Volt for now ret.centerToFront = ret.wheelbase * 0.4 @@ -163,7 +163,7 @@ class CarInterface(CarInterfaceBase): elif candidate == CAR.ACADIA: ret.minEnableSpeed = -1. # engage speed is decided by pcm - ret.mass = 4353. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 4353. * CV.LB_TO_KG ret.wheelbase = 2.86 ret.steerRatio = 14.4 # end to end is 13.46 ret.centerToFront = ret.wheelbase * 0.4 @@ -171,27 +171,27 @@ class CarInterface(CarInterfaceBase): CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.BUICK_LACROSSE: - ret.mass = 1712. + STD_CARGO_KG + ret.mass = 1712. ret.wheelbase = 2.91 ret.steerRatio = 15.8 ret.centerToFront = ret.wheelbase * 0.4 # wild guess CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.BUICK_REGAL: - ret.mass = 3779. * CV.LB_TO_KG + STD_CARGO_KG # (3849+3708)/2 + ret.mass = 3779. * CV.LB_TO_KG # (3849+3708)/2 ret.wheelbase = 2.83 # 111.4 inches in meters ret.steerRatio = 14.4 # guess for tourx ret.centerToFront = ret.wheelbase * 0.4 # guess for tourx elif candidate == CAR.CADILLAC_ATS: - ret.mass = 1601. + STD_CARGO_KG + ret.mass = 1601. ret.wheelbase = 2.78 ret.steerRatio = 15.3 ret.centerToFront = ret.wheelbase * 0.5 elif candidate == CAR.ESCALADE: ret.minEnableSpeed = -1. # engage speed is decided by pcm - ret.mass = 5653. * CV.LB_TO_KG + STD_CARGO_KG # (5552+5815)/2 + ret.mass = 5653. * CV.LB_TO_KG # (5552+5815)/2 ret.wheelbase = 2.95 # 116 inches in meters ret.steerRatio = 17.3 ret.centerToFront = ret.wheelbase * 0.5 @@ -199,30 +199,30 @@ class CarInterface(CarInterfaceBase): elif candidate == CAR.ESCALADE_ESV: ret.minEnableSpeed = -1. # engage speed is decided by pcm - ret.mass = 2739. + STD_CARGO_KG + ret.mass = 2739. ret.wheelbase = 3.302 ret.steerRatio = 17.3 ret.centerToFront = ret.wheelbase * 0.5 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[10., 41.0], [10., 41.0]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.13, 0.24], [0.01, 0.02]] ret.lateralTuning.pid.kf = 0.000045 - tire_stiffness_factor = 1.0 + ret.tireStiffnessFactor = 1.0 elif candidate == CAR.BOLT_EUV: - ret.mass = 1669. + STD_CARGO_KG + ret.mass = 1669. ret.wheelbase = 2.63779 ret.steerRatio = 16.8 ret.centerToFront = ret.wheelbase * 0.4 - tire_stiffness_factor = 1.0 + ret.tireStiffnessFactor = 1.0 ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.SILVERADO: - ret.mass = 2200. + STD_CARGO_KG + ret.mass = 2450. ret.wheelbase = 3.75 ret.steerRatio = 16.3 ret.centerToFront = ret.wheelbase * 0.5 - tire_stiffness_factor = 1.0 + ret.tireStiffnessFactor = 1.0 # On the Bolt, the ECM and camera independently check that you are either above 5 kph or at a stop # with foot on brake to allow engagement, but this platform only has that check in the camera. # TODO: check if this is split by EV/ICE with more platforms in the future @@ -231,26 +231,21 @@ class CarInterface(CarInterfaceBase): CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.EQUINOX: - ret.mass = 3500. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3500. * CV.LB_TO_KG ret.wheelbase = 2.72 ret.steerRatio = 14.4 ret.centerToFront = ret.wheelbase * 0.4 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.TRAILBLAZER: - ret.mass = 1345. + STD_CARGO_KG + ret.mass = 1345. ret.wheelbase = 2.64 ret.steerRatio = 16.8 ret.centerToFront = ret.wheelbase * 0.4 - tire_stiffness_factor = 1.0 + ret.tireStiffnessFactor = 1.0 ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, - tire_stiffness_factor=tire_stiffness_factor) - return ret # returns a car.CarState diff --git a/selfdrive/car/gm/radar_interface.py b/selfdrive/car/gm/radar_interface.py index 5995a08a10..0424b95a77 100755 --- a/selfdrive/car/gm/radar_interface.py +++ b/selfdrive/car/gm/radar_interface.py @@ -25,7 +25,7 @@ def create_radar_can_parser(car_fingerprint): ['TrkRange'] * NUM_SLOTS + ['TrkRangeRate'] * NUM_SLOTS + ['TrkRangeAccel'] * NUM_SLOTS + ['TrkAzimuth'] * NUM_SLOTS + ['TrkWidth'] * NUM_SLOTS + ['TrkObjectID'] * NUM_SLOTS, - [RADAR_HEADER_MSG] * 7 + radar_targets * 6)) + [RADAR_HEADER_MSG] * 7 + radar_targets * 6, strict=True)) messages = list({(s[1], 14) for s in signals}) @@ -44,7 +44,7 @@ class RadarInterface(RadarInterfaceBase): def update(self, can_strings): if self.rcp is None: - return super().update(None) + return None vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 3907f1c17e..cfe518650a 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -212,10 +212,10 @@ FINGERPRINTS = { }], # Trailblazer also matches as a Silverado, so comment out to avoid conflicts. # TODO: split with FW versions - CAR.TRAILBLAZER: [ - { + # CAR.TRAILBLAZER: [ + # { # 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1609: 8, 1611: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1930: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8 - }], + # }], } GM_RX_OFFSET = 0x400 diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 29c6fa0327..1025eb6212 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -5,7 +5,7 @@ from common.conversions import Conversions as CV from common.numpy_fast import interp from selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, \ HONDA_BOSCH_ALT_BRAKE_SIGNAL, HONDA_BOSCH_RADARLESS -from selfdrive.car import STD_CARGO_KG, CivicParams, create_button_event, scale_tire_stiffness, get_safety_config +from selfdrive.car import create_button_event, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu @@ -89,9 +89,9 @@ class CarInterface(CarInterfaceBase): eps_modified = True if candidate == CAR.CIVIC: - ret.mass = CivicParams.MASS - ret.wheelbase = CivicParams.WHEELBASE - ret.centerToFront = CivicParams.CENTER_TO_FRONT + ret.mass = 1326. + ret.wheelbase = 2.70 + ret.centerToFront = ret.wheelbase * 0.4 ret.steerRatio = 15.38 # 10.93 is end-to-end spec if eps_modified: # stock request input values: 0x0000, 0x00DE, 0x014D, 0x01EF, 0x0290, 0x0377, 0x0454, 0x0610, 0x06EE @@ -105,24 +105,22 @@ class CarInterface(CarInterfaceBase): else: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2560], [0, 2560]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[1.1], [0.33]] - tire_stiffness_factor = 1. elif candidate in (CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CIVIC_2022): - ret.mass = CivicParams.MASS - ret.wheelbase = CivicParams.WHEELBASE - ret.centerToFront = CivicParams.CENTER_TO_FRONT + ret.mass = 1326. + ret.wheelbase = 2.70 + ret.centerToFront = ret.wheelbase * 0.4 ret.steerRatio = 15.38 # 10.93 is end-to-end spec ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 1. ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate in (CAR.ACCORD, CAR.ACCORDH): - ret.mass = 3279. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3279. * CV.LB_TO_KG ret.wheelbase = 2.83 ret.centerToFront = ret.wheelbase * 0.39 ret.steerRatio = 16.33 # 11.82 is spec end-to-end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.8467 + ret.tireStiffnessFactor = 0.8467 if eps_modified: ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.09]] @@ -130,26 +128,26 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] elif candidate == CAR.ACURA_ILX: - ret.mass = 3095. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3095. * CV.LB_TO_KG ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.37 ret.steerRatio = 18.61 # 15.3 is spec end-to-end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.72 + ret.tireStiffnessFactor = 0.72 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate in (CAR.CRV, CAR.CRV_EU): - ret.mass = 3572. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3572. * CV.LB_TO_KG ret.wheelbase = 2.62 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 16.89 # as spec ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.444 + ret.tireStiffnessFactor = 0.444 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] ret.wheelSpeedFactor = 1.025 elif candidate == CAR.CRV_5G: - ret.mass = 3410. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3410. * CV.LB_TO_KG ret.wheelbase = 2.66 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 16.0 # 12.3 is spec end-to-end @@ -162,45 +160,45 @@ class CarInterface(CarInterfaceBase): else: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.64], [0.192]] - tire_stiffness_factor = 0.677 + ret.tireStiffnessFactor = 0.677 ret.wheelSpeedFactor = 1.025 elif candidate == CAR.CRV_HYBRID: - ret.mass = 1667. + STD_CARGO_KG # mean of 4 models in kg + ret.mass = 1667. # mean of 4 models in kg ret.wheelbase = 2.66 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 16.0 # 12.3 is spec end-to-end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.677 + ret.tireStiffnessFactor = 0.677 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] ret.wheelSpeedFactor = 1.025 elif candidate == CAR.FIT: - ret.mass = 2644. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 2644. * CV.LB_TO_KG ret.wheelbase = 2.53 ret.centerToFront = ret.wheelbase * 0.39 ret.steerRatio = 13.06 ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.75 + ret.tireStiffnessFactor = 0.75 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] elif candidate == CAR.FREED: - ret.mass = 3086. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3086. * CV.LB_TO_KG ret.wheelbase = 2.74 # the remaining parameters were copied from FIT ret.centerToFront = ret.wheelbase * 0.39 ret.steerRatio = 13.06 ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] - tire_stiffness_factor = 0.75 + ret.tireStiffnessFactor = 0.75 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] elif candidate in (CAR.HRV, CAR.HRV_3G): - ret.mass = 3125 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3125 * CV.LB_TO_KG ret.wheelbase = 2.61 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 15.2 ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 if candidate == CAR.HRV: ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.025]] ret.wheelSpeedFactor = 1.025 @@ -208,29 +206,29 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] # TODO: can probably use some tuning elif candidate == CAR.ACURA_RDX: - ret.mass = 3935. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3935. * CV.LB_TO_KG ret.wheelbase = 2.68 ret.centerToFront = ret.wheelbase * 0.38 ret.steerRatio = 15.0 # as spec - tire_stiffness_factor = 0.444 + ret.tireStiffnessFactor = 0.444 ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] elif candidate == CAR.ACURA_RDX_3G: - ret.mass = 4068. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 4068. * CV.LB_TO_KG ret.wheelbase = 2.75 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 11.95 # as spec ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.06]] - tire_stiffness_factor = 0.677 + ret.tireStiffnessFactor = 0.677 elif candidate in (CAR.ODYSSEY, CAR.ODYSSEY_CHN): - ret.mass = 1900. + STD_CARGO_KG + ret.mass = 1900. ret.wheelbase = 3.00 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 14.35 # as spec - tire_stiffness_factor = 0.82 + ret.tireStiffnessFactor = 0.82 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]] if candidate == CAR.ODYSSEY_CHN: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 32767], [0, 32767]] # TODO: determine if there is a dead zone at the top end @@ -238,39 +236,39 @@ class CarInterface(CarInterfaceBase): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end elif candidate == CAR.PILOT: - ret.mass = 4278. * CV.LB_TO_KG + STD_CARGO_KG # average weight + ret.mass = 4278. * CV.LB_TO_KG # average weight ret.wheelbase = 2.86 ret.centerToFront = ret.wheelbase * 0.428 ret.steerRatio = 16.0 # as spec ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.444 + ret.tireStiffnessFactor = 0.444 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] elif candidate == CAR.RIDGELINE: - ret.mass = 4515. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 4515. * CV.LB_TO_KG ret.wheelbase = 3.18 ret.centerToFront = ret.wheelbase * 0.41 ret.steerRatio = 15.59 # as spec ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.444 + ret.tireStiffnessFactor = 0.444 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] elif candidate == CAR.INSIGHT: - ret.mass = 2987. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 2987. * CV.LB_TO_KG ret.wheelbase = 2.7 ret.centerToFront = ret.wheelbase * 0.39 ret.steerRatio = 15.0 # 12.58 is spec end-to-end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.82 + ret.tireStiffnessFactor = 0.82 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] elif candidate == CAR.HONDA_E: - ret.mass = 3338.8 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3338.8 * CV.LB_TO_KG ret.wheelbase = 2.5 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 16.71 ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - tire_stiffness_factor = 0.82 + ret.tireStiffnessFactor = 0.82 ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] # TODO: can probably use some tuning else: @@ -296,11 +294,6 @@ class CarInterface(CarInterfaceBase): ret.autoResumeSng = candidate in (HONDA_BOSCH | {CAR.CIVIC}) or ret.enableGasInterceptor ret.minEnableSpeed = -1. if ret.autoResumeSng else 25.5 * CV.MPH_TO_MS - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, - tire_stiffness_factor=tire_stiffness_factor) - ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.8 diff --git a/selfdrive/car/honda/radar_interface.py b/selfdrive/car/honda/radar_interface.py index 58f665233b..43fe422026 100755 --- a/selfdrive/car/honda/radar_interface.py +++ b/selfdrive/car/honda/radar_interface.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +from collections import defaultdict + from cereal import car from opendbc.can.parser import CANParser from selfdrive.car.interfaces import RadarInterfaceBase @@ -28,50 +30,61 @@ class RadarInterface(RadarInterfaceBase): else: self.rcp = _create_nidec_can_parser(CP.carFingerprint) self.trigger_msg = 0x445 - self.updated_messages = set() + self.updated_values = defaultdict(lambda: defaultdict(list)) def update(self, can_strings): # in Bosch radar and we are only steering for now, so sleep 0.05s to keep # radard at 20Hz and return no points if self.radar_off_can: - return super().update(None) - - vls = self.rcp.update_strings(can_strings) - self.updated_messages.update(vls) - - if self.trigger_msg not in self.updated_messages: return None - rr = self._update(self.updated_messages) - self.updated_messages.clear() - return rr + addresses = self.rcp.update_strings(can_strings) + for addr in addresses: + vals_dict = self.rcp.vl_all[addr] + for sig_name, vals in vals_dict.items(): + self.updated_values[addr][sig_name].extend(vals) - def _update(self, updated_messages): + if self.trigger_msg not in self.updated_values: + return None + + radar_data = self._radar_msg_from_buffer(self.updated_values, self.rcp.can_valid) + self.updated_values.clear() + + return radar_data + + def _radar_msg_from_buffer(self, updated_values, can_valid): ret = car.RadarData.new_message() - for ii in sorted(updated_messages): - cpt = self.rcp.vl[ii] - if ii == 0x400: - # check for radar faults - self.radar_fault = cpt['RADAR_STATE'] != 0x79 - self.radar_wrong_config = cpt['RADAR_STATE'] == 0x69 - elif cpt['LONG_DIST'] < 255: - if ii not in self.pts or cpt['NEW_TRACK']: - self.pts[ii] = car.RadarData.RadarPoint.new_message() - self.pts[ii].trackId = self.track_id - self.track_id += 1 - self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car - self.pts[ii].yRel = -cpt['LAT_DIST'] # in car frame's y axis, left is positive - self.pts[ii].vRel = cpt['REL_SPEED'] - self.pts[ii].aRel = float('nan') - self.pts[ii].yvRel = float('nan') - self.pts[ii].measured = True - else: - if ii in self.pts: - del self.pts[ii] + for ii in sorted(updated_values): + msgs = updated_values[ii] + n_vals_per_addr = len(list(msgs.values())[0]) + cpts = [ + {k: v[i] for k, v in msgs.items()} + for i in range(n_vals_per_addr) + ] + + for cpt in cpts: + if ii == 0x400: + # check for radar faults + self.radar_fault = cpt['RADAR_STATE'] != 0x79 + self.radar_wrong_config = cpt['RADAR_STATE'] == 0x69 + elif cpt['LONG_DIST'] < 255: + if ii not in self.pts or cpt['NEW_TRACK']: + self.pts[ii] = car.RadarData.RadarPoint.new_message() + self.pts[ii].trackId = self.track_id + self.track_id += 1 + self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car + self.pts[ii].yRel = -cpt['LAT_DIST'] # in car frame's y axis, left is positive + self.pts[ii].vRel = cpt['REL_SPEED'] + self.pts[ii].aRel = float('nan') + self.pts[ii].yvRel = float('nan') + self.pts[ii].measured = True + else: + if ii in self.pts: + del self.pts[ii] errors = [] - if not self.rcp.can_valid: + if not can_valid: errors.append("canError") if self.radar_fault: errors.append("fault") diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 39df4e11f7..55c7fc9b3b 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -12,6 +12,7 @@ from selfdrive.car.interfaces import CarStateBase PREV_BUTTON_SAMPLES = 8 CLUSTER_SAMPLE_RATE = 20 # frames +STANDSTILL_THRESHOLD = 12 * 0.03125 * CV.KPH_TO_MS class CarState(CarStateBase): @@ -22,8 +23,8 @@ class CarState(CarStateBase): self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) - self.gear_msg_canfd = "GEAR_ALT_2" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS_2 else \ - "GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \ + self.gear_msg_canfd = "GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \ + "GEAR_ALT_2" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS_2 else \ "GEAR_SHIFTER" if CP.carFingerprint in CANFD_CAR: self.shifter_values = can_define.dv[self.gear_msg_canfd]["GEAR"] @@ -34,6 +35,11 @@ class CarState(CarStateBase): else: # preferred and elect gear methods use same definition self.shifter_values = can_define.dv["LVR12"]["CF_Lvr_Gear"] + self.accelerator_msg_canfd = "ACCELERATOR" if CP.carFingerprint in EV_CAR else \ + "ACCELERATOR_ALT" if CP.carFingerprint in HYBRID_CAR else \ + "ACCELERATOR_BRAKE_ALT" + self.cruise_btns_msg_canfd = "CRUISE_BUTTONS_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else \ + "CRUISE_BUTTONS" self.is_metric = False self.buttons_counter = 0 @@ -67,7 +73,7 @@ class CarState(CarStateBase): ) ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) - ret.standstill = ret.vEgoRaw < 0.1 + ret.standstill = ret.wheelSpeeds.fl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD self.cluster_speed_counter += 1 if self.cluster_speed_counter > CLUSTER_SAMPLE_RATE: @@ -166,13 +172,11 @@ class CarState(CarStateBase): speed_factor = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS if self.CP.carFingerprint in (EV_CAR | HYBRID_CAR): - if self.CP.carFingerprint in EV_CAR: - ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. - else: - ret.gas = cp.vl["ACCELERATOR_ALT"]["ACCELERATOR_PEDAL"] / 1023. + offset = 255. if self.CP.carFingerprint in EV_CAR else 1023. + ret.gas = cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL"] / offset ret.gasPressed = ret.gas > 1e-5 else: - ret.gasPressed = bool(cp.vl["ACCELERATOR_BRAKE_ALT"]["ACCELERATOR_PEDAL_PRESSED"]) + ret.gasPressed = bool(cp.vl[self.accelerator_msg_canfd]["ACCELERATOR_PEDAL_PRESSED"]) ret.brakePressed = cp.vl["TCS"]["DriverBraking"] == 1 @@ -191,7 +195,7 @@ class CarState(CarStateBase): ) ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) - ret.standstill = ret.vEgoRaw < 0.1 + ret.standstill = ret.wheelSpeeds.fl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD ret.steeringRateDeg = cp.vl["STEERING_SENSORS"]["STEERING_RATE"] ret.steeringAngleDeg = cp.vl["STEERING_SENSORS"]["STEERING_ANGLE"] * -1 @@ -220,11 +224,10 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp_cruise_info.vl["SCC_CONTROL"]["VSetDis"] * speed_factor self.cruise_info = copy.copy(cp_cruise_info.vl["SCC_CONTROL"]) - cruise_btn_msg = "CRUISE_BUTTONS_ALT" if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS else "CRUISE_BUTTONS" self.prev_cruise_buttons = self.cruise_buttons[-1] - self.cruise_buttons.extend(cp.vl_all[cruise_btn_msg]["CRUISE_BUTTONS"]) - self.main_buttons.extend(cp.vl_all[cruise_btn_msg]["ADAPTIVE_CRUISE_MAIN_BTN"]) - self.buttons_counter = cp.vl[cruise_btn_msg]["COUNTER"] + self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) + self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"]) + self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"] ret.accFaulted = cp.vl["TCS"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED if self.CP.flags & HyundaiFlags.CANFD_HDA2: @@ -232,10 +235,9 @@ class CarState(CarStateBase): return ret - @staticmethod - def get_can_parser(CP): + def get_can_parser(self, CP): if CP.carFingerprint in CANFD_CAR: - return CarState.get_can_parser_canfd(CP) + return self.get_can_parser_canfd(CP) freq_mdps12 = 100 if CP.flags & HyundaiFlags.CAN_CANFD_HDA2.value else 50 @@ -315,14 +317,12 @@ class CarState(CarStateBase): bus = 6 if CP.flags & HyundaiFlags.CAN_CANFD_HDA2 else 2 return CANParser(DBC[CP.carFingerprint]["pt"], messages, bus) - @staticmethod - def get_can_parser_canfd(CP): - gear_msg = "GEAR_ALT_2" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS_2 else \ - "GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \ - "GEAR_SHIFTER" + def get_can_parser_canfd(self, CP): messages = [ + (self.gear_msg_canfd, 100), + (self.cruise_btns_msg_canfd, 50), + (self.accelerator_msg_canfd, 100), ("WHEEL_SPEEDS", 100), - (gear_msg, 100), ("STEERING_SENSORS", 100), ("MDPS", 100), ("TCS", 50), @@ -331,9 +331,6 @@ class CarState(CarStateBase): ("DOORS_SEATBELTS", 4), ] - if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): - messages.append(("CRUISE_BUTTONS", 50)) - if CP.enableBsm: messages += [ ("BLINDSPOTS_REAR_CORNERS", 20), @@ -344,19 +341,6 @@ class CarState(CarStateBase): ("SCC_CONTROL", 50), ] - if CP.carFingerprint in EV_CAR: - messages += [ - ("ACCELERATOR", 100), - ] - elif CP.carFingerprint in HYBRID_CAR: - messages += [ - ("ACCELERATOR_ALT", 100), - ] - else: - messages += [ - ("ACCELERATOR_BRAKE_ALT", 100), - ] - return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).ECAN) @staticmethod diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 6761560bf0..292fbfb195 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -6,7 +6,7 @@ from selfdrive.car.hyundai.hyundaicanfd import CanBus from selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \ EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR -from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config +from selfdrive.car import create_button_event, get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.disable_ecu import disable_ecu @@ -63,185 +63,183 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.1 # Default delay ret.steerLimitTimer = 0.4 - tire_stiffness_factor = 1. CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) if candidate in (CAR.SANTA_FE, CAR.SANTA_FE_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022): - ret.mass = 3982. * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3982. * CV.LB_TO_KG ret.wheelbase = 2.766 # Values from optimizer ret.steerRatio = 16.55 # 13.8 is spec end-to-end - tire_stiffness_factor = 0.82 + ret.tireStiffnessFactor = 0.82 elif candidate in (CAR.SONATA, CAR.SONATA_HYBRID): - ret.mass = 1513. + STD_CARGO_KG + ret.mass = 1513. ret.wheelbase = 2.84 ret.steerRatio = 13.27 * 1.15 # 15% higher at the center seems reasonable - tire_stiffness_factor = 0.65 + ret.tireStiffnessFactor = 0.65 elif candidate == CAR.SONATA_LF: - ret.mass = 4497. * CV.LB_TO_KG + ret.mass = 1536. ret.wheelbase = 2.804 ret.steerRatio = 13.27 * 1.15 # 15% higher at the center seems reasonable elif candidate in (CAR.PALISADE, CAR.PALISADE_2023): - ret.mass = 1999. + STD_CARGO_KG + ret.mass = 1999. ret.wheelbase = 2.90 ret.steerRatio = 15.6 * 1.15 - tire_stiffness_factor = 0.63 + ret.tireStiffnessFactor = 0.63 elif candidate == CAR.ELANTRA: - ret.mass = 1275. + STD_CARGO_KG + ret.mass = 1275. ret.wheelbase = 2.7 ret.steerRatio = 15.4 # 14 is Stock | Settled Params Learner values are steerRatio: 15.401566348670535 - tire_stiffness_factor = 0.385 # stiffnessFactor settled on 1.0081302973865127 + ret.tireStiffnessFactor = 0.385 # stiffnessFactor settled on 1.0081302973865127 ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.ELANTRA_2021: - ret.mass = (2800. * CV.LB_TO_KG) + STD_CARGO_KG + ret.mass = 2800. * CV.LB_TO_KG ret.wheelbase = 2.72 ret.steerRatio = 12.9 - tire_stiffness_factor = 0.65 + ret.tireStiffnessFactor = 0.65 elif candidate == CAR.ELANTRA_HEV_2021: - ret.mass = (3017. * CV.LB_TO_KG) + STD_CARGO_KG + ret.mass = 3017. * CV.LB_TO_KG ret.wheelbase = 2.72 ret.steerRatio = 12.9 - tire_stiffness_factor = 0.65 + ret.tireStiffnessFactor = 0.65 elif candidate == CAR.HYUNDAI_GENESIS: - ret.mass = 2060. + STD_CARGO_KG + ret.mass = 2060. ret.wheelbase = 3.01 ret.steerRatio = 16.5 ret.minSteerSpeed = 60 * CV.KPH_TO_MS elif candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022): - ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425., CAR.KONA_EV_2022: 1743.}.get(candidate, 1275.) + STD_CARGO_KG + ret.mass = {CAR.KONA_EV: 1685., CAR.KONA_HEV: 1425., CAR.KONA_EV_2022: 1743.}.get(candidate, 1275.) ret.wheelbase = 2.6 ret.steerRatio = 13.42 # Spec - tire_stiffness_factor = 0.385 + ret.tireStiffnessFactor = 0.385 elif candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV_2019, CAR.IONIQ_HEV_2022, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV): - ret.mass = 1490. + STD_CARGO_KG # weight per hyundai site https://www.hyundaiusa.com/ioniq-electric/specifications.aspx + ret.mass = 1490. # weight per hyundai site https://www.hyundaiusa.com/ioniq-electric/specifications.aspx ret.wheelbase = 2.7 ret.steerRatio = 13.73 # Spec - tire_stiffness_factor = 0.385 + ret.tireStiffnessFactor = 0.385 if candidate in (CAR.IONIQ, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV_2019): ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.VELOSTER: - ret.mass = 3558. * CV.LB_TO_KG + ret.mass = 2917. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 * 1.15 - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 elif candidate == CAR.TUCSON: ret.mass = 3520. * CV.LB_TO_KG ret.wheelbase = 2.67 ret.steerRatio = 14.00 * 1.15 - tire_stiffness_factor = 0.385 + ret.tireStiffnessFactor = 0.385 elif candidate in (CAR.TUCSON_4TH_GEN, CAR.TUCSON_HYBRID_4TH_GEN): - ret.mass = 1630. + STD_CARGO_KG # average + ret.mass = 1630. # average ret.wheelbase = 2.756 ret.steerRatio = 16. - tire_stiffness_factor = 0.385 + ret.tireStiffnessFactor = 0.385 elif candidate == CAR.SANTA_CRUZ_1ST_GEN: - ret.mass = 1870. + STD_CARGO_KG # weight from Limited trim - the only supported trim + ret.mass = 1870. # weight from Limited trim - the only supported trim ret.wheelbase = 3.000 # steering ratio according to Hyundai News https://www.hyundainews.com/assets/documents/original/48035-2022SantaCruzProductGuideSpecsv2081521.pdf ret.steerRatio = 14.2 # Kia elif candidate == CAR.KIA_SORENTO: - ret.mass = 1985. + STD_CARGO_KG + ret.mass = 1985. ret.wheelbase = 2.78 ret.steerRatio = 14.4 * 1.1 # 10% higher at the center seems reasonable elif candidate in (CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_NIRO_HEV_2ND_GEN): - ret.mass = 3543. * CV.LB_TO_KG + STD_CARGO_KG # average of all the cars + ret.mass = 3543. * CV.LB_TO_KG # average of all the cars ret.wheelbase = 2.7 ret.steerRatio = 13.6 # average of all the cars - tire_stiffness_factor = 0.385 + ret.tireStiffnessFactor = 0.385 if candidate == CAR.KIA_NIRO_PHEV: ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate == CAR.KIA_SELTOS: - ret.mass = 1337. + STD_CARGO_KG + ret.mass = 1337. ret.wheelbase = 2.63 ret.steerRatio = 14.56 - tire_stiffness_factor = 1 elif candidate == CAR.KIA_SPORTAGE_5TH_GEN: - ret.mass = 1700. + STD_CARGO_KG # weight from SX and above trims, average of FWD and AWD versions + ret.mass = 1700. # weight from SX and above trims, average of FWD and AWD versions ret.wheelbase = 2.756 ret.steerRatio = 13.6 # steering ratio according to Kia News https://www.kiamedia.com/us/en/models/sportage/2023/specifications elif candidate in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.KIA_OPTIMA_H): ret.mass = 3558. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 if candidate == CAR.KIA_OPTIMA_G4: ret.minSteerSpeed = 32 * CV.MPH_TO_MS elif candidate in (CAR.KIA_STINGER, CAR.KIA_STINGER_2022): - ret.mass = 1825. + STD_CARGO_KG + ret.mass = 1825. ret.wheelbase = 2.78 ret.steerRatio = 14.4 * 1.15 # 15% higher at the center seems reasonable elif candidate == CAR.KIA_FORTE: - ret.mass = 3558. * CV.LB_TO_KG + ret.mass = 2878. * CV.LB_TO_KG ret.wheelbase = 2.80 ret.steerRatio = 13.75 - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 elif candidate == CAR.KIA_CEED: - ret.mass = 1450. + STD_CARGO_KG + ret.mass = 1450. ret.wheelbase = 2.65 ret.steerRatio = 13.75 - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 elif candidate in (CAR.KIA_K5_2021, CAR.KIA_K5_HEV_2020): - ret.mass = 3228. * CV.LB_TO_KG + ret.mass = 3381. * CV.LB_TO_KG ret.wheelbase = 2.85 ret.steerRatio = 13.27 # 2021 Kia K5 Steering Ratio (all trims) - tire_stiffness_factor = 0.5 + ret.tireStiffnessFactor = 0.5 elif candidate == CAR.KIA_EV6: - ret.mass = 2055 + STD_CARGO_KG + ret.mass = 2055 ret.wheelbase = 2.9 ret.steerRatio = 16. - tire_stiffness_factor = 0.65 + ret.tireStiffnessFactor = 0.65 elif candidate in (CAR.IONIQ_5, CAR.IONIQ_6): - ret.mass = 1948 + STD_CARGO_KG + ret.mass = 1948 ret.wheelbase = 2.97 ret.steerRatio = 14.26 - tire_stiffness_factor = 0.65 + ret.tireStiffnessFactor = 0.65 elif candidate == CAR.KIA_SPORTAGE_HYBRID_5TH_GEN: - ret.mass = 1767. + STD_CARGO_KG # SX Prestige trim support only + ret.mass = 1767. # SX Prestige trim support only ret.wheelbase = 2.756 ret.steerRatio = 13.6 elif candidate in (CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN): ret.wheelbase = 2.81 ret.steerRatio = 13.5 # average of the platforms if candidate == CAR.KIA_SORENTO_4TH_GEN: - ret.mass = 3957 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3957 * CV.LB_TO_KG else: - ret.mass = 4537 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 4537 * CV.LB_TO_KG elif candidate == CAR.KIA_CARNIVAL_4TH_GEN: - ret.mass = 2087. + STD_CARGO_KG + ret.mass = 2087. ret.wheelbase = 3.09 ret.steerRatio = 14.23 # Genesis elif candidate == CAR.GENESIS_GV60_EV_1ST_GEN: - ret.mass = 2205 + STD_CARGO_KG + ret.mass = 2205 ret.wheelbase = 2.9 # https://www.motor1.com/reviews/586376/2023-genesis-gv60-first-drive/#:~:text=Relative%20to%20the%20related%20Ioniq,5%2FEV6%27s%2014.3%3A1. ret.steerRatio = 12.6 elif candidate == CAR.GENESIS_G70: ret.steerActuatorDelay = 0.1 - ret.mass = 1640.0 + STD_CARGO_KG + ret.mass = 1640.0 ret.wheelbase = 2.84 ret.steerRatio = 13.56 elif candidate == CAR.GENESIS_G70_2020: - ret.mass = 3673.0 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3673.0 * CV.LB_TO_KG ret.wheelbase = 2.83 ret.steerRatio = 12.9 elif candidate == CAR.GENESIS_GV70_1ST_GEN: - ret.mass = 1950. + STD_CARGO_KG + ret.mass = 1950. ret.wheelbase = 2.87 ret.steerRatio = 14.6 elif candidate == CAR.GENESIS_G80: - ret.mass = 2060. + STD_CARGO_KG + ret.mass = 2060. ret.wheelbase = 3.01 ret.steerRatio = 16.5 elif candidate == CAR.GENESIS_G90: - ret.mass = 2200 + ret.mass = 2200. ret.wheelbase = 3.15 ret.steerRatio = 12.069 elif candidate == CAR.GENESIS_GV80: - ret.mass = 2258. + STD_CARGO_KG + ret.mass = 2258. ret.wheelbase = 2.95 ret.steerRatio = 14.14 @@ -313,10 +311,6 @@ class CarInterface(CarInterfaceBase): ret.centerToFront = ret.wheelbase * 0.4 - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, - tire_stiffness_factor=tire_stiffness_factor) return ret @staticmethod diff --git a/selfdrive/car/hyundai/radar_interface.py b/selfdrive/car/hyundai/radar_interface.py index 3b74a03d4b..7301ad18ce 100644 --- a/selfdrive/car/hyundai/radar_interface.py +++ b/selfdrive/car/hyundai/radar_interface.py @@ -30,7 +30,7 @@ class RadarInterface(RadarInterfaceBase): def update(self, can_strings): if self.radar_off_can or (self.rcp is None): - return super().update(None) + return None vls = self.rcp.update_strings(can_strings) self.updated_messages.update(vls) diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 99df4cf4b4..a9966c2bb7 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -1,6 +1,5 @@ import yaml import os -import time from abc import abstractmethod, ABC from typing import Any, Dict, Optional, Tuple, List, Callable @@ -10,7 +9,7 @@ from common.conversions import Conversions as CV from common.kalman.simple_kalman import KF1D from common.numpy_fast import clip from common.realtime import DT_CTRL -from selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness +from selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction from selfdrive.controls.lib.events import Events from selfdrive.controls.lib.vehicle_model import VehicleModel @@ -100,16 +99,13 @@ class CarInterfaceBase(ABC): ret = CarInterfaceBase.get_std_params(candidate) ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs) - # Set common params using fields set by the car interface - # TODO: get actual value, for now starting with reasonable value for - # civic and scaling by mass and wheelbase - ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) + # Vehicle mass is published curb weight plus assumed payload such as a human driver; notCars have no assumed payload + if not ret.notCar: + ret.mass = ret.mass + STD_CARGO_KG - # TODO: some car interfaces set stiffness factor - if ret.tireStiffnessFront == 0 or ret.tireStiffnessRear == 0: - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront) + # Set params dependent on values set by the car interface + ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) + ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, ret.tireStiffnessFactor) return ret @@ -152,6 +148,7 @@ class CarInterfaceBase(ABC): ret.autoResumeSng = True # describes whether car can resume from a stop automatically # standard ALC params + ret.tireStiffnessFactor = 1.0 ret.steerControlType = car.CarParams.SteerControlType.torque ret.minSteerSpeed = 0. ret.wheelSpeedFactor = 1.0 @@ -312,14 +309,9 @@ class RadarInterfaceBase(ABC): self.rcp = None self.pts = {} self.delay = 0 - self.radar_ts = CP.radarTimeStep - self.no_radar_sleep = 'NO_RADAR_SLEEP' in os.environ def update(self, can_strings): - ret = car.RadarData.new_message() - if not self.no_radar_sleep: - time.sleep(self.radar_ts) # radard runs on RI updates - return ret + pass class CarStateBase(ABC): diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 443116bc18..cb89c4c448 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -2,7 +2,7 @@ from cereal import car from common.conversions import Conversions as CV from selfdrive.car.mazda.values import CAR, LKAS_LIMITS -from selfdrive.car import STD_CARGO_KG, scale_tire_stiffness, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -20,24 +20,24 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.8 - tire_stiffness_factor = 0.70 # not optimized yet + ret.tireStiffnessFactor = 0.70 # not optimized yet CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) if candidate in (CAR.CX5, CAR.CX5_2022): - ret.mass = 3655 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3655 * CV.LB_TO_KG ret.wheelbase = 2.7 ret.steerRatio = 15.5 elif candidate in (CAR.CX9, CAR.CX9_2021): - ret.mass = 4217 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 4217 * CV.LB_TO_KG ret.wheelbase = 3.1 ret.steerRatio = 17.6 elif candidate == CAR.MAZDA3: - ret.mass = 2875 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 2875 * CV.LB_TO_KG ret.wheelbase = 2.7 ret.steerRatio = 14.0 elif candidate == CAR.MAZDA6: - ret.mass = 3443 * CV.LB_TO_KG + STD_CARGO_KG + ret.mass = 3443 * CV.LB_TO_KG ret.wheelbase = 2.83 ret.steerRatio = 15.5 @@ -46,11 +46,6 @@ class CarInterface(CarInterfaceBase): ret.centerToFront = ret.wheelbase * 0.41 - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, - tire_stiffness_factor=tire_stiffness_factor) - return ret # returns a car.CarState diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 1c74aef1fa..7986adb8f1 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -26,8 +26,6 @@ class CarInterface(CarInterfaceBase): ret.wheelbase = 2.70 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 13. # reasonable - ret.tireStiffnessFront = 1e6 # very stiff to neglect slip - ret.tireStiffnessRear = 1e6 # very stiff to neglect slip return ret diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index f26dea43af..423a1bf8de 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 from cereal import car -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.nissan.values import CAR @@ -22,17 +22,17 @@ class CarInterface(CarInterfaceBase): ret.radarUnavailable = True if candidate in (CAR.ROGUE, CAR.XTRAIL): - ret.mass = 1610 + STD_CARGO_KG + ret.mass = 1610 ret.wheelbase = 2.705 ret.centerToFront = ret.wheelbase * 0.44 elif candidate in (CAR.LEAF, CAR.LEAF_IC): - ret.mass = 1610 + STD_CARGO_KG + ret.mass = 1610 ret.wheelbase = 2.705 ret.centerToFront = ret.wheelbase * 0.44 elif candidate == CAR.ALTIMA: # Altima has EPS on C-CAN unlike the others that have it on V-CAN ret.safetyConfigs[0].safetyParam = 1 # EPS is on alternate bus - ret.mass = 1492 + STD_CARGO_KG + ret.mass = 1492 ret.wheelbase = 2.824 ret.centerToFront = ret.wheelbase * 0.44 diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index b37c88797a..80634bf261 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -1,3 +1,4 @@ +from common.numpy_fast import clip, interp from opendbc.can.packer import CANPacker from selfdrive.car import apply_driver_steer_torque_limits from selfdrive.car.subaru import subarucan @@ -42,6 +43,21 @@ class CarController: self.apply_steer_last = apply_steer + # *** longitudinal *** + + if CC.longActive: + apply_throttle = int(round(interp(actuators.accel, CarControllerParams.THROTTLE_LOOKUP_BP, CarControllerParams.THROTTLE_LOOKUP_V))) + apply_rpm = int(round(interp(actuators.accel, CarControllerParams.RPM_LOOKUP_BP, CarControllerParams.RPM_LOOKUP_V))) + apply_brake = int(round(interp(actuators.accel, CarControllerParams.BRAKE_LOOKUP_BP, CarControllerParams.BRAKE_LOOKUP_V))) + + # limit min and max values + cruise_throttle = clip(apply_throttle, CarControllerParams.THROTTLE_MIN, CarControllerParams.THROTTLE_MAX) + cruise_rpm = clip(apply_rpm, CarControllerParams.RPM_MIN, CarControllerParams.RPM_MAX) + cruise_brake = clip(apply_brake, CarControllerParams.BRAKE_MIN, CarControllerParams.BRAKE_MAX) + else: + cruise_throttle = CarControllerParams.THROTTLE_INACTIVE + cruise_rpm = CarControllerParams.RPM_INACTIVE + cruise_brake = CarControllerParams.BRAKE_MIN # *** alerts and pcm cancel *** if self.CP.carFingerprint in PREGLOBAL_CARS: @@ -64,13 +80,9 @@ class CarController: can_sends.append(subarucan.create_preglobal_es_distance(self.packer, cruise_button, CS.es_distance_msg)) else: - if pcm_cancel_cmd and (self.frame - self.last_cancel_frame) > 0.2: - bus = CanBus.alt if self.CP.carFingerprint in GLOBAL_GEN2 else CanBus.main - can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, bus, pcm_cancel_cmd)) - self.last_cancel_frame = self.frame - if self.frame % 10 == 0: - can_sends.append(subarucan.create_es_dashstatus(self.packer, CS.es_dashstatus_msg)) + can_sends.append(subarucan.create_es_dashstatus(self.packer, CS.es_dashstatus_msg, CC.enabled, self.CP.openpilotLongitudinalControl, + CC.longActive, hud_control.leadVisible)) can_sends.append(subarucan.create_es_lkas_state(self.packer, CS.es_lkas_state_msg, CC.enabled, hud_control.visualAlert, hud_control.leftLaneVisible, hud_control.rightLaneVisible, @@ -79,6 +91,20 @@ class CarController: if self.CP.flags & SubaruFlags.SEND_INFOTAINMENT: can_sends.append(subarucan.create_es_infotainment(self.packer, CS.es_infotainment_msg, hud_control.visualAlert)) + if self.CP.openpilotLongitudinalControl: + if self.frame % 5 == 0: + can_sends.append(subarucan.create_es_status(self.packer, CS.es_status_msg, self.CP.openpilotLongitudinalControl, CC.longActive, cruise_rpm)) + + can_sends.append(subarucan.create_es_brake(self.packer, CS.es_brake_msg, CC.enabled, cruise_brake)) + + can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, 0, pcm_cancel_cmd, + self.CP.openpilotLongitudinalControl, cruise_brake > 0, cruise_throttle)) + else: + if pcm_cancel_cmd and (self.frame - self.last_cancel_frame) > 0.2: + bus = CanBus.alt if self.CP.carFingerprint in GLOBAL_GEN2 else CanBus.main + can_sends.append(subarucan.create_es_distance(self.packer, CS.es_distance_msg, bus, pcm_cancel_cmd)) + self.last_cancel_frame = self.frame + new_actuators = actuators.copy() new_actuators.steer = self.apply_steer_last / self.p.STEER_MAX new_actuators.steerOutputCan = self.apply_steer_last diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index da8f88ed02..84c1285af1 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -5,6 +5,7 @@ from common.conversions import Conversions as CV from selfdrive.car.interfaces import CarStateBase from opendbc.can.parser import CANParser from selfdrive.car.subaru.values import DBC, CAR, GLOBAL_GEN2, PREGLOBAL_CARS, CanBus, SubaruFlags +from selfdrive.car import CanSignalRateCalculator class CarState(CarStateBase): @@ -13,6 +14,8 @@ class CarState(CarStateBase): can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) self.shifter_values = can_define.dv["Transmission"]["Gear"] + self.angle_rate_calulator = CanSignalRateCalculator(50) + def update(self, cp, cp_cam, cp_body): ret = car.CarState.new_message() @@ -47,6 +50,11 @@ class CarState(CarStateBase): ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) ret.steeringAngleDeg = cp.vl["Steering_Torque"]["Steering_Angle"] + + if self.car_fingerprint not in PREGLOBAL_CARS: + # ideally we get this from the car, but unclear if it exists. diagnostic software doesn't even have it + ret.steeringRateDeg = self.angle_rate_calulator.update(ret.steeringAngleDeg, cp.vl["Steering_Torque"]["COUNTER"]) + ret.steeringTorque = cp.vl["Steering_Torque"]["Steer_Torque_Sensor"] ret.steeringTorqueEps = cp.vl["Steering_Torque"]["Steer_Torque_Output"] @@ -83,6 +91,12 @@ class CarState(CarStateBase): ret.stockAeb = (cp_es_distance.vl["ES_Brake"]["AEB_Status"] == 8) and \ (cp_es_distance.vl["ES_Brake"]["Brake_Pressure"] != 0) self.es_lkas_state_msg = copy.copy(cp_cam.vl["ES_LKAS_State"]) + cp_es_brake = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam + self.es_brake_msg = copy.copy(cp_es_brake.vl["ES_Brake"]) + cp_es_status = cp_body if self.car_fingerprint in GLOBAL_GEN2 else cp_cam + self.es_status_msg = copy.copy(cp_es_status.vl["ES_Status"]) + self.cruise_control_msg = copy.copy(cp_cruise.vl["CruiseControl"]) + self.brake_status_msg = copy.copy(cp_brakes.vl["Brake_Status"]) self.es_distance_msg = copy.copy(cp_es_distance.vl["ES_Distance"]) self.es_dashstatus_msg = copy.copy(cp_cam.vl["ES_DashStatus"]) @@ -106,6 +120,8 @@ class CarState(CarStateBase): messages = [ ("ES_Brake", 20), ("ES_Distance", 20), + ("ES_Status", 20), + ("ES_Brake", 20), ] return messages diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index b01d1eb3bc..eab39420cc 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from cereal import car from panda import Panda -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.subaru.values import CAR, LKAS_ANGLE, GLOBAL_GEN2, PREGLOBAL_CARS, SubaruFlags @@ -37,7 +37,7 @@ class CarInterface(CarInterfaceBase): CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) if candidate == CAR.ASCENT: - ret.mass = 2031. + STD_CARGO_KG + ret.mass = 2031. ret.wheelbase = 2.89 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 13.5 @@ -48,7 +48,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.0025, 0.1], [0.00025, 0.01]] elif candidate == CAR.IMPREZA: - ret.mass = 1568. + STD_CARGO_KG + ret.mass = 1568. ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 15 @@ -59,7 +59,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.3], [0.02, 0.03]] elif candidate == CAR.IMPREZA_2020: - ret.mass = 1480. + STD_CARGO_KG + ret.mass = 1480. ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 17 # learned, 14 stock @@ -69,7 +69,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.045, 0.042, 0.20], [0.04, 0.035, 0.045]] elif candidate in (CAR.FORESTER, CAR.FORESTER_2022): - ret.mass = 1568. + STD_CARGO_KG + ret.mass = 1568. ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 17 # learned, 14 stock @@ -79,7 +79,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.01, 0.065, 0.2], [0.001, 0.015, 0.025]] elif candidate in (CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023): - ret.mass = 1568. + STD_CARGO_KG + ret.mass = 1568. ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 17 @@ -87,26 +87,38 @@ class CarInterface(CarInterfaceBase): elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018): ret.safetyConfigs[0].safetyParam = 1 # Outback 2018-2019 and Forester have reversed driver torque signal - ret.mass = 1568 + STD_CARGO_KG + ret.mass = 1568 ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 20 # learned, 14 stock elif candidate == CAR.LEGACY_PREGLOBAL: - ret.mass = 1568 + STD_CARGO_KG + ret.mass = 1568 ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 12.5 # 14.5 stock ret.steerActuatorDelay = 0.15 elif candidate == CAR.OUTBACK_PREGLOBAL: - ret.mass = 1568 + STD_CARGO_KG + ret.mass = 1568 ret.wheelbase = 2.67 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 20 # learned, 14 stock else: raise ValueError(f"unknown car: {candidate}") + #ret.experimentalLongitudinalAvailable = candidate not in (GLOBAL_GEN2 | PREGLOBAL_CARS | LKAS_ANGLE) + ret.openpilotLongitudinalControl = experimental_long and ret.experimentalLongitudinalAvailable + + if ret.openpilotLongitudinalControl: + ret.longitudinalTuning.kpBP = [0., 5., 35.] + ret.longitudinalTuning.kpV = [0.8, 1.0, 1.5] + ret.longitudinalTuning.kiBP = [0., 35.] + ret.longitudinalTuning.kiV = [0.54, 0.36] + + ret.stoppingControl = True + ret.safetyConfigs[0].safetyParam |= Panda.FLAG_SUBARU_LONG + return ret # returns a car.CarState diff --git a/selfdrive/car/subaru/subarucan.py b/selfdrive/car/subaru/subarucan.py index 0c32a150d8..df2718c764 100644 --- a/selfdrive/car/subaru/subarucan.py +++ b/selfdrive/car/subaru/subarucan.py @@ -16,8 +16,7 @@ def create_steering_control(packer, apply_steer, steer_req): def create_steering_status(packer): return packer.make_can_msg("ES_LKAS_State", 0, {}) - -def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd): +def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd, long_enabled = False, brake_cmd = False, cruise_throttle = 0): values = {s: es_distance_msg[s] for s in [ "CHECKSUM", "COUNTER", @@ -41,8 +40,20 @@ def create_es_distance(packer, es_distance_msg, bus, pcm_cancel_cmd): "Signal6", ]} values["COUNTER"] = (values["COUNTER"] + 1) % 0x10 + + if long_enabled: + values["Cruise_Throttle"] = cruise_throttle + + # Do not disable openpilot on Eyesight Soft Disable, if openpilot is controlling long + values["Cruise_Soft_Disable"] = 0 + + if brake_cmd: + values["Cruise_Brake_Active"] = 1 + if pcm_cancel_cmd: values["Cruise_Cancel"] = 1 + values["Cruise_Throttle"] = 1818 # inactive throttle + return packer.make_can_msg("ES_Distance", bus, values) @@ -105,8 +116,7 @@ def create_es_lkas_state(packer, es_lkas_state_msg, enabled, visual_alert, left_ return packer.make_can_msg("ES_LKAS_State", CanBus.main, values) - -def create_es_dashstatus(packer, dashstatus_msg): +def create_es_dashstatus(packer, dashstatus_msg, enabled, long_enabled, long_active, lead_visible): values = {s: dashstatus_msg[s] for s in [ "CHECKSUM", "COUNTER", @@ -137,12 +147,68 @@ def create_es_dashstatus(packer, dashstatus_msg): "Cruise_State", ]} + if enabled and long_active: + values["Cruise_State"] = 0 + values["Cruise_Activated"] = 1 + values["Cruise_Disengaged"] = 0 + values["Car_Follow"] = int(lead_visible) + + if long_enabled: + values["PCB_Off"] = 1 # AEB is not presevered, so show the PCB_Off on dash + # Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts if values["LKAS_State_Msg"] in (2, 3): values["LKAS_State_Msg"] = 0 return packer.make_can_msg("ES_DashStatus", CanBus.main, values) +def create_es_brake(packer, es_brake_msg, enabled, brake_value): + values = {s: es_brake_msg[s] for s in [ + "CHECKSUM", + "COUNTER", + "Signal1", + "Brake_Pressure", + "AEB_Status", + "Cruise_Brake_Lights", + "Cruise_Brake_Fault", + "Cruise_Brake_Active", + "Cruise_Activated", + "Signal3", + ]} + + if enabled: + values["Cruise_Activated"] = 1 + + values["Brake_Pressure"] = brake_value + + if brake_value > 0: + values["Cruise_Brake_Active"] = 1 + values["Cruise_Brake_Lights"] = 1 if brake_value >= 70 else 0 + + return packer.make_can_msg("ES_Brake", CanBus.main, values) + +def create_es_status(packer, es_status_msg, long_enabled, long_active, cruise_rpm): + values = {s: es_status_msg[s] for s in [ + "CHECKSUM", + "COUNTER", + "Signal1", + "Cruise_Fault", + "Cruise_RPM", + "Signal2", + "Cruise_Activated", + "Brake_Lights", + "Cruise_Hold", + "Signal3", + ]} + + if long_enabled: + values["Cruise_RPM"] = cruise_rpm + + if long_active: + values["Cruise_Activated"] = 1 + + return packer.make_can_msg("ES_Status", CanBus.main, values) + def create_es_infotainment(packer, es_infotainment_msg, visual_alert): # Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 95708445aa..dc25f31f73 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -29,6 +29,29 @@ class CarControllerParams: else: self.STEER_MAX = 2047 + THROTTLE_MIN = 808 + THROTTLE_MAX = 3400 + + THROTTLE_INACTIVE = 1818 # corresponds to zero acceleration + THROTTLE_ENGINE_BRAKE = 808 # while braking, eyesight sets throttle to this, probably for engine braking + + BRAKE_MIN = 0 + BRAKE_MAX = 600 # about -3.5m/s2 from testing + + RPM_MIN = 0 + RPM_MAX = 2400 + + RPM_INACTIVE = 600 # a good base rpm for zero acceleration + + THROTTLE_LOOKUP_BP = [0, 1] + THROTTLE_LOOKUP_V = [THROTTLE_INACTIVE, THROTTLE_MAX] + + RPM_LOOKUP_BP = [0, 1] + RPM_LOOKUP_V = [RPM_INACTIVE, RPM_MAX] + + BRAKE_LOOKUP_BP = [-1, 0] + BRAKE_LOOKUP_V = [BRAKE_MAX, BRAKE_MIN] + class SubaruFlags(IntFlag): SEND_INFOTAINMENT = 1 @@ -288,6 +311,7 @@ FW_VERSIONS = { b'\xe6!fp\x07', b'\xf3"fp\x07', b'\xe6"f0\x07', + b'\xe6"fp\x07', ], (Ecu.transmission, 0x7e1, None): [ b'\xe6\xf5\004\000\000', diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py index afd3fb3be4..209f00873a 100755 --- a/selfdrive/car/tesla/interface.py +++ b/selfdrive/car/tesla/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from selfdrive.car.tesla.values import CANBUS, CAR -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase @@ -42,7 +42,7 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.25 if candidate in (CAR.AP2_MODELS, CAR.AP1_MODELS): - ret.mass = 2100. + STD_CARGO_KG + ret.mass = 2100. ret.wheelbase = 2.959 ret.centerToFront = ret.wheelbase * 0.5 ret.steerRatio = 15.0 diff --git a/selfdrive/car/tesla/radar_interface.py b/selfdrive/car/tesla/radar_interface.py index c368c794b0..cf76e213e0 100755 --- a/selfdrive/car/tesla/radar_interface.py +++ b/selfdrive/car/tesla/radar_interface.py @@ -36,7 +36,7 @@ class RadarInterface(RadarInterfaceBase): def update(self, can_strings): if self.rcp is None: - return super().update(None) + return None values = self.rcp.update_strings(can_strings) self.updated_messages.update(values) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 4e0b2446bc..1de2d112fd 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from collections import namedtuple +from typing import NamedTuple, Optional from selfdrive.car.chrysler.values import CAR as CHRYSLER from selfdrive.car.gm.values import CAR as GM @@ -30,7 +30,12 @@ non_tested_cars = [ TOYOTA.RAV4H_TSS2_2023, ] -CarTestRoute = namedtuple('CarTestRoute', ['route', 'car_model', 'segment'], defaults=(None,)) + +class CarTestRoute(NamedTuple): + route: str + car_model: Optional[str] + segment: Optional[int] = None + routes = [ CarTestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.BODY), @@ -166,7 +171,6 @@ routes = [ CarTestRoute("5f5afb36036506e4|2019-05-14--02-09-54", TOYOTA.COROLLA_TSS2), CarTestRoute("5ceff72287a5c86c|2019-10-19--10-59-02", TOYOTA.COROLLAH_TSS2), CarTestRoute("d2525c22173da58b|2021-04-25--16-47-04", TOYOTA.PRIUS), - CarTestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.RAV4), CarTestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.RAV4H), CarTestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.RAV4_TSS2), CarTestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), diff --git a/selfdrive/car/tests/test_can_fingerprint.py b/selfdrive/car/tests/test_can_fingerprint.py new file mode 100755 index 0000000000..9f3f232980 --- /dev/null +++ b/selfdrive/car/tests/test_can_fingerprint.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +from parameterized import parameterized +import unittest + +from cereal import log, messaging +from selfdrive.car.car_helpers import can_fingerprint +from selfdrive.car.fingerprints import _FINGERPRINTS as FINGERPRINTS + + +class TestCanFingerprint(unittest.TestCase): + @parameterized.expand([(c, f) for c, f in FINGERPRINTS.items()]) + def test_can_fingerprint(self, car_model, fingerprints): + """Tests online fingerprinting function on offline fingerprints""" + + for fingerprint in fingerprints: # can have multiple fingerprints for each platform + can = messaging.new_message('can', 1) + can.can = [log.CanData(address=address, dat=b'\x00' * length, src=src) + for address, length in fingerprint.items() for src in (0, 1)] + + fingerprint_iter = iter([can]) + empty_can = messaging.new_message('can', 0) + car_fingerprint, finger = can_fingerprint(lambda: next(fingerprint_iter, empty_can)) # noqa: B023 + + self.assertEqual(car_fingerprint, car_model) + self.assertEqual(finger[0], fingerprint) + self.assertEqual(finger[1], fingerprint) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/car/tests/test_fingerprints.py b/selfdrive/car/tests/test_fingerprints.py index 26ade29e4a..a0baec68d6 100755 --- a/selfdrive/car/tests/test_fingerprints.py +++ b/selfdrive/car/tests/test_fingerprints.py @@ -70,7 +70,7 @@ if __name__ == "__main__": for brand in fingerprints: for car in fingerprints[brand]: fingerprints_flat += fingerprints[brand][car] - for i in range(len(fingerprints[brand][car])): + for _ in range(len(fingerprints[brand][car])): car_names.append(car) brand_names.append(brand) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index a2a8ed5eb7..c40d8bb505 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # pylint: disable=E1101 +import capnp import os import importlib import unittest @@ -11,7 +12,7 @@ from cereal import log, car from common.basedir import BASEDIR from common.realtime import DT_CTRL from selfdrive.car.fingerprints import all_known_cars -from selfdrive.car.car_helpers import interfaces +from selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces from selfdrive.car.gm.values import CAR as GM from selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH from selfdrive.car.hyundai.values import CAR as HYUNDAI @@ -27,6 +28,7 @@ PandaType = log.PandaState.PandaType NUM_JOBS = int(os.environ.get("NUM_JOBS", "1")) JOB_ID = int(os.environ.get("JOB_ID", "0")) INTERNAL_SEG_LIST = os.environ.get("INTERNAL_SEG_LIST", "") +INTERNAL_SEG_CNT = int(os.environ.get("INTERNAL_SEG_CNT", "0")) ignore_addr_checks_valid = [ GM.BUICK_REGAL, @@ -34,9 +36,9 @@ ignore_addr_checks_valid = [ ] -def get_test_cases(): +def get_test_cases() -> List[Tuple[str, Optional[CarTestRoute]]]: # build list of test cases - test_cases: List[Tuple[str, Optional[CarTestRoute]]] = [] + test_cases = [] if not len(INTERNAL_SEG_LIST): routes_by_car = defaultdict(set) for r in routes: @@ -48,11 +50,14 @@ def get_test_cases(): else: with open(os.path.join(BASEDIR, INTERNAL_SEG_LIST), "r") as f: - seg_list = iter(f.read().splitlines()) + seg_list = f.read().splitlines() - for platform in seg_list: + cnt = INTERNAL_SEG_CNT or len(seg_list) + seg_list_iter = iter(seg_list[:cnt]) + + for platform in seg_list_iter: platform = platform[2:] # get rid of comment - segment_name = SegmentName(next(seg_list)) + segment_name = SegmentName(next(seg_list_iter)) test_cases.append((platform, CarTestRoute(segment_name.route_name.canonical_name, platform, segment=segment_name.segment_num))) return test_cases @@ -62,9 +67,11 @@ SKIP_ENV_VAR = "SKIP_LONG_TESTS" class TestCarModelBase(unittest.TestCase): - car_model = None - test_route = None - ci = True + car_model: Optional[str] = None + test_route: Optional[CarTestRoute] = None + ci: bool = True + + can_msgs: List[capnp.lib.capnp._DynamicStructReader] @unittest.skipIf(SKIP_ENV_VAR in os.environ, f"Long running test skipped. Unset {SKIP_ENV_VAR} to run") @classmethod @@ -82,7 +89,6 @@ class TestCarModelBase(unittest.TestCase): raise unittest.SkipTest raise Exception(f"missing test route for {cls.car_model}") - experimental_long = False test_segs = (2, 1, 0) if cls.test_route.segment is not None: test_segs = (cls.test_route.segment,) @@ -102,24 +108,38 @@ class TestCarModelBase(unittest.TestCase): car_fw = [] can_msgs = [] fingerprint = defaultdict(dict) + experimental_long = False + enabled_toggle = True + dashcam_only = False for msg in lr: if msg.which() == "can": - for m in msg.can: - if m.src < 64: - fingerprint[m.src][m.address] = len(m.dat) can_msgs.append(msg) + if len(can_msgs) <= FRAME_FINGERPRINT: + for m in msg.can: + if m.src < 64: + fingerprint[m.src][m.address] = len(m.dat) + elif msg.which() == "carParams": car_fw = msg.carParams.carFw + dashcam_only = msg.carParams.dashcamOnly if msg.carParams.openpilotLongitudinalControl: experimental_long = True if cls.car_model is None and not cls.ci: cls.car_model = msg.carParams.carFingerprint + elif msg.which() == 'initData': + for param in msg.initData.params.entries: + if param.key == 'OpenpilotEnabledToggle': + enabled_toggle = param.value.strip(b'\x00') == b'1' + if len(can_msgs) > int(50 / DT_CTRL): break else: raise Exception(f"Route: {repr(cls.test_route.route)} with segments: {test_segs} not found or no CAN msgs found. Is it uploaded?") + # if relay is expected to be open in the route + cls.openpilot_enabled = enabled_toggle and not dashcam_only + cls.can_msgs = sorted(can_msgs, key=lambda msg: msg.logMonoTime) cls.CarInterface, cls.CarController, cls.CarState = interfaces[cls.car_model] @@ -219,6 +239,14 @@ class TestCarModelBase(unittest.TestCase): self.safety.safety_tick_current_rx_checks() if t > 1e6: self.assertTrue(self.safety.addr_checks_valid()) + + # No need to check relay malfunction on disabled routes (relay closed) or for reasonable fingerprinting time + # TODO: detect when relay has flipped to properly check relay malfunction + if self.openpilot_enabled and t > 5e6: + self.assertFalse(self.safety.get_relay_malfunction()) + else: + self.safety.set_relay_malfunction(False) + self.assertFalse(len(failed_addrs), f"panda safety RX check failed: {failed_addrs}") def test_panda_safety_tx_cases(self, data=None): @@ -294,9 +322,7 @@ class TestCarModelBase(unittest.TestCase): # TODO: check rest of panda's carstate (steering, ACC main on, etc.) checks['gasPressed'] += CS.gasPressed != self.safety.get_gas_pressed_prev() - if self.CP.carName not in ("hyundai", "body"): - # TODO: fix standstill mismatches for other makes - checks['standstill'] += CS.standstill == self.safety.get_vehicle_moving() + checks['standstill'] += CS.standstill == self.safety.get_vehicle_moving() # TODO: remove this exception once this mismatch is resolved brake_pressed = CS.brakePressed @@ -316,6 +342,10 @@ class TestCarModelBase(unittest.TestCase): checks['controlsAllowed'] += not self.safety.get_controls_allowed() else: checks['controlsAllowed'] += not CS.cruiseState.enabled and self.safety.get_controls_allowed() + + # TODO: fix notCar mismatch + if not self.CP.notCar: + checks['cruiseState'] += CS.cruiseState.enabled != self.safety.get_cruise_engaged_prev() else: # Check for enable events on rising edge of controls allowed button_enable = any(evt.enable for evt in CS.events) diff --git a/selfdrive/car/tests/test_models_segs.txt b/selfdrive/car/tests/test_models_segs.txt index 68841af007..11c19685da 100644 --- a/selfdrive/car/tests/test_models_segs.txt +++ b/selfdrive/car/tests/test_models_segs.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:636df10e41e8c6668678a3aa7098afad8c160ea7b75c5a0473f6709db1c702dc -size 39373 +oid sha256:b93de5a9a259934896d8573d9b0f696289b88693908968009fe144e2e10a3355 +size 127597 diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index b35ceb0f1f..6be01c1c0e 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -4,7 +4,7 @@ from common.conversions import Conversions as CV from panda import Panda from selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \ MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR -from selfdrive.car import STD_CARGO_KG, scale_tire_stiffness, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase EventName = car.CarEvent.EventName @@ -48,8 +48,8 @@ class CarInterface(CarInterfaceBase): stop_and_go = True ret.wheelbase = 2.70 ret.steerRatio = 15.74 # unknown end-to-end spec - tire_stiffness_factor = 0.6371 # hand-tune - ret.mass = 3045. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.6371 # hand-tune + ret.mass = 3045. * CV.LB_TO_KG # Only give steer angle deadzone to for bad angle sensor prius for fw in car_fw: if fw.ecu == "eps" and not fw.fwVersion == b'8965B47060\x00\x00\x00\x00\x00\x00': @@ -60,50 +60,50 @@ class CarInterface(CarInterfaceBase): stop_and_go = True ret.wheelbase = 2.78 ret.steerRatio = 17.4 - tire_stiffness_factor = 0.5533 - ret.mass = 3340. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.5533 + ret.mass = 3340. * CV.LB_TO_KG elif candidate in (CAR.RAV4, CAR.RAV4H): stop_and_go = True if (candidate in CAR.RAV4H) else False ret.wheelbase = 2.65 ret.steerRatio = 16.88 # 14.5 is spec end-to-end - tire_stiffness_factor = 0.5533 - ret.mass = 3650. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.tireStiffnessFactor = 0.5533 + ret.mass = 3650. * CV.LB_TO_KG # mean between normal and hybrid elif candidate == CAR.COROLLA: ret.wheelbase = 2.70 ret.steerRatio = 18.27 - tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 2860. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.tireStiffnessFactor = 0.444 # not optimized yet + ret.mass = 2860. * CV.LB_TO_KG # mean between normal and hybrid elif candidate in (CAR.LEXUS_RX, CAR.LEXUS_RXH, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2): stop_and_go = True ret.wheelbase = 2.79 ret.steerRatio = 16. # 14.8 is spec end-to-end ret.wheelSpeedFactor = 1.035 - tire_stiffness_factor = 0.5533 - ret.mass = 4481. * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max + ret.tireStiffnessFactor = 0.5533 + ret.mass = 4481. * CV.LB_TO_KG # mean between min and max elif candidate in (CAR.CHR, CAR.CHRH, CAR.CHR_TSS2, CAR.CHRH_TSS2): stop_and_go = True ret.wheelbase = 2.63906 ret.steerRatio = 13.6 - tire_stiffness_factor = 0.7933 - ret.mass = 3300. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.7933 + ret.mass = 3300. * CV.LB_TO_KG elif candidate in (CAR.CAMRY, CAR.CAMRYH, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2): stop_and_go = True ret.wheelbase = 2.82448 ret.steerRatio = 13.7 - tire_stiffness_factor = 0.7933 - ret.mass = 3400. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.tireStiffnessFactor = 0.7933 + ret.mass = 3400. * CV.LB_TO_KG # mean between normal and hybrid elif candidate in (CAR.HIGHLANDER, CAR.HIGHLANDERH, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2): stop_and_go = True ret.wheelbase = 2.8194 # average of 109.8 and 112.2 in ret.steerRatio = 16.0 - tire_stiffness_factor = 0.8 - ret.mass = 4516. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.tireStiffnessFactor = 0.8 + ret.mass = 4516. * CV.LB_TO_KG # mean between normal and hybrid elif candidate in (CAR.AVALON, CAR.AVALON_2019, CAR.AVALONH_2019, CAR.AVALON_TSS2, CAR.AVALONH_TSS2): # starting from 2019, all Avalon variants have stop and go @@ -111,15 +111,15 @@ class CarInterface(CarInterfaceBase): stop_and_go = candidate != CAR.AVALON ret.wheelbase = 2.82 ret.steerRatio = 14.8 # Found at https://pressroom.toyota.com/releases/2016+avalon+product+specs.download - tire_stiffness_factor = 0.7983 - ret.mass = 3505. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid + ret.tireStiffnessFactor = 0.7983 + ret.mass = 3505. * CV.LB_TO_KG # mean between normal and hybrid elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.RAV4H_TSS2_2023): ret.wheelbase = 2.68986 ret.steerRatio = 14.3 - tire_stiffness_factor = 0.7933 - ret.mass = 3585. * CV.LB_TO_KG + STD_CARGO_KG # Average between ICE and Hybrid + ret.tireStiffnessFactor = 0.7933 + ret.mass = 3585. * CV.LB_TO_KG # Average between ICE and Hybrid ret.lateralTuning.init('pid') ret.lateralTuning.pid.kiBP = [0.0] ret.lateralTuning.pid.kpBP = [0.0] @@ -139,70 +139,64 @@ class CarInterface(CarInterfaceBase): elif candidate in (CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2): ret.wheelbase = 2.67 # Average between 2.70 for sedan and 2.64 for hatchback ret.steerRatio = 13.9 - tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 3060. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.444 # not optimized yet + ret.mass = 3060. * CV.LB_TO_KG elif candidate in (CAR.LEXUS_ES, CAR.LEXUS_ESH, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2): if candidate not in (CAR.LEXUS_ES,): # TODO: LEXUS_ES may have sng stop_and_go = True ret.wheelbase = 2.8702 ret.steerRatio = 16.0 # not optimized - tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 3677. * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max + ret.tireStiffnessFactor = 0.444 # not optimized yet + ret.mass = 3677. * CV.LB_TO_KG # mean between min and max elif candidate == CAR.SIENNA: stop_and_go = True ret.wheelbase = 3.03 ret.steerRatio = 15.5 - tire_stiffness_factor = 0.444 - ret.mass = 4590. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.444 + ret.mass = 4590. * CV.LB_TO_KG elif candidate in (CAR.LEXUS_IS, CAR.LEXUS_IS_TSS2, CAR.LEXUS_RC): ret.wheelbase = 2.79908 ret.steerRatio = 13.3 - tire_stiffness_factor = 0.444 - ret.mass = 3736.8 * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.444 + ret.mass = 3736.8 * CV.LB_TO_KG elif candidate == CAR.LEXUS_CTH: stop_and_go = True ret.wheelbase = 2.60 ret.steerRatio = 18.6 - tire_stiffness_factor = 0.517 - ret.mass = 3108 * CV.LB_TO_KG + STD_CARGO_KG # mean between min and max + ret.tireStiffnessFactor = 0.517 + ret.mass = 3108 * CV.LB_TO_KG # mean between min and max elif candidate in (CAR.LEXUS_NX, CAR.LEXUS_NXH, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2): stop_and_go = True ret.wheelbase = 2.66 ret.steerRatio = 14.7 - tire_stiffness_factor = 0.444 # not optimized yet - ret.mass = 4070 * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.444 # not optimized yet + ret.mass = 4070 * CV.LB_TO_KG elif candidate == CAR.PRIUS_TSS2: ret.wheelbase = 2.70002 # from toyota online sepc. ret.steerRatio = 13.4 # True steerRatio from older prius - tire_stiffness_factor = 0.6371 # hand-tune - ret.mass = 3115. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.6371 # hand-tune + ret.mass = 3115. * CV.LB_TO_KG elif candidate == CAR.MIRAI: stop_and_go = True ret.wheelbase = 2.91 ret.steerRatio = 14.8 - tire_stiffness_factor = 0.8 - ret.mass = 4300. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.8 + ret.mass = 4300. * CV.LB_TO_KG elif candidate in (CAR.ALPHARD_TSS2, CAR.ALPHARDH_TSS2): ret.wheelbase = 3.00 ret.steerRatio = 14.2 - tire_stiffness_factor = 0.444 - ret.mass = 4305. * CV.LB_TO_KG + STD_CARGO_KG + ret.tireStiffnessFactor = 0.444 + ret.mass = 4305. * CV.LB_TO_KG ret.centerToFront = ret.wheelbase * 0.44 - - # TODO: start from empirically derived lateral slip stiffness for the civic and scale by - # mass and CG position, so all cars will have approximately similar dyn behaviors - ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, - tire_stiffness_factor=tire_stiffness_factor) - ret.enableBsm = 0x3F6 in fingerprint[0] and candidate in TSS2_CAR # Detect smartDSU, which intercepts ACC_CMD from the DSU (or radar) allowing openpilot to send it diff --git a/selfdrive/car/toyota/radar_interface.py b/selfdrive/car/toyota/radar_interface.py index ad6238b601..378178f5c8 100755 --- a/selfdrive/car/toyota/radar_interface.py +++ b/selfdrive/car/toyota/radar_interface.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +from collections import defaultdict + from opendbc.can.parser import CANParser from cereal import car from selfdrive.car.toyota.values import DBC, TSS2_CAR @@ -15,7 +17,7 @@ def _create_radar_can_parser(car_fingerprint): msg_a_n = len(RADAR_A_MSGS) msg_b_n = len(RADAR_B_MSGS) - messages = list(zip(RADAR_A_MSGS + RADAR_B_MSGS, [20] * (msg_a_n + msg_b_n))) + messages = list(zip(RADAR_A_MSGS + RADAR_B_MSGS, [20] * (msg_a_n + msg_b_n), strict=True)) return CANParser(DBC[car_fingerprint]['radar'], messages, 1) @@ -36,34 +38,47 @@ class RadarInterface(RadarInterfaceBase): self.rcp = None if CP.radarUnavailable else _create_radar_can_parser(CP.carFingerprint) self.trigger_msg = self.RADAR_B_MSGS[-1] - self.updated_messages = set() + self.updated_values = defaultdict(lambda: defaultdict(list)) def update(self, can_strings): if self.rcp is None: - return super().update(None) - - vls = self.rcp.update_strings(can_strings) - self.updated_messages.update(vls) - - if self.trigger_msg not in self.updated_messages: return None - rr = self._update(self.updated_messages) - self.updated_messages.clear() + addresses = self.rcp.update_strings(can_strings) + for addr in addresses: + vals_dict = self.rcp.vl_all[addr] + for sig_name, vals in vals_dict.items(): + self.updated_values[addr][sig_name].extend(vals) - return rr + if self.trigger_msg not in self.updated_values: + return None - def _update(self, updated_messages): + radar_data = self._radar_msg_from_buffer(self.updated_values, self.rcp.can_valid) + self.updated_values.clear() + + return radar_data + + def _radar_msg_from_buffer(self, updated_values, can_valid): ret = car.RadarData.new_message() errors = [] - if not self.rcp.can_valid: + if not can_valid: errors.append("canError") ret.errors = errors - for ii in sorted(updated_messages): - if ii in self.RADAR_A_MSGS: - cpt = self.rcp.vl[ii] + for ii in sorted(updated_values): + if ii not in self.RADAR_A_MSGS: + continue + radar_a_msgs = updated_values[ii] + radar_b_msgs = updated_values[ii+16] + + n_vals_per_addr = len(list(radar_a_msgs.values())[0]) + cpts = [ + {k: v[i] for k, v in radar_a_msgs.items()} + for i in range(n_vals_per_addr) + ] + + for index, cpt in enumerate(cpts): if cpt['LONG_DIST'] >= 255 or cpt['NEW_TRACK']: self.valid_cnt[ii] = 0 # reset counter if cpt['VALID'] and cpt['LONG_DIST'] < 255: @@ -71,11 +86,15 @@ class RadarInterface(RadarInterfaceBase): else: self.valid_cnt[ii] = max(self.valid_cnt[ii] - 1, 0) - score = self.rcp.vl[ii+16]['SCORE'] - # print ii, self.valid_cnt[ii], score, cpt['VALID'], cpt['LONG_DIST'], cpt['LAT_DIST'] + n_b_scores = len(radar_b_msgs['SCORE']) + if n_b_scores > 0: + score_index = min(index, n_b_scores - 1) + score = radar_b_msgs['SCORE'][score_index] + else: + score = None # radar point only valid if it's a valid measurement and score is above 50 - if cpt['VALID'] or (score > 50 and cpt['LONG_DIST'] < 255 and self.valid_cnt[ii] > 0): + if cpt['VALID'] or (score and score > 50 and cpt['LONG_DIST'] < 255 and self.valid_cnt[ii] > 0): if ii not in self.pts or cpt['NEW_TRACK']: self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 2b0603f162..66b6239cb3 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -1,7 +1,7 @@ from cereal import car from panda import Panda from common.conversions import Conversions as CV -from selfdrive.car import STD_CARGO_KG, get_safety_config +from selfdrive.car import get_safety_config from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.volkswagen.values import CAR, PQ_CARS, CANBUS, NetworkLocation, TransmissionType, GearShifter @@ -101,32 +101,32 @@ class CarInterface(CarInterfaceBase): # Per-chassis tuning values, override tuning defaults here if desired if candidate == CAR.ARTEON_MK1: - ret.mass = 1733 + STD_CARGO_KG + ret.mass = 1733 ret.wheelbase = 2.84 elif candidate == CAR.ATLAS_MK1: - ret.mass = 2011 + STD_CARGO_KG + ret.mass = 2011 ret.wheelbase = 2.98 elif candidate == CAR.CRAFTER_MK2: - ret.mass = 2100 + STD_CARGO_KG + ret.mass = 2100 ret.wheelbase = 3.64 # SWB, LWB is 4.49, TBD how to detect difference ret.minSteerSpeed = 50 * CV.KPH_TO_MS elif candidate == CAR.GOLF_MK7: - ret.mass = 1397 + STD_CARGO_KG + ret.mass = 1397 ret.wheelbase = 2.62 elif candidate == CAR.JETTA_MK7: - ret.mass = 1328 + STD_CARGO_KG + ret.mass = 1328 ret.wheelbase = 2.71 elif candidate == CAR.PASSAT_MK8: - ret.mass = 1551 + STD_CARGO_KG + ret.mass = 1551 ret.wheelbase = 2.79 elif candidate == CAR.PASSAT_NMS: - ret.mass = 1503 + STD_CARGO_KG + ret.mass = 1503 ret.wheelbase = 2.80 ret.minEnableSpeed = 20 * CV.KPH_TO_MS # ACC "basic", no FtS ret.minSteerSpeed = 50 * CV.KPH_TO_MS @@ -134,86 +134,86 @@ class CarInterface(CarInterfaceBase): CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) elif candidate == CAR.POLO_MK6: - ret.mass = 1230 + STD_CARGO_KG + ret.mass = 1230 ret.wheelbase = 2.55 elif candidate == CAR.SHARAN_MK2: - ret.mass = 1639 + STD_CARGO_KG + ret.mass = 1639 ret.wheelbase = 2.92 ret.minSteerSpeed = 50 * CV.KPH_TO_MS ret.steerActuatorDelay = 0.2 elif candidate == CAR.TAOS_MK1: - ret.mass = 1498 + STD_CARGO_KG + ret.mass = 1498 ret.wheelbase = 2.69 elif candidate == CAR.TCROSS_MK1: - ret.mass = 1150 + STD_CARGO_KG + ret.mass = 1150 ret.wheelbase = 2.60 elif candidate == CAR.TIGUAN_MK2: - ret.mass = 1715 + STD_CARGO_KG + ret.mass = 1715 ret.wheelbase = 2.74 elif candidate == CAR.TOURAN_MK2: - ret.mass = 1516 + STD_CARGO_KG + ret.mass = 1516 ret.wheelbase = 2.79 elif candidate == CAR.TRANSPORTER_T61: - ret.mass = 1926 + STD_CARGO_KG + ret.mass = 1926 ret.wheelbase = 3.00 # SWB, LWB is 3.40, TBD how to detect difference ret.minSteerSpeed = 14.0 elif candidate == CAR.TROC_MK1: - ret.mass = 1413 + STD_CARGO_KG + ret.mass = 1413 ret.wheelbase = 2.63 elif candidate == CAR.AUDI_A3_MK3: - ret.mass = 1335 + STD_CARGO_KG + ret.mass = 1335 ret.wheelbase = 2.61 elif candidate == CAR.AUDI_Q2_MK1: - ret.mass = 1205 + STD_CARGO_KG + ret.mass = 1205 ret.wheelbase = 2.61 elif candidate == CAR.AUDI_Q3_MK2: - ret.mass = 1623 + STD_CARGO_KG + ret.mass = 1623 ret.wheelbase = 2.68 elif candidate == CAR.SEAT_ATECA_MK1: - ret.mass = 1900 + STD_CARGO_KG + ret.mass = 1900 ret.wheelbase = 2.64 elif candidate == CAR.SEAT_LEON_MK3: - ret.mass = 1227 + STD_CARGO_KG + ret.mass = 1227 ret.wheelbase = 2.64 elif candidate == CAR.SKODA_FABIA_MK4: - ret.mass = 1266 + STD_CARGO_KG + ret.mass = 1266 ret.wheelbase = 2.56 elif candidate == CAR.SKODA_KAMIQ_MK1: - ret.mass = 1265 + STD_CARGO_KG + ret.mass = 1265 ret.wheelbase = 2.66 elif candidate == CAR.SKODA_KAROQ_MK1: - ret.mass = 1278 + STD_CARGO_KG + ret.mass = 1278 ret.wheelbase = 2.66 elif candidate == CAR.SKODA_KODIAQ_MK1: - ret.mass = 1569 + STD_CARGO_KG + ret.mass = 1569 ret.wheelbase = 2.79 elif candidate == CAR.SKODA_OCTAVIA_MK3: - ret.mass = 1388 + STD_CARGO_KG + ret.mass = 1388 ret.wheelbase = 2.68 elif candidate == CAR.SKODA_SCALA_MK1: - ret.mass = 1192 + STD_CARGO_KG + ret.mass = 1192 ret.wheelbase = 2.65 elif candidate == CAR.SKODA_SUPERB_MK3: - ret.mass = 1505 + STD_CARGO_KG + ret.mass = 1505 ret.wheelbase = 2.84 else: diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 3a6ed0e30c..bc129f79cc 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -458,6 +458,7 @@ FW_VERSIONS = { b'\xf1\x878V0906259H \xf1\x890002', b'\xf1\x878V0906259J \xf1\x890003', b'\xf1\x878V0906259K \xf1\x890001', + b'\xf1\x878V0906259K \xf1\x890003', b'\xf1\x878V0906259P \xf1\x890001', b'\xf1\x878V0906259Q \xf1\x890002', b'\xf1\x878V0906264F \xf1\x890003', @@ -486,6 +487,7 @@ FW_VERSIONS = { b'\xf1\x870D9300012 \xf1\x894913', b'\xf1\x870D9300012 \xf1\x894937', b'\xf1\x870D9300012 \xf1\x895045', + b'\xf1\x870D9300012 \xf1\x895046', b'\xf1\x870D9300014M \xf1\x895004', b'\xf1\x870D9300014Q \xf1\x895006', b'\xf1\x870D9300020J \xf1\x894902', @@ -953,6 +955,7 @@ FW_VERSIONS = { b'\xf1\x875G0906259D \xf1\x890002', b'\xf1\x875G0906259L \xf1\x890002', b'\xf1\x875G0906259Q \xf1\x890002', + b'\xf1\x878V0906259E \xf1\x890001', b'\xf1\x878V0906259F \xf1\x890002', b'\xf1\x878V0906259H \xf1\x890002', b'\xf1\x878V0906259J \xf1\x890002', @@ -967,6 +970,7 @@ FW_VERSIONS = { b'\xf1\x870CW300048 \xf1\x895201', b'\xf1\x870D9300012 \xf1\x894912', b'\xf1\x870D9300012 \xf1\x894931', + b'\xf1\x870D9300012L \xf1\x894521', b'\xf1\x870D9300012K \xf1\x894513', b'\xf1\x870D9300013B \xf1\x894902', b'\xf1\x870D9300013B \xf1\x894931', @@ -997,6 +1001,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655N \xf1\x890361\xf1\x82\0211212001112111104110411111521159114', ], (Ecu.eps, 0x712, None): [ + b'\xf1\x873Q0909144F \xf1\x895043\xf1\x82\x0561G01A13A0', b'\xf1\x873Q0909144H \xf1\x895061\xf1\x82\00566G0HA14A1', b'\xf1\x873Q0909144J \xf1\x895063\xf1\x82\x0566G0HA14A1', b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571G01A16A1', @@ -1012,6 +1017,7 @@ FW_VERSIONS = { b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\00521G00807A1', ], (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x875Q0907567M \xf1\x890398\xf1\x82\x0101', b'\xf1\x875Q0907567N \xf1\x890400\xf1\x82\x0101', b'\xf1\x875Q0907572F \xf1\x890400\xf1\x82\x0101', b'\xf1\x875Q0907572D \xf1\x890304\xf1\x82\x0101', diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index e552e18966..0230a5775c 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -238,7 +238,7 @@ def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.S f"Steer Unavailable Below {get_display_speed(CP.minSteerSpeed, metric)}", "", AlertStatus.userPrompt, AlertSize.small, - Priority.MID, VisualAlert.steerRequired, AudibleAlert.prompt, 0.4) + Priority.LOW, VisualAlert.steerRequired, AudibleAlert.prompt, 0.4) def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: @@ -505,7 +505,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { "Press Resume to Exit Standstill", "", AlertStatus.userPrompt, AlertSize.small, - Priority.LOW, VisualAlert.none, AudibleAlert.none, .2), + Priority.MID, VisualAlert.none, AudibleAlert.none, .2), }, EventName.belowSteerSpeed: { diff --git a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py b/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py index 2a58a8667f..6afcb99dab 100755 --- a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py +++ b/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py @@ -129,11 +129,15 @@ def gen_lat_ocp(): class LateralMpc(): - def __init__(self, x0=np.zeros(X_DIM)): + def __init__(self, x0=None): + if x0 is None: + x0 = np.zeros(X_DIM) self.solver = AcadosOcpSolverCython(MODEL_NAME, ACADOS_SOLVER_TYPE, N) self.reset(x0) - def reset(self, x0=np.zeros(X_DIM)): + def reset(self, x0=None): + if x0 is None: + x0 = np.zeros(X_DIM) self.x_sol = np.zeros((N+1, X_DIM)) self.u_sol = np.zeros((N, 1)) self.yref = np.zeros((N+1, COST_DIM)) diff --git a/selfdrive/controls/lib/lateral_planner.py b/selfdrive/controls/lib/lateral_planner.py index 5914312420..38258b4b5d 100644 --- a/selfdrive/controls/lib/lateral_planner.py +++ b/selfdrive/controls/lib/lateral_planner.py @@ -50,7 +50,9 @@ class LateralPlanner: self.lat_mpc = LateralMpc() self.reset_mpc(np.zeros(4)) - def reset_mpc(self, x0=np.zeros(4)): + def reset_mpc(self, x0=None): + if x0 is None: + x0 = np.zeros(4) self.x0 = x0 self.lat_mpc.reset(x0=self.x0) @@ -130,7 +132,7 @@ class LateralPlanner: lateralPlan.psis = self.lat_mpc.x_sol[0:CONTROL_N, 2].tolist() lateralPlan.curvatures = (self.lat_mpc.x_sol[0:CONTROL_N, 3]/self.v_ego).tolist() - lateralPlan.curvatureRates = [float(x/self.v_ego) for x in self.lat_mpc.u_sol[0:CONTROL_N - 1]] + [0.0] + lateralPlan.curvatureRates = [float(x.item() / self.v_ego) for x in self.lat_mpc.u_sol[0:CONTROL_N - 1]] + [0.0] lateralPlan.mpcSolutionValid = bool(plan_solution_valid) lateralPlan.solverExecutionTime = self.lat_mpc.solve_time diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index afc400ede8..dadf6cba28 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -83,7 +83,9 @@ def get_stopped_equivalence_factor(v_lead): def get_safe_obstacle_distance(v_ego, t_follow): return (v_ego**2) / (2 * COMFORT_BRAKE) + t_follow * v_ego + STOP_DISTANCE -def desired_follow_distance(v_ego, v_lead, t_follow=get_T_FOLLOW()): +def desired_follow_distance(v_ego, v_lead, t_follow=None): + if t_follow is None: + t_follow = get_T_FOLLOW() return get_safe_obstacle_distance(v_ego, t_follow) - get_stopped_equivalence_factor(v_lead) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index cce866a093..303bbaaafe 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -8,7 +8,7 @@ import capnp from cereal import messaging, log, car from common.numpy_fast import interp from common.params import Params -from common.realtime import Ratekeeper, Priority, config_realtime_process +from common.realtime import Ratekeeper, Priority, config_realtime_process, DT_MDL from system.swaglog import cloudlog from common.kalman.simple_kalman import KF1D @@ -50,7 +50,8 @@ class KalmanParams: class Track: - def __init__(self, v_lead: float, kalman_params: KalmanParams): + def __init__(self, identifier: int, v_lead: float, kalman_params: KalmanParams): + self.identifier = identifier self.cnt = 0 self.aLeadTau = _LEAD_ACCEL_TAU self.K_A = kalman_params.A @@ -63,9 +64,13 @@ class Track: self.dRel = d_rel # LONG_DIST self.yRel = y_rel # -LAT_DIST self.vRel = v_rel # REL_SPEED - self.vLead = v_lead self.measured = measured # measured or estimate + self.update_vlead(v_lead) + + def update_vlead(self, v_lead: float): + self.vLead = v_lead + # computed velocity and accelerations if self.cnt > 0: self.kf.update(self.vLead) @@ -98,11 +103,12 @@ class Track: "vLead": float(self.vLead), "vLeadK": float(self.vLeadK), "aLeadK": float(self.aLeadK), + "aLeadTau": float(self.aLeadTau), "status": True, "fcw": self.is_potential_fcw(model_prob), "modelProb": model_prob, "radar": True, - "aLeadTau": float(self.aLeadTau) + "radarTrackId": self.identifier, } def potential_low_speed_lead(self, v_ego: float): @@ -158,15 +164,17 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa "aLeadTau": 0.3, "fcw": False, "modelProb": float(lead_msg.prob), + "status": True, "radar": False, - "status": True + "radarTrackId": -1, } def get_lead(v_ego: float, ready: bool, tracks: Dict[int, Track], lead_msg: capnp._DynamicStructReader, model_v_ego: float, low_speed_override: bool = True) -> Dict[str, Any]: # Determine leads, this is where the essential logic happens - if len(tracks) > 0 and ready and lead_msg.prob > .5: + lead_msg_empty = any(len(c) == 0 for c in [lead_msg.x, lead_msg.y, lead_msg.v]) + if len(tracks) > 0 and ready and not lead_msg_empty and lead_msg.prob > .5: track = match_vision_to_track(v_ego, lead_msg, tracks) else: track = None @@ -174,7 +182,7 @@ def get_lead(v_ego: float, ready: bool, tracks: Dict[int, Track], lead_msg: capn lead_dict = {'status': False} if track is not None: lead_dict = track.get_RadarState(lead_msg.prob) - elif (track is None) and ready and (lead_msg.prob > .5): + elif track is None and ready and not lead_msg_empty and lead_msg.prob > .5: lead_dict = get_RadarState_from_vision(lead_msg, v_ego, model_v_ego) if low_speed_override: @@ -204,14 +212,14 @@ class RadarD: self.ready = False - def update(self, sm: messaging.SubMaster, rr: Optional[car.RadarData]): + def update(self, sm: messaging.SubMaster, radar_data: Optional[car.RadarData]): self.current_time = 1e-9*max(sm.logMonoTime.values()) radar_points = [] radar_errors = [] - if rr is not None: - radar_points = rr.points - radar_errors = rr.errors + if radar_data is not None: + radar_points = radar_data.points + radar_errors = radar_data.errors if sm.updated['carState']: self.v_ego = sm['carState'].vEgo @@ -219,26 +227,32 @@ class RadarD: if sm.updated['modelV2']: self.ready = True - ar_pts = {} - for pt in radar_points: - ar_pts[pt.trackId] = [pt.dRel, pt.yRel, pt.vRel, pt.measured] + if radar_data is not None: + ar_pts = {} + for pt in radar_points: + ar_pts[pt.trackId] = [pt.dRel, pt.yRel, pt.vRel, pt.measured] - # *** remove missing points from meta data *** - for ids in list(self.tracks.keys()): - if ids not in ar_pts: - self.tracks.pop(ids, None) + # *** remove missing points from meta data *** + for ids in list(self.tracks.keys()): + if ids not in ar_pts: + self.tracks.pop(ids, None) - # *** compute the tracks *** - for ids in ar_pts: - rpt = ar_pts[ids] + # *** compute the tracks *** + for ids in ar_pts: + rpt = ar_pts[ids] - # align v_ego by a fixed time to align it with the radar measurement - v_lead = rpt[2] + self.v_ego_hist[0] + # align v_ego by a fixed time to align it with the radar measurement + v_lead = rpt[2] + self.v_ego_hist[0] - # create the track if it doesn't exist or it's a new track - if ids not in self.tracks: - self.tracks[ids] = Track(v_lead, self.kalman_params) - self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead, rpt[3]) + # create the track if it doesn't exist or it's a new track + if ids not in self.tracks: + self.tracks[ids] = Track(ids, v_lead, self.kalman_params) + self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead, rpt[3]) + else: + # *** no radar points, keep existing tracks, update v_lead + for track in self.tracks.values(): + v_lead = track.vRel + self.v_ego_hist[0] + track.update_vlead(v_lead) # *** publish radarState *** self.radar_state_valid = sm.all_checks() and len(radar_errors) == 0 @@ -291,32 +305,33 @@ def radard_thread(sm: Optional[messaging.SubMaster] = None, pm: Optional[messagi cloudlog.info("radard is importing %s", CP.carName) RadarInterface = importlib.import_module(f'selfdrive.car.{CP.carName}.radar_interface').RadarInterface - # *** setup messaging + # setup messaging if can_sock is None: can_sock = messaging.sub_sock('can') if sm is None: - sm = messaging.SubMaster(['modelV2', 'carState'], ignore_avg_freq=['modelV2', 'carState']) # Can't check average frequency, since radar determines timing + sm = messaging.SubMaster(['modelV2', 'carState'], poll=["modelV2"]) if pm is None: pm = messaging.PubMaster(['radarState', 'liveTracks']) - RI = RadarInterface(CP) + interface = RadarInterface(CP) - rk = Ratekeeper(1.0 / CP.radarTimeStep, print_delay_threshold=None) - RD = RadarD(CP.radarTimeStep, RI.delay) + rk = Ratekeeper(1 / DT_MDL, print_delay_threshold=None) + radar = RadarD(DT_MDL, interface.delay) - while 1: - can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True) - rr = RI.update(can_strings) + while True: + sm.update() - if rr is None: - continue + if sm.updated['modelV2']: + can_strings = messaging.drain_sock_raw(can_sock) + if len(can_strings) == 0: + radar_data = None + else: + radar_data = interface.update(can_strings) - sm.update(0) + radar.update(sm, radar_data) + radar.publish(pm, -rk.remaining*1000.0) - RD.update(sm, rr) - RD.publish(pm, -rk.remaining*1000.0) - - rk.monitor_time() + rk.monitor_time() def main(sm: Optional[messaging.SubMaster] = None, pm: Optional[messaging.PubMaster] = None, can_sock: messaging.SubSocket = None): diff --git a/selfdrive/controls/tests/test_clustering.py b/selfdrive/controls/tests/test_clustering.py deleted file mode 100644 index 99c24d5938..0000000000 --- a/selfdrive/controls/tests/test_clustering.py +++ /dev/null @@ -1,140 +0,0 @@ -# pylint: skip-file - -import time -import unittest -import numpy as np -from fastcluster import linkage_vector -from scipy.cluster import _hierarchy -from scipy.spatial.distance import pdist - -from third_party.cluster.fastcluster_py import hclust, ffi -from third_party.cluster.fastcluster_py import cluster_points_centroid - - -def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): - # supersimplified function to get fast clustering. Got it from scipy - Z = np.asarray(Z, order='c') - n = Z.shape[0] + 1 - T = np.zeros((n,), dtype='i') - _hierarchy.cluster_dist(Z, T, float(t), int(n)) - return T - - -TRACK_PTS = np.array([[59.26000137, -9.35999966, -5.42500019], - [91.61999817, -0.31999999, -2.75], - [31.38000031, 0.40000001, -0.2], - [89.57999725, -8.07999992, -18.04999924], - [53.42000122, 0.63999999, -0.175], - [31.38000031, 0.47999999, -0.2], - [36.33999939, 0.16, -0.2], - [53.33999939, 0.95999998, -0.175], - [59.26000137, -9.76000023, -5.44999981], - [33.93999977, 0.40000001, -0.22499999], - [106.74000092, -5.76000023, -18.04999924]]) - -CORRECT_LINK = np.array([[2., 5., 0.07999998, 2.], - [4., 7., 0.32984889, 2.], - [0., 8., 0.40078104, 2.], - [6., 9., 2.41209933, 2.], - [11., 14., 3.76342275, 4.], - [12., 13., 13.02297651, 4.], - [1., 3., 17.27626057, 2.], - [10., 17., 17.92918845, 3.], - [15., 16., 23.68525366, 8.], - [18., 19., 52.52351319, 11.]]) - -CORRECT_LABELS = np.array([7, 1, 4, 2, 6, 4, 5, 6, 7, 5, 3], dtype=np.int32) - - -def plot_cluster(pts, idx_old, idx_new): - import matplotlib.pyplot as plt - m = 'Set1' - - plt.figure() - plt.subplot(1, 2, 1) - plt.scatter(pts[:, 0], pts[:, 1], c=idx_old, cmap=m) - plt.title("Old") - plt.colorbar() - plt.subplot(1, 2, 2) - plt.scatter(pts[:, 0], pts[:, 1], c=idx_new, cmap=m) - plt.title("New") - plt.colorbar() - - plt.show() - - -def same_clusters(correct, other): - correct = np.asarray(correct) - other = np.asarray(other) - if len(correct) != len(other): - return False - - for i in range(len(correct)): - c = np.where(correct == correct[i]) - o = np.where(other == other[i]) - if not np.array_equal(c, o): - return False - return True - - -class TestClustering(unittest.TestCase): - def test_scipy_clustering(self): - old_link = linkage_vector(TRACK_PTS, method='centroid') - old_cluster_idxs = fcluster(old_link, 2.5, criterion='distance') - - np.testing.assert_allclose(old_link, CORRECT_LINK) - np.testing.assert_allclose(old_cluster_idxs, CORRECT_LABELS) - - def test_pdist(self): - pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) - pts_ptr = ffi.cast("double *", pts.ctypes.data) - - n, m = pts.shape - out = np.zeros((n * (n - 1) // 2, ), dtype=np.float64) - out_ptr = ffi.cast("double *", out.ctypes.data) - hclust.hclust_pdist(n, m, pts_ptr, out_ptr) - - np.testing.assert_allclose(out, np.power(pdist(TRACK_PTS), 2)) - - def test_cpp_clustering(self): - pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) - pts_ptr = ffi.cast("double *", pts.ctypes.data) - n, m = pts.shape - - labels = np.zeros((n, ), dtype=np.int32) - labels_ptr = ffi.cast("int *", labels.ctypes.data) - hclust.cluster_points_centroid(n, m, pts_ptr, 2.5**2, labels_ptr) - self.assertTrue(same_clusters(CORRECT_LABELS, labels)) - - def test_cpp_wrapper_clustering(self): - labels = cluster_points_centroid(TRACK_PTS, 2.5) - self.assertTrue(same_clusters(CORRECT_LABELS, labels)) - - def test_random_cluster(self): - np.random.seed(1337) - N = 1000 - - t_old = 0. - t_new = 0. - - for _ in range(N): - n = int(np.random.uniform(2, 32)) - x = np.random.uniform(-10, 50, (n, 1)) - y = np.random.uniform(-5, 5, (n, 1)) - vrel = np.random.uniform(-5, 5, (n, 1)) - pts = np.hstack([x, y, vrel]) - - t = time.time() - old_link = linkage_vector(pts, method='centroid') - old_cluster_idx = fcluster(old_link, 2.5, criterion='distance') - t_old += time.time() - t - - t = time.time() - cluster_idx = cluster_points_centroid(pts, 2.5) - t_new += time.time() - t - - self.assertTrue(same_clusters(old_cluster_idx, cluster_idx)) - - -if __name__ == "__main__": - unittest.main() diff --git a/selfdrive/debug/check_can_parser_performance.py b/selfdrive/debug/check_can_parser_performance.py new file mode 100755 index 0000000000..4b430e013f --- /dev/null +++ b/selfdrive/debug/check_can_parser_performance.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +import numpy as np +import time +from tqdm import tqdm + +from cereal import car +from selfdrive.car.tests.routes import CarTestRoute +from selfdrive.car.tests.test_models import TestCarModelBase +from tools.plotjuggler.juggle import DEMO_ROUTE + +N_RUNS = 10 + + +class CarModelTestCase(TestCarModelBase): + test_route = CarTestRoute(DEMO_ROUTE, None) + ci = False + + +if __name__ == '__main__': + # Get CAN messages and parsers + tm = CarModelTestCase() + tm.setUpClass() + tm.setUp() + + CC = car.CarControl.new_message() + ets = [] + for _ in tqdm(range(N_RUNS)): + start_t = time.process_time_ns() + for msg in tm.can_msgs: + for cp in tm.CI.can_parsers: + if cp is not None: + cp.update_strings((msg.as_builder().to_bytes(),)) + ets.append((time.process_time_ns() - start_t) * 1e-6) + + print(f'{len(tm.can_msgs)} CAN packets, {N_RUNS} runs') + print(f'{np.mean(ets):.2f} mean ms, {max(ets):.2f} max ms, {min(ets):.2f} min ms, {np.std(ets):.2f} std ms') + print(f'{np.mean(ets) / len(tm.can_msgs):.4f} mean ms / CAN packet') diff --git a/selfdrive/debug/filter_log_message.py b/selfdrive/debug/filter_log_message.py index af52953936..8d9ce8e6a2 100755 --- a/selfdrive/debug/filter_log_message.py +++ b/selfdrive/debug/filter_log_message.py @@ -59,7 +59,7 @@ if __name__ == "__main__": logs = [args.route[0]] else: r = Route(args.route[0]) - logs = [q_log if r_log is None else r_log for (q_log, r_log) in zip(r.qlog_paths(), r.log_paths())] + logs = [q_log if r_log is None else r_log for (q_log, r_log) in zip(r.qlog_paths(), r.log_paths(), strict=True)] if len(args.route) == 2 and logs: n = int(args.route[1]) diff --git a/selfdrive/debug/internal/fuzz_fw_fingerprint.py b/selfdrive/debug/internal/fuzz_fw_fingerprint.py index a18390fef3..8209bbf4ce 100755 --- a/selfdrive/debug/internal/fuzz_fw_fingerprint.py +++ b/selfdrive/debug/internal/fuzz_fw_fingerprint.py @@ -27,7 +27,7 @@ if __name__ == "__main__": for _ in tqdm(range(1000)): for candidate, fws in FWS.items(): fw_dict = {} - for (tp, addr, subaddr), fw_list in fws.items(): + for (_, addr, subaddr), fw_list in fws.items(): fw_dict[(addr, subaddr)] = [random.choice(fw_list)] matches = match_fw_to_car_fuzzy(fw_dict, log=False, exclude=candidate) diff --git a/selfdrive/debug/internal/qlog_size.py b/selfdrive/debug/internal/qlog_size.py index a98a71181d..be9ab5b17e 100755 --- a/selfdrive/debug/internal/qlog_size.py +++ b/selfdrive/debug/internal/qlog_size.py @@ -27,7 +27,7 @@ def make_pie(msgs, typ): sizes_large = [(k, sz) for (k, sz) in sizes if sz >= total * MIN_SIZE / 100] sizes_large += [('other', sum(sz for (_, sz) in sizes if sz < total * MIN_SIZE / 100))] - labels, sizes = zip(*sizes_large) + labels, sizes = zip(*sizes_large, strict=True) plt.figure() plt.title(f"{typ}") diff --git a/selfdrive/locationd/models/loc_kf.py b/selfdrive/locationd/models/loc_kf.py index 12f3cb7d00..d865509e95 100755 --- a/selfdrive/locationd/models/loc_kf.py +++ b/selfdrive/locationd/models/loc_kf.py @@ -191,9 +191,9 @@ class LocKalman(): # Observation matrix modifier H_mod_sym = sp.Matrix(np.zeros((dim_state, dim_state_err))) - for p_idx, p_err_idx in zip(p_idxs, p_err_idxs): + for p_idx, p_err_idx in zip(p_idxs, p_err_idxs, strict=True): H_mod_sym[p_idx[0]:p_idx[1], p_err_idx[0]:p_err_idx[1]] = np.eye(p_idx[1] - p_idx[0]) - for q_idx, q_err_idx in zip(q_idxs, q_err_idxs): + for q_idx, q_err_idx in zip(q_idxs, q_err_idxs, strict=True): H_mod_sym[q_idx[0]:q_idx[1], q_err_idx[0]:q_err_idx[1]] = 0.5 * quat_matrix_r(state[q_idx[0]:q_idx[1]])[:, 1:] # these error functions are defined so that say there @@ -205,17 +205,17 @@ class LocKalman(): delta_x = sp.MatrixSymbol('delta_x', dim_state_err, 1) err_function_sym = sp.Matrix(np.zeros((dim_state, 1))) - for q_idx, q_err_idx in zip(q_idxs, q_err_idxs): + for q_idx, q_err_idx in zip(q_idxs, q_err_idxs, strict=True): delta_quat = sp.Matrix(np.ones(4)) delta_quat[1:, :] = sp.Matrix(0.5 * delta_x[q_err_idx[0]: q_err_idx[1], :]) err_function_sym[q_idx[0]:q_idx[1], 0] = quat_matrix_r(nom_x[q_idx[0]:q_idx[1], 0]) * delta_quat - for p_idx, p_err_idx in zip(p_idxs, p_err_idxs): + for p_idx, p_err_idx in zip(p_idxs, p_err_idxs, strict=True): err_function_sym[p_idx[0]:p_idx[1], :] = sp.Matrix(nom_x[p_idx[0]:p_idx[1], :] + delta_x[p_err_idx[0]:p_err_idx[1], :]) inv_err_function_sym = sp.Matrix(np.zeros((dim_state_err, 1))) - for p_idx, p_err_idx in zip(p_idxs, p_err_idxs): + for p_idx, p_err_idx in zip(p_idxs, p_err_idxs, strict=True): inv_err_function_sym[p_err_idx[0]:p_err_idx[1], 0] = sp.Matrix(-nom_x[p_idx[0]:p_idx[1], 0] + true_x[p_idx[0]:p_idx[1], 0]) - for q_idx, q_err_idx in zip(q_idxs, q_err_idxs): + for q_idx, q_err_idx in zip(q_idxs, q_err_idxs, strict=True): delta_quat = quat_matrix_r(nom_x[q_idx[0]:q_idx[1], 0]).T * true_x[q_idx[0]:q_idx[1], 0] inv_err_function_sym[q_err_idx[0]:q_err_idx[1], 0] = sp.Matrix(2 * delta_quat[1:]) diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index de1265f0d7..1644ceaf92 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -85,8 +85,8 @@ class ParamsLearner: # We observe the current stiffness and steer ratio (with a high observation noise) to bound # the respective estimate STD. Otherwise the STDs keep increasing, causing rapid changes in the # states in longer routes (especially straight stretches). - stiffness = float(self.kf.x[States.STIFFNESS]) - steer_ratio = float(self.kf.x[States.STEER_RATIO]) + stiffness = float(self.kf.x[States.STIFFNESS].item()) + steer_ratio = float(self.kf.x[States.STEER_RATIO].item()) self.kf.predict_and_observe(t, ObservationKind.STIFFNESS, np.array([[stiffness]])) self.kf.predict_and_observe(t, ObservationKind.STEER_RATIO, np.array([[steer_ratio]])) @@ -198,14 +198,14 @@ def main(sm=None, pm=None): learner = ParamsLearner(CP, CP.steerRatio, 1.0, 0.0) x = learner.kf.x - angle_offset_average = clip(math.degrees(x[States.ANGLE_OFFSET]), + angle_offset_average = clip(math.degrees(x[States.ANGLE_OFFSET].item()), angle_offset_average - MAX_ANGLE_OFFSET_DELTA, angle_offset_average + MAX_ANGLE_OFFSET_DELTA) - angle_offset = clip(math.degrees(x[States.ANGLE_OFFSET] + x[States.ANGLE_OFFSET_FAST]), + angle_offset = clip(math.degrees(x[States.ANGLE_OFFSET].item() + x[States.ANGLE_OFFSET_FAST].item()), angle_offset - MAX_ANGLE_OFFSET_DELTA, angle_offset + MAX_ANGLE_OFFSET_DELTA) - roll = clip(float(x[States.ROAD_ROLL]), roll - ROLL_MAX_DELTA, roll + ROLL_MAX_DELTA) - roll_std = float(P[States.ROAD_ROLL]) + roll = clip(float(x[States.ROAD_ROLL].item()), roll - ROLL_MAX_DELTA, roll + ROLL_MAX_DELTA) + roll_std = float(P[States.ROAD_ROLL].item()) # Account for the opposite signs of the yaw rates - sensors_valid = bool(abs(learner.speed * (x[States.YAW_RATE] + learner.yaw_rate)) < LATERAL_ACC_SENSOR_THRESHOLD) + sensors_valid = bool(abs(learner.speed * (x[States.YAW_RATE].item() + learner.yaw_rate)) < LATERAL_ACC_SENSOR_THRESHOLD) avg_offset_valid = check_valid_with_hysteresis(avg_offset_valid, angle_offset_average, OFFSET_MAX, OFFSET_LOWERED_MAX) total_offset_valid = check_valid_with_hysteresis(total_offset_valid, angle_offset, OFFSET_MAX, OFFSET_LOWERED_MAX) roll_valid = check_valid_with_hysteresis(roll_valid, roll, ROLL_MAX, ROLL_LOWERED_MAX) @@ -215,8 +215,8 @@ def main(sm=None, pm=None): liveParameters = msg.liveParameters liveParameters.posenetValid = True liveParameters.sensorValid = sensors_valid - liveParameters.steerRatio = float(x[States.STEER_RATIO]) - liveParameters.stiffnessFactor = float(x[States.STIFFNESS]) + liveParameters.steerRatio = float(x[States.STEER_RATIO].item()) + liveParameters.stiffnessFactor = float(x[States.STIFFNESS].item()) liveParameters.roll = roll liveParameters.angleOffsetAverageDeg = angle_offset_average liveParameters.angleOffsetDeg = angle_offset @@ -228,10 +228,10 @@ def main(sm=None, pm=None): 0.2 <= liveParameters.stiffnessFactor <= 5.0, min_sr <= liveParameters.steerRatio <= max_sr, )) - liveParameters.steerRatioStd = float(P[States.STEER_RATIO]) - liveParameters.stiffnessFactorStd = float(P[States.STIFFNESS]) - liveParameters.angleOffsetAverageStd = float(P[States.ANGLE_OFFSET]) - liveParameters.angleOffsetFastStd = float(P[States.ANGLE_OFFSET_FAST]) + liveParameters.steerRatioStd = float(P[States.STEER_RATIO].item()) + liveParameters.stiffnessFactorStd = float(P[States.STIFFNESS].item()) + liveParameters.angleOffsetAverageStd = float(P[States.ANGLE_OFFSET].item()) + liveParameters.angleOffsetFastStd = float(P[States.ANGLE_OFFSET_FAST].item()) if DEBUG: liveParameters.filterState = log.LiveLocationKalman.Measurement.new_message() liveParameters.filterState.value = x.tolist() diff --git a/selfdrive/locationd/test/test_laikad.py b/selfdrive/locationd/test/test_laikad.py index bf314e9be8..c90095cdca 100755 --- a/selfdrive/locationd/test/test_laikad.py +++ b/selfdrive/locationd/test/test_laikad.py @@ -173,7 +173,7 @@ class TestLaikad(unittest.TestCase): self.assertTrue(kf_valid) def test_laika_online_nav_only(self): - for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]): + for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs], strict=True): laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.NAV, use_qcom=use_qcom) # Disable fetch_orbits to test NAV only correct_msgs = verify_messages(logs, laikad) @@ -215,7 +215,7 @@ class TestLaikad(unittest.TestCase): def test_get_navs_in_process(self): for auto_fetch_navs in [True, False]: - for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]): + for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs], strict=True): laikad = Laikad(auto_update=False, use_qcom=use_qcom, auto_fetch_navs=auto_fetch_navs) has_navs = False has_fix = False @@ -248,7 +248,7 @@ class TestLaikad(unittest.TestCase): def test_cache(self): use_qcom = True - for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]): + for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs], strict=True): Params().remove(EPHEMERIS_CACHE) laikad = Laikad(auto_update=True, save_ephemeris=True, use_qcom=use_qcom) def wait_for_cache(): diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py index 66898bd163..2bac2a8988 100755 --- a/selfdrive/locationd/torqued.py +++ b/selfdrive/locationd/torqued.py @@ -63,7 +63,7 @@ class PointBuckets: def __init__(self, x_bounds, min_points, min_points_total): self.x_bounds = x_bounds self.buckets = {bounds: NPQueue(maxlen=POINTS_PER_BUCKET, rowsize=3) for bounds in x_bounds} - self.buckets_min_points = dict(zip(x_bounds, min_points)) + self.buckets_min_points = dict(zip(x_bounds, min_points, strict=True)) self.min_points_total = min_points_total def bucket_lengths(self): @@ -73,7 +73,8 @@ class PointBuckets: return sum(self.bucket_lengths()) def is_valid(self): - return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values())) and (self.__len__() >= self.min_points_total) + return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values(), strict=True)) \ + and (self.__len__() >= self.min_points_total) def add_point(self, x, y): for bound_min, bound_max in self.x_bounds: diff --git a/selfdrive/manager/build.py b/selfdrive/manager/build.py index 5b69e3dca7..26003cd1de 100755 --- a/selfdrive/manager/build.py +++ b/selfdrive/manager/build.py @@ -15,7 +15,7 @@ from system.version import is_dirty MAX_CACHE_SIZE = 4e9 if "CI" in os.environ else 2e9 CACHE_DIR = Path("/data/scons_cache" if AGNOS else "/tmp/scons_cache") -TOTAL_SCONS_NODES = 2460 +TOTAL_SCONS_NODES = 2560 MAX_BUILD_PROGRESS = 100 PREBUILT = os.path.exists(os.path.join(BASEDIR, 'prebuilt')) diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index 76a49eda5b..0acb23857a 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -39,7 +39,7 @@ def launcher(proc: str, name: str) -> None: sentry.set_tag("daemon", name) # exec the process - getattr(mod, 'main')() + mod.main() except KeyboardInterrupt: cloudlog.warning(f"child {proc} got SIGINT") except Exception: diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 2fd786875c..7cd1ed9489 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -13,6 +13,9 @@ def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: return CP.notCar # type: ignore +def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: + return not CP.notCar + def logging(started, params, CP: car.CarParams) -> bool: run = (not CP.notCar) or not params.get_bool("DisableLogging") return started and run @@ -35,12 +38,13 @@ procs = [ NativeProcess("logcatd", "system/logcatd", ["./logcatd"]), NativeProcess("proclogd", "system/proclogd", ["./proclogd"]), PythonProcess("logmessaged", "system.logmessaged", offroad=True), - PythonProcess("micd", "system.micd"), + PythonProcess("micd", "system.micd", callback=iscar), PythonProcess("timezoned", "system.timezoned", enabled=not PC, offroad=True), DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), callback=driverview), NativeProcess("encoderd", "system/loggerd", ["./encoderd"]), + NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], onroad=False, callback=notcar), NativeProcess("loggerd", "system/loggerd", ["./loggerd"], onroad=False, callback=logging), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), NativeProcess("mapsd", "selfdrive/navd", ["./mapsd"]), diff --git a/selfdrive/modeld/runners/onnx_runner.py b/selfdrive/modeld/runners/onnx_runner.py index 8e45760a3e..9e53874578 100755 --- a/selfdrive/modeld/runners/onnx_runner.py +++ b/selfdrive/modeld/runners/onnx_runner.py @@ -36,16 +36,16 @@ def run_loop(m, tf8_input=False): # run once to initialize CUDA provider if "CUDAExecutionProvider" in m.get_providers(): - m.run(None, dict(zip(keys, [np.zeros(shp, dtype=itp) for shp, itp in zip(ishapes, itypes)]))) + m.run(None, dict(zip(keys, [np.zeros(shp, dtype=itp) for shp, itp in zip(ishapes, itypes, strict=True)], strict=True))) print("ready to run onnx model", keys, ishapes, file=sys.stderr) while 1: inputs = [] - for k, shp, itp in zip(keys, ishapes, itypes): + for k, shp, itp in zip(keys, ishapes, itypes, strict=True): ts = np.product(shp) #print("reshaping %s with offset %d" % (str(shp), offset), file=sys.stderr) inputs.append(read(ts, (k=='input_img' and tf8_input)).reshape(shp).astype(itp)) - ret = m.run(None, dict(zip(keys, inputs))) + ret = m.run(None, dict(zip(keys, inputs, strict=True))) #print(ret, file=sys.stderr) for r in ret: write(r.astype(np.float32)) diff --git a/selfdrive/modeld/tests/timing/benchmark.py b/selfdrive/modeld/tests/timing/benchmark.py index 3c7ce5b70a..f4fddaab40 100755 --- a/selfdrive/modeld/tests/timing/benchmark.py +++ b/selfdrive/modeld/tests/timing/benchmark.py @@ -35,6 +35,6 @@ if __name__ == "__main__": print("\n\n") print(f"ran modeld {N} times for {TIME}s each") - for n, t in enumerate(execution_times): + for _, t in enumerate(execution_times): print(f"\tavg: {sum(t)/len(t):0.2f}ms, min: {min(t):0.2f}ms, max: {max(t):0.2f}ms") print("\n\n") diff --git a/selfdrive/monitoring/driver_monitor.py b/selfdrive/monitoring/driver_monitor.py index 7d7a55e5d8..97407e25eb 100644 --- a/selfdrive/monitoring/driver_monitor.py +++ b/selfdrive/monitoring/driver_monitor.py @@ -119,7 +119,9 @@ class DriverBlink(): self.right_blink = 0. class DriverStatus(): - def __init__(self, rhd_saved=False, settings=DRIVER_MONITOR_SETTINGS()): + def __init__(self, rhd_saved=False, settings=None): + if settings is None: + settings = DRIVER_MONITOR_SETTINGS() # init policy settings self.settings = settings diff --git a/selfdrive/navd/helpers.py b/selfdrive/navd/helpers.py index 050c571923..5957816334 100644 --- a/selfdrive/navd/helpers.py +++ b/selfdrive/navd/helpers.py @@ -8,6 +8,9 @@ from common.conversions import Conversions from common.numpy_fast import clip from common.params import Params +DIRECTIONS = ('left', 'right', 'straight') +MODIFIABLE_DIRECTIONS = ('left', 'right') + EARTH_MEAN_RADIUS = 6371007.2 SPEED_CONVERSIONS = { 'km/h': Conversions.KPH_TO_MS, @@ -119,8 +122,10 @@ def coordinate_from_param(param: str, params: Optional[Params] = None) -> Option def string_to_direction(direction: str) -> str: - for d in ['left', 'right', 'straight']: + for d in DIRECTIONS: if d in direction: + if 'slight' in direction and d in MODIFIABLE_DIRECTIONS: + return 'slight' + d.capitalize() return d return 'none' diff --git a/selfdrive/statsd.py b/selfdrive/statsd.py index e64907149c..a444a62312 100755 --- a/selfdrive/statsd.py +++ b/selfdrive/statsd.py @@ -23,6 +23,8 @@ class METRIC_TYPE: class StatLog: def __init__(self): self.pid = None + self.zctx = None + self.sock = None def connect(self) -> None: self.zctx = zmq.Context() @@ -31,6 +33,12 @@ class StatLog: self.sock.connect(STATS_SOCKET) self.pid = os.getpid() + def __del__(self): + if self.sock is not None: + self.sock.close() + if self.zctx is not None: + self.zctx.term() + def _send(self, metric: str) -> None: if os.getpid() != self.pid: self.connect() @@ -68,7 +76,7 @@ def main() -> NoReturn: return res # open statistics socket - ctx = zmq.Context().instance() + ctx = zmq.Context.instance() sock = ctx.socket(zmq.PULL) sock.bind(STATS_SOCKET) @@ -92,70 +100,74 @@ def main() -> NoReturn: last_flush_time = time.monotonic() gauges = {} samples: Dict[str, List[float]] = defaultdict(list) - while True: - started_prev = sm['deviceState'].started - sm.update() - - # Update metrics + try: while True: - try: - metric = sock.recv_string(zmq.NOBLOCK) + started_prev = sm['deviceState'].started + sm.update() + + # Update metrics + while True: try: - metric_type = metric.split('|')[1] - metric_name = metric.split(':')[0] - metric_value = float(metric.split('|')[0].split(':')[1]) + metric = sock.recv_string(zmq.NOBLOCK) + try: + metric_type = metric.split('|')[1] + metric_name = metric.split(':')[0] + metric_value = float(metric.split('|')[0].split(':')[1]) - if metric_type == METRIC_TYPE.GAUGE: - gauges[metric_name] = metric_value - elif metric_type == METRIC_TYPE.SAMPLE: - samples[metric_name].append(metric_value) - else: - cloudlog.event("unknown metric type", metric_type=metric_type) - except Exception: - cloudlog.event("malformed metric", metric=metric) - except zmq.error.Again: - break + if metric_type == METRIC_TYPE.GAUGE: + gauges[metric_name] = metric_value + elif metric_type == METRIC_TYPE.SAMPLE: + samples[metric_name].append(metric_value) + else: + cloudlog.event("unknown metric type", metric_type=metric_type) + except Exception: + cloudlog.event("malformed metric", metric=metric) + except zmq.error.Again: + break - # flush when started state changes or after FLUSH_TIME_S - if (time.monotonic() > last_flush_time + STATS_FLUSH_TIME_S) or (sm['deviceState'].started != started_prev): - result = "" - current_time = datetime.utcnow().replace(tzinfo=timezone.utc) - tags['started'] = sm['deviceState'].started + # flush when started state changes or after FLUSH_TIME_S + if (time.monotonic() > last_flush_time + STATS_FLUSH_TIME_S) or (sm['deviceState'].started != started_prev): + result = "" + current_time = datetime.utcnow().replace(tzinfo=timezone.utc) + tags['started'] = sm['deviceState'].started - for key, value in gauges.items(): - result += get_influxdb_line(f"gauge.{key}", value, current_time, tags) + for key, value in gauges.items(): + result += get_influxdb_line(f"gauge.{key}", value, current_time, tags) - for key, values in samples.items(): - values.sort() - sample_count = len(values) - sample_sum = sum(values) + for key, values in samples.items(): + values.sort() + sample_count = len(values) + sample_sum = sum(values) - stats = { - 'count': sample_count, - 'min': values[0], - 'max': values[-1], - 'mean': sample_sum / sample_count, - } - for percentile in [0.05, 0.5, 0.95]: - value = values[int(round(percentile * (sample_count - 1)))] - stats[f"p{int(percentile * 100)}"] = value + stats = { + 'count': sample_count, + 'min': values[0], + 'max': values[-1], + 'mean': sample_sum / sample_count, + } + for percentile in [0.05, 0.5, 0.95]: + value = values[int(round(percentile * (sample_count - 1)))] + stats[f"p{int(percentile * 100)}"] = value - result += get_influxdb_line(f"sample.{key}", stats, current_time, tags) + result += get_influxdb_line(f"sample.{key}", stats, current_time, tags) - # clear intermediate data - gauges.clear() - samples.clear() - last_flush_time = time.monotonic() + # clear intermediate data + gauges.clear() + samples.clear() + last_flush_time = time.monotonic() - # check that we aren't filling up the drive - if len(os.listdir(STATS_DIR)) < STATS_DIR_FILE_LIMIT: - if len(result) > 0: - stats_path = os.path.join(STATS_DIR, f"{current_time.timestamp():.0f}_{idx}") - with atomic_write_in_dir(stats_path) as f: - f.write(result) - idx += 1 - else: - cloudlog.error("stats dir full") + # check that we aren't filling up the drive + if len(os.listdir(STATS_DIR)) < STATS_DIR_FILE_LIMIT: + if len(result) > 0: + stats_path = os.path.join(STATS_DIR, f"{current_time.timestamp():.0f}_{idx}") + with atomic_write_in_dir(stats_path) as f: + f.write(result) + idx += 1 + else: + cloudlog.error("stats dir full") + finally: + sock.close() + ctx.term() if __name__ == "__main__": diff --git a/selfdrive/test/ciui.py b/selfdrive/test/ciui.py new file mode 100755 index 0000000000..291f9f6e44 --- /dev/null +++ b/selfdrive/test/ciui.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +import signal +import subprocess + +signal.signal(signal.SIGINT, signal.SIG_DFL) +signal.signal(signal.SIGTERM, signal.SIG_DFL) + +from PyQt5.QtCore import QTimer # pylint: disable=no-name-in-module, import-error +from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel # pylint: disable=no-name-in-module, import-error +from selfdrive.ui.qt.python_helpers import set_main_window + +class Window(QWidget): + def __init__(self, parent=None): + super(Window, self).__init__(parent) + + layout = QVBoxLayout() + self.setLayout(layout) + + self.l = QLabel("jenkins runner") + layout.addWidget(self.l) + layout.addStretch(1) + layout.setContentsMargins(20, 20, 20, 20) + + cmds = [ + "cat /etc/hostname", + "echo AGNOS v$(cat /VERSION)", + "uptime -p", + ] + self.labels = {} + for c in cmds: + self.labels[c] = QLabel(c) + layout.addWidget(self.labels[c]) + + self.setStyleSheet(""" + * { + color: white; + font-size: 55px; + background-color: black; + font-family: "JetBrains Mono"; + } + """) + + self.timer = QTimer() + self.timer.timeout.connect(self.update) + self.timer.start(10 * 1000) + self.update() + + def update(self): + for cmd, label in self.labels.items(): + out = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=True, check=False, encoding='utf8').stdout + label.setText(out.strip()) + +if __name__ == "__main__": + app = QApplication([]) + w = Window() + set_main_window(w) + app.exec_() diff --git a/selfdrive/test/process_replay/compare_logs.py b/selfdrive/test/process_replay/compare_logs.py index aadfe2064a..a929fae6ed 100755 --- a/selfdrive/test/process_replay/compare_logs.py +++ b/selfdrive/test/process_replay/compare_logs.py @@ -70,7 +70,7 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non raise Exception(f"logs are not same length: {len(log1)} VS {len(log2)}\n\t\t{cnt1}\n\t\t{cnt2}") diff = [] - for msg1, msg2 in zip(log1, log2): + for msg1, msg2 in zip(log1, log2, strict=True): if msg1.which() != msg2.which(): raise Exception("msgs not aligned between logs") diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 96d625c2cb..08e497e72d 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -465,8 +465,8 @@ CONFIGS = [ subs=["radarState", "liveTracks"], ignore=["logMonoTime", "valid", "radarState.cumLagMs"], init_callback=get_car_params_callback, - should_recv_callback=MessageBasedRcvCallback("can"), - main_pub="can", + should_recv_callback=MessageBasedRcvCallback("modelV2"), + unlocked_pubs=["can"], ), ProcessConfig( proc_name="plannerd", @@ -672,8 +672,8 @@ def _replay_multi_process( containers = [] for cfg in cfgs: container = ProcessContainer(cfg) - container.start(params_config, env_config, all_msgs, fingerprint, captured_output_store is not None) containers.append(container) + container.start(params_config, env_config, all_msgs, fingerprint, captured_output_store is not None) all_pubs = {pub for container in containers for pub in container.pubs} all_subs = {sub for container in containers for sub in container.subs} diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index f76b19eddb..ce6c513c10 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -8fd42f02d1ecac695327bfc0afd4be1918ab680a \ No newline at end of file +ac3f87bad519df408a295d2e007e0de58b11690c \ No newline at end of file diff --git a/selfdrive/test/process_replay/test_debayer.py b/selfdrive/test/process_replay/test_debayer.py index 1b3e0f112e..2ed2be61ac 100755 --- a/selfdrive/test/process_replay/test_debayer.py +++ b/selfdrive/test/process_replay/test_debayer.py @@ -137,7 +137,7 @@ if __name__ == "__main__": failed = True diff += 'amount of frames not equal\n' - for i, (frame, cmp_frame) in enumerate(zip(frames, cmp_frames)): + for i, (frame, cmp_frame) in enumerate(zip(frames, cmp_frames, strict=True)): for j in range(3): fr = frame[j] cmp_f = cmp_frame[j] @@ -159,7 +159,7 @@ if __name__ == "__main__": diff += f'different at a large amount of pixels ({diff_len})\n' else: diff += 'different at (frame, yuv, pixel, ref, HEAD):\n' - for k in zip(*np.nonzero(frame_diff)): + for k in zip(*np.nonzero(frame_diff), strict=True): diff += f'{i}, {yuv_i[j]}, {k}, {cmp_f[k]}, {fr[k]}\n' if failed: diff --git a/selfdrive/test/profiling/profiler.py b/selfdrive/test/profiling/profiler.py index a0940b327b..28e3b34e40 100755 --- a/selfdrive/test/profiling/profiler.py +++ b/selfdrive/test/profiling/profiler.py @@ -2,8 +2,8 @@ import os import sys import cProfile # pylint: disable=import-error -import pprofile # pylint: disable=import-error -import pyprof2calltree # pylint: disable=import-error +import pprofile +import pyprof2calltree from common.params import Params from tools.lib.logreader import LogReader diff --git a/selfdrive/test/setup_device_ci.sh b/selfdrive/test/setup_device_ci.sh index 4ac9707408..1b99c31038 100755 --- a/selfdrive/test/setup_device_ci.sh +++ b/selfdrive/test/setup_device_ci.sh @@ -42,6 +42,13 @@ while true; do if ! sudo systemctl is-active -q ssh; then sudo systemctl start ssh fi + + if ! pgrep -f 'ciui.py' > /dev/null 2>&1; then + echo 'starting UI' + cp $SOURCE_DIR/selfdrive/test/ciui.py /data/ + /data/ciui.py & + fi + sleep 5s done diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index b27f2407a2..d71f49dc3a 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -282,7 +282,7 @@ class TestOnroad(unittest.TestCase): result += "-------------- Debayer Timing ------------------\n" result += "------------------------------------------------\n" - ts = [getattr(getattr(m, m.which()), "processingTime") for m in self.lr if 'CameraState' in m.which()] + ts = [getattr(m, m.which()).processingTime for m in self.lr if 'CameraState' in m.which()] self.assertLess(min(ts), 0.025, f"high execution time: {min(ts)}") result += f"execution time: min {min(ts):.5f}s\n" result += f"execution time: max {max(ts):.5f}s\n" @@ -297,7 +297,7 @@ class TestOnroad(unittest.TestCase): result += "----------------- SoF Timing ------------------\n" result += "------------------------------------------------\n" for name in ['roadCameraState', 'wideRoadCameraState', 'driverCameraState']: - ts = [getattr(getattr(m, m.which()), "timestampSof") for m in self.lr if name in m.which()] + ts = [getattr(m, m.which()).timestampSof for m in self.lr if name in m.which()] d_ms = np.diff(ts) / 1e6 d50 = np.abs(d_ms-50) self.assertLess(max(d50), 1.0, f"high sof delta vs 50ms: {max(d50)}") @@ -315,7 +315,7 @@ class TestOnroad(unittest.TestCase): cfgs = [("lateralPlan", 0.05, 0.05), ("longitudinalPlan", 0.05, 0.05)] for (s, instant_max, avg_max) in cfgs: - ts = [getattr(getattr(m, s), "solverExecutionTime") for m in self.service_msgs[s]] + ts = [getattr(m, s).solverExecutionTime for m in self.service_msgs[s]] self.assertLess(max(ts), instant_max, f"high '{s}' execution time: {max(ts)}") self.assertLess(np.mean(ts), avg_max, f"high avg '{s}' execution time: {np.mean(ts)}") result += f"'{s}' execution time: min {min(ts):.5f}s\n" @@ -335,7 +335,7 @@ class TestOnroad(unittest.TestCase): ("driverStateV2", 0.050, 0.026), ] for (s, instant_max, avg_max) in cfgs: - ts = [getattr(getattr(m, s), "modelExecutionTime") for m in self.service_msgs[s]] + ts = [getattr(m, s).modelExecutionTime for m in self.service_msgs[s]] self.assertLess(max(ts), instant_max, f"high '{s}' execution time: {max(ts)}") self.assertLess(np.mean(ts), avg_max, f"high avg '{s}' execution time: {np.mean(ts)}") result += f"'{s}' execution time: min {min(ts):.5f}s\n" diff --git a/selfdrive/test/update_ci_routes.py b/selfdrive/test/update_ci_routes.py index 78b2fb6f5a..cee2f49e56 100755 --- a/selfdrive/test/update_ci_routes.py +++ b/selfdrive/test/update_ci_routes.py @@ -52,7 +52,7 @@ def sync_to_ci_public(route): return True print(f"Uploading {route}") - for (source_account, source_bucket), source_key in zip(SOURCES, source_keys): + for (source_account, source_bucket), source_key in zip(SOURCES, source_keys, strict=True): print(f"Trying {source_account}/{source_bucket}") cmd = [ "azcopy", diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 572c205ec7..931f9be88f 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -61,7 +61,7 @@ def populate_tz_by_type(): if not n.startswith("thermal_zone"): continue with open(os.path.join("/sys/devices/virtual/thermal", n, "type")) as f: - tz_by_type[f.read().strip()] = int(n.lstrip("thermal_zone")) + tz_by_type[f.read().strip()] = int(n.removeprefix("thermal_zone")) def read_tz(x): if x is None: diff --git a/selfdrive/tombstoned.py b/selfdrive/tombstoned.py index 65fb45b678..b1086305b7 100755 --- a/selfdrive/tombstoned.py +++ b/selfdrive/tombstoned.py @@ -54,7 +54,7 @@ def get_tombstones(): with os.scandir(folder) as d: # Loop over first 1000 directory entries - for _, f in zip(range(1000), d): + for _, f in zip(range(1000), d, strict=False): if f.name.startswith("tombstone"): files.append((f.path, int(f.stat().st_ctime))) elif f.name.endswith(".crash") and f.stat().st_mode == 0o100640: diff --git a/selfdrive/ui/qt/maps/map.cc b/selfdrive/ui/qt/maps/map.cc index c971bf9c0b..b596b11260 100644 --- a/selfdrive/ui/qt/maps/map.cc +++ b/selfdrive/ui/qt/maps/map.cc @@ -43,11 +43,7 @@ MapWindow::MapWindow(const QMapboxGLSettings &settings) : m_settings(settings), overlay_layout->addStretch(1); overlay_layout->addWidget(map_eta); - auto last_gps_position = coordinate_from_param("LastGPSPosition"); - if (last_gps_position.has_value()) { - last_position = *last_gps_position; - } - + last_position = coordinate_from_param("LastGPSPosition"); grabGesture(Qt::GestureType::PinchGesture); qDebug() << "MapWindow initialized"; } @@ -160,13 +156,15 @@ void MapWindow::updateState(const UIState &s) { } if (sm.updated("navRoute") && sm["navRoute"].getNavRoute().getCoordinates().size()) { + auto nav_dest = coordinate_from_param("NavDestination"); + bool allow_open = std::exchange(last_valid_nav_dest, nav_dest) != nav_dest && + nav_dest && !isVisible(); qWarning() << "Got new navRoute from navd. Opening map:" << allow_open; - // Only open the map on setting destination the first time + // Show map on destination set/change if (allow_open) { emit requestSettings(false); - emit requestVisible(true); // Show map on destination set/change - allow_open = false; + emit requestVisible(true); } } @@ -295,7 +293,7 @@ void MapWindow::clearRoute() { map_instructions->setVisible(false); map_eta->setVisible(false); - allow_open = true; + last_valid_nav_dest = std::nullopt; } void MapWindow::mousePressEvent(QMouseEvent *ev) { @@ -381,8 +379,6 @@ void MapWindow::offroadTransition(bool offroad) { } void MapWindow::updateDestinationMarker() { - m_map->setPaintProperty("pinLayer", "visibility", "none"); - auto nav_dest = coordinate_from_param("NavDestination"); if (nav_dest.has_value()) { auto point = coordinate_to_collection(*nav_dest); @@ -392,5 +388,7 @@ void MapWindow::updateDestinationMarker() { pinSource["data"] = QVariant::fromValue(feature); m_map->updateSource("pinSource", pinSource); m_map->setPaintProperty("pinLayer", "visibility", "visible"); + } else { + m_map->setPaintProperty("pinLayer", "visibility", "none"); } } diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h index d57f6517b5..66d10a00a0 100644 --- a/selfdrive/ui/qt/maps/map.h +++ b/selfdrive/ui/qt/maps/map.h @@ -50,7 +50,6 @@ private: void setError(const QString &err_str); bool loaded_once = false; - bool allow_open = true; // Panning QPointF m_lastPos; @@ -58,6 +57,7 @@ private: int zoom_counter = 0; // Position + std::optional last_valid_nav_dest; std::optional last_position; std::optional last_bearing; FirstOrderFilter velocity_filter; diff --git a/selfdrive/ui/qt/maps/map_eta.cc b/selfdrive/ui/qt/maps/map_eta.cc index 13e11e5597..322861ed15 100644 --- a/selfdrive/ui/qt/maps/map_eta.cc +++ b/selfdrive/ui/qt/maps/map_eta.cc @@ -3,6 +3,7 @@ #include #include +#include "selfdrive/ui/qt/maps/map_helpers.h" #include "selfdrive/ui/ui.h" const float MANEUVER_TRANSITION_THRESHOLD = 10; @@ -30,12 +31,12 @@ void MapETA::paintEvent(QPaintEvent *event) { void MapETA::updateETA(float s, float s_typical, float d) { // ETA auto eta_t = QDateTime::currentDateTime().addSecs(s).time(); - auto eta = format_24h ? std::array{eta_t.toString("HH:mm"), tr("eta")} - : std::array{eta_t.toString("h:mm a").split(' ')[0], eta_t.toString("a")}; + auto eta = format_24h ? std::pair{eta_t.toString("HH:mm"), tr("eta")} + : std::pair{eta_t.toString("h:mm a").split(' ')[0], eta_t.toString("a")}; // Remaining time - auto remaining = s < 3600 ? std::array{QString::number(int(s / 60)), tr("min")} - : std::array{QString("%1:%2").arg((int)s / 3600).arg(((int)s % 3600) / 60, 2, 10, QLatin1Char('0')), tr("hr")}; + auto remaining = s < 3600 ? std::pair{QString::number(int(s / 60)), tr("min")} + : std::pair{QString("%1:%2").arg((int)s / 3600).arg(((int)s % 3600) / 60, 2, 10, QLatin1Char('0')), tr("hr")}; QString color = "#25DA6E"; if (s / s_typical > 1.5) color = "#DA3025"; @@ -43,14 +44,12 @@ void MapETA::updateETA(float s, float s_typical, float d) { color = "#DAA725"; // Distance - float num = uiState()->scene.is_metric ? (d / 1000.0) : (d * METER_TO_MILE); - auto distance = std::array{QString::number(num, 'f', num < 100 ? 1 : 0), - uiState()->scene.is_metric ? tr("km") : tr("mi")}; + auto distance = map_format_distance(d, uiState()->scene.is_metric); eta_doc.setHtml(QString(R"()") - .arg(eta[0], eta[1], color, remaining[0], remaining[1], distance[0], distance[1])); + .arg(eta.first, eta.second, color, remaining.first, remaining.second, distance.first, distance.second)); setVisible(d >= MANEUVER_TRANSITION_THRESHOLD); update(); diff --git a/selfdrive/ui/qt/maps/map_helpers.cc b/selfdrive/ui/qt/maps/map_helpers.cc index 95db4f2bbd..0f96638820 100644 --- a/selfdrive/ui/qt/maps/map_helpers.cc +++ b/selfdrive/ui/qt/maps/map_helpers.cc @@ -129,6 +129,23 @@ std::optional coordinate_from_param(const std::string ¶ } } +// return {distance, unit} +std::pair map_format_distance(float d, bool is_metric) { + auto round_distance = [](float d) -> float { + return (d > 10) ? std::nearbyint(d) : std::nearbyint(d * 10) / 10.0; + }; + + d = std::max(d, 0.0f); + if (is_metric) { + return (d > 500) ? std::pair{QString::number(round_distance(d / 1000)), QObject::tr("km")} + : std::pair{QString::number(50 * std::nearbyint(d / 50)), QObject::tr("m")}; + } else { + float feet = d * METER_TO_FOOT; + return (feet > 500) ? std::pair{QString::number(round_distance(d * METER_TO_MILE)), QObject::tr("mi")} + : std::pair{QString::number(50 * std::nearbyint(d / 50)), QObject::tr("ft")}; + } +} + double angle_difference(double angle1, double angle2) { double diff = fmod(angle2 - angle1 + 180.0, 360.0) - 180.0; return diff < -180.0 ? diff + 360.0 : diff; diff --git a/selfdrive/ui/qt/maps/map_helpers.h b/selfdrive/ui/qt/maps/map_helpers.h index f9c56107e3..0090753a40 100644 --- a/selfdrive/ui/qt/maps/map_helpers.h +++ b/selfdrive/ui/qt/maps/map_helpers.h @@ -25,6 +25,6 @@ QMapbox::CoordinatesCollections coordinate_to_collection(const QMapbox::Coordina QMapbox::CoordinatesCollections capnp_coordinate_list_to_collection(const capnp::List::Reader &coordinate_list); QMapbox::CoordinatesCollections coordinate_list_to_collection(const QList &coordinate_list); QList polyline_to_coordinate_list(const QString &polylineString); - std::optional coordinate_from_param(const std::string ¶m); +std::pair map_format_distance(float d, bool is_metric); double angle_difference(double angle1, double angle2); diff --git a/selfdrive/ui/qt/maps/map_instructions.cc b/selfdrive/ui/qt/maps/map_instructions.cc index 25fec5c274..0901213c76 100644 --- a/selfdrive/ui/qt/maps/map_instructions.cc +++ b/selfdrive/ui/qt/maps/map_instructions.cc @@ -3,6 +3,7 @@ #include #include +#include "selfdrive/ui/qt/maps/map_helpers.h" #include "selfdrive/ui/ui.h" const QString ICON_SUFFIX = ".png"; @@ -10,7 +11,7 @@ const QString ICON_SUFFIX = ".png"; MapInstructions::MapInstructions(QWidget *parent) : QWidget(parent) { is_rhd = Params().getBool("IsRhdDetected"); QHBoxLayout *main_layout = new QHBoxLayout(this); - main_layout->setContentsMargins(11, 50, 11, 11); + main_layout->setContentsMargins(11, UI_BORDER_SIZE, 11, 11); main_layout->addWidget(icon_01 = new QLabel, 0, Qt::AlignTop); QWidget *right_container = new QWidget(this); @@ -63,18 +64,6 @@ void MapInstructions::buildPixmapCache() { } } -QString MapInstructions::getDistance(float d) { - d = std::max(d, 0.0f); - if (uiState()->scene.is_metric) { - return (d > 500) ? QString::number(d / 1000, 'f', 1) + tr(" km") - : QString::number(50 * qRound(d / 50)) + tr(" m"); - } else { - float feet = d * METER_TO_FOOT; - return (feet > 500) ? QString::number(d * METER_TO_MILE, 'f', 1) + tr(" mi") - : QString::number(50 * qRound(feet / 50)) + tr(" ft"); - } -} - void MapInstructions::updateInstructions(cereal::NavInstruction::Reader instruction) { setUpdatesEnabled(false); @@ -85,7 +74,9 @@ void MapInstructions::updateInstructions(cereal::NavInstruction::Reader instruct primary->setText(primary_str); secondary->setVisible(secondary_str.length() > 0); secondary->setText(secondary_str); - distance->setText(getDistance(instruction.getManeuverDistance())); + + auto distance_str_pair = map_format_distance(instruction.getManeuverDistance(), uiState()->scene.is_metric); + distance->setText(QString("%1 %2").arg(distance_str_pair.first, distance_str_pair.second)); // Show arrow with direction QString type = QString::fromStdString(instruction.getManeuverType()); @@ -100,6 +91,8 @@ void MapInstructions::updateInstructions(cereal::NavInstruction::Reader instruct icon_01->setPixmap(pixmap_cache[!rhd ? fn : "rhd_" + fn]); icon_01->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); icon_01->setVisible(true); + } else { + icon_01->setVisible(false); } // Hide distance after arrival diff --git a/selfdrive/ui/qt/maps/map_instructions.h b/selfdrive/ui/qt/maps/map_instructions.h index 26bcb4d580..6c08cb9b9e 100644 --- a/selfdrive/ui/qt/maps/map_instructions.h +++ b/selfdrive/ui/qt/maps/map_instructions.h @@ -11,6 +11,8 @@ static std::map DIRECTIONS = { {cereal::NavInstruction::Direction::LEFT, "left"}, {cereal::NavInstruction::Direction::RIGHT, "right"}, {cereal::NavInstruction::Direction::STRAIGHT, "straight"}, + {cereal::NavInstruction::Direction::SLIGHT_LEFT, "slight_left"}, + {cereal::NavInstruction::Direction::SLIGHT_RIGHT, "slight_right"}, }; class MapInstructions : public QWidget { @@ -29,6 +31,5 @@ private: public: MapInstructions(QWidget * parent=nullptr); void buildPixmapCache(); - QString getDistance(float d); void updateInstructions(cereal::NavInstruction::Reader instruction); }; diff --git a/selfdrive/ui/qt/offroad/driverview.cc b/selfdrive/ui/qt/offroad/driverview.cc index 0a216766a2..cc715c6755 100644 --- a/selfdrive/ui/qt/offroad/driverview.cc +++ b/selfdrive/ui/qt/offroad/driverview.cc @@ -33,10 +33,12 @@ DriverViewScene::DriverViewScene(QWidget* parent) : sm({"driverStateV2"}), QWidg void DriverViewScene::showEvent(QShowEvent* event) { frame_updated = false; params.putBool("IsDriverViewEnabled", true); + device()->resetInteractiveTimeout(60); } void DriverViewScene::hideEvent(QHideEvent* event) { params.putBool("IsDriverViewEnabled", false); + device()->resetInteractiveTimeout(); } void DriverViewScene::frameUpdated() { diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index c146345eb4..628a92fb58 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -2,15 +2,13 @@ #include -#include #include -#include -#include #include +#include #include "selfdrive/ui/ui.h" -#include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" +#include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/controls.h" #include "selfdrive/ui/qt/widgets/prime.h" #include "selfdrive/ui/qt/widgets/scrollview.h" @@ -79,7 +77,7 @@ void Networking::refresh() { an->refresh(); } -void Networking::connectToNetwork(const Network &n) { +void Networking::connectToNetwork(const Network n) { if (wifi->isKnownConnection(n.ssid)) { wifi->activateWifiConnection(n.ssid); wifiWidget->refresh(); @@ -211,7 +209,7 @@ void AdvancedNetworking::toggleTethering(bool enabled) { // WifiUI functions WifiUI::WifiUI(QWidget *parent, WifiManager* wifi) : QWidget(parent), wifi(wifi) { - main_layout = new QVBoxLayout(this); + QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(0, 0, 0, 0); main_layout->setSpacing(0); @@ -228,8 +226,9 @@ WifiUI::WifiUI(QWidget *parent, WifiManager* wifi) : QWidget(parent), wifi(wifi) scanningLabel->setStyleSheet("font-size: 65px;"); main_layout->addWidget(scanningLabel, 0, Qt::AlignCenter); - list_layout = new QVBoxLayout; - main_layout->addLayout(list_layout); + wifi_list_widget = new ListWidget(this); + wifi_list_widget->setVisible(false); + main_layout->addWidget(wifi_list_widget); setStyleSheet(R"( QScrollBar::handle:vertical { @@ -262,16 +261,11 @@ WifiUI::WifiUI(QWidget *parent, WifiManager* wifi) : QWidget(parent), wifi(wifi) background-color: black; } #ssidLabel { - font-size: 55px; - font-weight: 300; text-align: left; border: none; padding-top: 50px; padding-bottom: 50px; } - #ssidLabel[disconnected=false] { - font-weight: 500; - } #ssidLabel:disabled { color: #696969; } @@ -279,76 +273,85 @@ WifiUI::WifiUI(QWidget *parent, WifiManager* wifi) : QWidget(parent), wifi(wifi) } void WifiUI::refresh() { - // TODO: don't rebuild this every time - clearLayout(list_layout); - bool is_empty = wifi->seenNetworks.isEmpty(); scanningLabel->setVisible(is_empty); + wifi_list_widget->setVisible(!is_empty); if (is_empty) return; + setUpdatesEnabled(false); + const bool is_tethering_enabled = wifi->isTetheringEnabled(); QList sortedNetworks = wifi->seenNetworks.values(); std::sort(sortedNetworks.begin(), sortedNetworks.end(), compare_by_strength); - // add networks - ListWidget *list = new ListWidget(this); + int n = 0; for (Network &network : sortedNetworks) { - QHBoxLayout *hlayout = new QHBoxLayout; - hlayout->setContentsMargins(44, 0, 73, 0); - hlayout->setSpacing(50); - - // Clickable SSID label - ElidedLabel *ssidLabel = new ElidedLabel(network.ssid); - ssidLabel->setObjectName("ssidLabel"); - ssidLabel->setEnabled(network.security_type != SecurityType::UNSUPPORTED); - ssidLabel->setProperty("disconnected", network.connected == ConnectedType::DISCONNECTED); - if (network.connected == ConnectedType::DISCONNECTED) { - QObject::connect(ssidLabel, &ElidedLabel::clicked, this, [=]() { emit connectToNetwork(network); }); - } - hlayout->addWidget(ssidLabel, network.connected == ConnectedType::CONNECTING ? 0 : 1); - - if (network.connected == ConnectedType::CONNECTING) { - QPushButton *connecting = new QPushButton(tr("CONNECTING...")); - connecting->setObjectName("connecting"); - hlayout->addWidget(connecting, 2, Qt::AlignLeft); - } - - // Forget button - if (wifi->isKnownConnection(network.ssid) && !is_tethering_enabled) { - QPushButton *forgetBtn = new QPushButton(tr("FORGET")); - forgetBtn->setObjectName("forgetBtn"); - QObject::connect(forgetBtn, &QPushButton::clicked, [=]() { - if (ConfirmationDialog::confirm(tr("Forget Wi-Fi Network \"%1\"?").arg(QString::fromUtf8(network.ssid)), tr("Forget"), this)) { - wifi->forgetConnection(network.ssid); - } - }); - hlayout->addWidget(forgetBtn, 0, Qt::AlignRight); - } - - // Status icon + QPixmap status_icon; if (network.connected == ConnectedType::CONNECTED) { - QLabel *connectIcon = new QLabel(); - connectIcon->setPixmap(checkmark); - hlayout->addWidget(connectIcon, 0, Qt::AlignRight); + status_icon = checkmark; } else if (network.security_type == SecurityType::UNSUPPORTED) { - QLabel *unsupportedIcon = new QLabel(); - unsupportedIcon->setPixmap(circled_slash); - hlayout->addWidget(unsupportedIcon, 0, Qt::AlignRight); + status_icon = circled_slash; } else if (network.security_type == SecurityType::WPA) { - QLabel *lockIcon = new QLabel(); - lockIcon->setPixmap(lock); - hlayout->addWidget(lockIcon, 0, Qt::AlignRight); - } else { - hlayout->addSpacing(lock.width() + hlayout->spacing()); + status_icon = lock; } + bool show_forget_btn = wifi->isKnownConnection(network.ssid) && !is_tethering_enabled; + QPixmap strength = strengths[strengthLevel(network.strength)]; - // Strength indicator - QLabel *strength = new QLabel(); - strength->setPixmap(strengths[std::clamp((int)round(network.strength / 33.), 0, 3)]); - hlayout->addWidget(strength, 0, Qt::AlignRight); - - list->addItem(hlayout); + auto item = getItem(n++); + item->setItem(network, status_icon, show_forget_btn, strength); + item->setVisible(true); } - list_layout->addWidget(list); - list_layout->addStretch(1); + for (; n < wifi_items.size(); ++n) wifi_items[n]->setVisible(false); + + setUpdatesEnabled(true); +} + +WifiItem *WifiUI::getItem(int n) { + auto item = n < wifi_items.size() ? wifi_items[n] : wifi_items.emplace_back(new WifiItem(tr("CONNECTING..."), tr("FORGET"))); + if (!item->parentWidget()) { + QObject::connect(item, &WifiItem::connectToNetwork, this, &WifiUI::connectToNetwork); + QObject::connect(item, &WifiItem::forgotNetwork, [this](const Network n) { + if (ConfirmationDialog::confirm(tr("Forget Wi-Fi Network \"%1\"?").arg(QString::fromUtf8(n.ssid)), tr("Forget"), this)) + wifi->forgetConnection(n.ssid); + }); + wifi_list_widget->addItem(item); + } + return item; +} + +// WifiItem + +WifiItem::WifiItem(const QString &connecting_text, const QString &forget_text, QWidget *parent) : QWidget(parent) { + QHBoxLayout *hlayout = new QHBoxLayout(this); + hlayout->setContentsMargins(44, 0, 73, 0); + hlayout->setSpacing(50); + + hlayout->addWidget(ssidLabel = new ElidedLabel()); + ssidLabel->setObjectName("ssidLabel"); + ssidLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hlayout->addWidget(connecting = new QPushButton(connecting_text), 0, Qt::AlignRight); + connecting->setObjectName("connecting"); + hlayout->addWidget(forgetBtn = new QPushButton(forget_text), 0, Qt::AlignRight); + forgetBtn->setObjectName("forgetBtn"); + hlayout->addWidget(iconLabel = new QLabel(), 0, Qt::AlignRight); + hlayout->addWidget(strengthLabel = new QLabel(), 0, Qt::AlignRight); + + QObject::connect(forgetBtn, &QPushButton::clicked, [this]() { emit forgotNetwork(network); }); + QObject::connect(ssidLabel, &ElidedLabel::clicked, [this]() { + if (network.connected == ConnectedType::DISCONNECTED) emit connectToNetwork(network); + }); +} + +void WifiItem::setItem(const Network &n, const QPixmap &status_icon, bool show_forget_btn, const QPixmap &strength_icon) { + network = n; + + ssidLabel->setText(n.ssid); + ssidLabel->setEnabled(n.security_type != SecurityType::UNSUPPORTED); + ssidLabel->setFont(InterFont(55, network.connected == ConnectedType::DISCONNECTED ? QFont::Normal : QFont::Bold)); + + connecting->setVisible(n.connected == ConnectedType::CONNECTING); + forgetBtn->setVisible(show_forget_btn); + + iconLabel->setPixmap(status_icon); + strengthLabel->setPixmap(strength_icon); } diff --git a/selfdrive/ui/qt/offroad/networking.h b/selfdrive/ui/qt/offroad/networking.h index 79cbcc3493..cdcdf067ab 100644 --- a/selfdrive/ui/qt/offroad/networking.h +++ b/selfdrive/ui/qt/offroad/networking.h @@ -1,14 +1,30 @@ #pragma once -#include -#include -#include - #include "selfdrive/ui/qt/offroad/wifiManager.h" #include "selfdrive/ui/qt/widgets/input.h" #include "selfdrive/ui/qt/widgets/ssh_keys.h" #include "selfdrive/ui/qt/widgets/toggle.h" +class WifiItem : public QWidget { + Q_OBJECT +public: + explicit WifiItem(const QString &connecting_text, const QString &forget_text, QWidget* parent = nullptr); + void setItem(const Network& n, const QPixmap &icon, bool show_forget_btn, const QPixmap &strength); + +signals: + // Cannot pass Network by reference. it may change after the signal is sent. + void connectToNetwork(const Network n); + void forgotNetwork(const Network n); + +protected: + ElidedLabel* ssidLabel; + QPushButton* connecting; + QPushButton* forgetBtn; + QLabel* iconLabel; + QLabel* strengthLabel; + Network network; +}; + class WifiUI : public QWidget { Q_OBJECT @@ -16,17 +32,19 @@ public: explicit WifiUI(QWidget *parent = 0, WifiManager* wifi = 0); private: + WifiItem *getItem(int n); + WifiManager *wifi = nullptr; - QVBoxLayout *list_layout = nullptr; QLabel *scanningLabel = nullptr; - QVBoxLayout* main_layout; QPixmap lock; QPixmap checkmark; QPixmap circled_slash; QVector strengths; + ListWidget *wifi_list_widget = nullptr; + std::vector wifi_items; signals: - void connectToNetwork(const Network &n); + void connectToNetwork(const Network n); public slots: void refresh(); @@ -65,10 +83,8 @@ private: QStackedLayout* main_layout = nullptr; QWidget* wifiScreen = nullptr; AdvancedNetworking* an = nullptr; - WifiUI* wifiWidget; -protected: void showEvent(QShowEvent* event) override; void hideEvent(QHideEvent* event) override; @@ -76,6 +92,6 @@ public slots: void refresh(); private slots: - void connectToNetwork(const Network &n); + void connectToNetwork(const Network n); void wrongPassword(const QString &ssid); }; diff --git a/selfdrive/ui/qt/offroad/wifiManager.cc b/selfdrive/ui/qt/offroad/wifiManager.cc index be9da34d45..391cc9fb50 100644 --- a/selfdrive/ui/qt/offroad/wifiManager.cc +++ b/selfdrive/ui/qt/offroad/wifiManager.cc @@ -8,11 +8,8 @@ #include "selfdrive/ui/qt/util.h" bool compare_by_strength(const Network &a, const Network &b) { - if (a.connected == ConnectedType::CONNECTED) return true; - if (b.connected == ConnectedType::CONNECTED) return false; - if (a.connected == ConnectedType::CONNECTING) return true; - if (b.connected == ConnectedType::CONNECTING) return false; - return a.strength > b.strength; + return std::tuple(a.connected, strengthLevel(a.strength), b.ssid) > + std::tuple(b.connected, strengthLevel(b.strength), a.ssid); } template @@ -102,15 +99,22 @@ void WifiManager::refreshFinished(QDBusPendingCallWatcher *watcher) { auto properties = replay.value(); const QByteArray ssid = properties["Ssid"].toByteArray(); - uint32_t strength = properties["Strength"].toUInt(); - if (ssid.isEmpty() || (seenNetworks.contains(ssid) && strength <= seenNetworks[ssid].strength)) continue; + if (ssid.isEmpty()) continue; - SecurityType security = getSecurityType(properties); - ConnectedType ctype = ConnectedType::DISCONNECTED; + // May be multiple access points for each SSID. + // Use first for ssid and security type, then update connected status and strength using all + if (!seenNetworks.contains(ssid)) { + seenNetworks[ssid] = {ssid, 0U, ConnectedType::DISCONNECTED, getSecurityType(properties)}; + } + if (path.path() == activeAp) { - ctype = (ssid == connecting_to_network) ? ConnectedType::CONNECTING : ConnectedType::CONNECTED; + seenNetworks[ssid].connected = (ssid == connecting_to_network) ? ConnectedType::CONNECTING : ConnectedType::CONNECTED; + } + + uint32_t strength = properties["Strength"].toUInt(); + if (seenNetworks[ssid].strength < strength) { + seenNetworks[ssid].strength = strength; } - seenNetworks[ssid] = {ssid, strength, ctype, security}; } emit refreshSignal(); diff --git a/selfdrive/ui/qt/offroad/wifiManager.h b/selfdrive/ui/qt/offroad/wifiManager.h index 8be4c6c31b..244a3cec4a 100644 --- a/selfdrive/ui/qt/offroad/wifiManager.h +++ b/selfdrive/ui/qt/offroad/wifiManager.h @@ -33,6 +33,7 @@ struct Network { SecurityType security_type; }; bool compare_by_strength(const Network &a, const Network &b); +inline int strengthLevel(unsigned int strength) { return std::clamp((int)round(strength / 33.), 0, 3); } class WifiManager : public QObject { Q_OBJECT diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index 15f7c47607..e952940056 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -84,7 +84,9 @@ void Sidebar::updateState(const UIState &s) { if (last_ping == 0) { connectStatus = ItemStatus{{tr("CONNECT"), tr("OFFLINE")}, warning_color}; } else { - connectStatus = nanos_since_boot() - last_ping < 80e9 ? ItemStatus{{tr("CONNECT"), tr("ONLINE")}, good_color} : ItemStatus{{tr("CONNECT"), tr("ERROR")}, danger_color}; + connectStatus = nanos_since_boot() - last_ping < 80e9 + ? ItemStatus{{tr("CONNECT"), tr("ONLINE")}, good_color} + : ItemStatus{{tr("CONNECT"), tr("ERROR")}, danger_color}; } setProperty("connectStatus", QVariant::fromValue(connectStatus)); diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc index a2926548ed..3804aacd78 100644 --- a/selfdrive/ui/qt/util.cc +++ b/selfdrive/ui/qt/util.cc @@ -51,19 +51,6 @@ QMap getSupportedLanguages() { return map; } -void clearLayout(QLayout* layout) { - while (layout->count() > 0) { - QLayoutItem* item = layout->takeAt(0); - if (QWidget* widget = item->widget()) { - widget->deleteLater(); - } - if (QLayout* childLayout = item->layout()) { - clearLayout(childLayout); - } - delete item; - } -} - QString timeAgo(const QDateTime &date) { int diff = date.secsTo(QDateTime::currentDateTimeUtc()); diff --git a/selfdrive/ui/qt/util.h b/selfdrive/ui/qt/util.h index 68c7bd2712..2b1200a861 100644 --- a/selfdrive/ui/qt/util.h +++ b/selfdrive/ui/qt/util.h @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -18,7 +17,6 @@ QString getBrand(); QString getUserAgent(); std::optional getDongleId(); QMap getSupportedLanguages(); -void clearLayout(QLayout* layout); void setQtSurfaceFormat(); void sigTermHandler(int s); QString timeAgo(const QDateTime &date); diff --git a/selfdrive/ui/soundd/sound.cc b/selfdrive/ui/soundd/sound.cc index 49c28373c5..8d5b2b96b0 100644 --- a/selfdrive/ui/soundd/sound.cc +++ b/selfdrive/ui/soundd/sound.cc @@ -12,7 +12,7 @@ // TODO: detect when we can't play sounds // TODO: detect when we can't display the UI -Sound::Sound(QObject *parent) : sm({"controlsState", "deviceState", "microphone"}) { +Sound::Sound(QObject *parent) : sm({"controlsState", "microphone"}) { qInfo() << "default audio device: " << QAudioDeviceInfo::defaultOutputDevice().deviceName(); for (auto &[alert, fn, loops] : sound_list) { @@ -30,22 +30,8 @@ Sound::Sound(QObject *parent) : sm({"controlsState", "deviceState", "microphone" }; void Sound::update() { - const bool started_prev = sm["deviceState"].getDeviceState().getStarted(); sm.update(0); - const bool started = sm["deviceState"].getDeviceState().getStarted(); - if (started && !started_prev) { - started_frame = sm.frame; - } - - // no sounds while offroad - // also no sounds if nothing is alive in case thermald crashes while offroad - const bool crashed = (sm.frame - std::max(sm.rcv_frame("deviceState"), sm.rcv_frame("controlsState"))) > 10*UI_FREQ; - if (!started || crashed) { - setAlert({}); - return; - } - // scale volume using ambient noise level if (sm.updated("microphone")) { float volume = util::map_val(sm["microphone"].getMicrophone().getFilteredSoundPressureWeightedDb(), 30.f, 60.f, 0.f, 1.f); @@ -53,7 +39,7 @@ void Sound::update() { Hardware::set_volume(volume); } - setAlert(Alert::get(sm, started_frame)); + setAlert(Alert::get(sm, 0)); } void Sound::setAlert(const Alert &alert) { diff --git a/selfdrive/ui/soundd/sound.h b/selfdrive/ui/soundd/sound.h index 7e009d28ad..da9814c543 100644 --- a/selfdrive/ui/soundd/sound.h +++ b/selfdrive/ui/soundd/sound.h @@ -27,8 +27,7 @@ protected: void update(); void setAlert(const Alert &alert); + SubMaster sm; Alert current_alert = {}; QMap> sounds; - SubMaster sm; - uint64_t started_frame; }; diff --git a/selfdrive/ui/tests/test_translations.py b/selfdrive/ui/tests/test_translations.py index 5e52eabe3a..8321e2e4c0 100755 --- a/selfdrive/ui/tests/test_translations.py +++ b/selfdrive/ui/tests/test_translations.py @@ -11,6 +11,7 @@ from selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, u TMP_TRANSLATIONS_DIR = os.path.join(TRANSLATIONS_DIR, "tmp") UNFINISHED_TRANSLATION_TAG = "" not in cur_translations, f"{file} ({name}) translation file has obsolete translations. Run selfdrive/ui/update_translations.py --vanish to remove them") - def test_plural_translations(self): + def test_finished_translations(self): """ - Tests: - - that any numerus (plural) translations marked "finished" have all plural forms non-empty + Tests ran on each translation marked "finished" + Plural: + - that any numerus (plural) translations have all plural forms non-empty - that the correct format specifier is used (%n) + Non-plural: + - that translation is not empty + - that translation format arguments are consistent """ for name, file in self.translation_files.items(): with self.subTest(name=name, file=file): @@ -79,17 +84,28 @@ class TestTranslations(unittest.TestCase): for context in tr_xml.getroot(): for message in context.iterfind("message"): + translation = message.find("translation") + source_text = message.find("source").text + + # Do not test unfinished translations + if translation.get("type") == "unfinished": + continue + if message.get("numerus") == "yes": - translation = message.find("translation") numerusform = [t.text for t in translation.findall("numerusform")] - # Do not assert finished translations - if translation.get("type") == "unfinished": - continue + for nf in numerusform: + self.assertIsNotNone(nf, f"Ensure all plural translation forms are completed: {source_text}") + self.assertIn("%n", nf, "Ensure numerus argument (%n) exists in translation.") + self.assertIsNone(FORMAT_ARG.search(nf), "Plural translations must use %n, not %1, %2, etc.: {}".format(numerusform)) - self.assertNotIn(None, numerusform, "Ensure all plural translation forms are completed.") - self.assertTrue(all(re.search("%[0-9]+", t) is None for t in numerusform), - "Plural translations must use %n, not %1, %2, etc.: {}".format(numerusform)) + else: + self.assertIsNotNone(translation.text, f"Ensure translation is completed: {source_text}") + + source_args = FORMAT_ARG.findall(source_text) + translation_args = FORMAT_ARG.findall(translation.text) + self.assertEqual(sorted(source_args), sorted(translation_args), + f"Ensure format arguments are consistent: `{source_text}` vs. `{translation.text}`") def test_no_locations(self): for name, file in self.translation_files.items(): diff --git a/selfdrive/ui/translations/languages.json b/selfdrive/ui/translations/languages.json index 86d3e62d87..fa659e18ba 100644 --- a/selfdrive/ui/translations/languages.json +++ b/selfdrive/ui/translations/languages.json @@ -1,7 +1,10 @@ { "English": "main_en", "Deutsch": "main_de", + "Français": "main_fr", "Português": "main_pt-BR", + "Türkçe": "main_tr", + "ไทย": "main_th", "中文(繁體)": "main_zh-CHT", "中文(简体)": "main_zh-CHS", "한국어": "main_ko", diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 74b60f4b74..a1b8faa2e3 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -354,33 +354,6 @@ hr std - - km - km - - - mi - mi - - - - MapInstructions - - km - km - - - m - m - - - mi - mi - - - ft - fuß - MapSettings @@ -620,6 +593,22 @@ vor %n Tagen + + km + km + + + m + m + + + mi + mi + + + ft + fuß + Reset diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts new file mode 100644 index 0000000000..14ca4df954 --- /dev/null +++ b/selfdrive/ui/translations/main_fr.ts @@ -0,0 +1,1215 @@ + + + + + AbstractAlert + + Close + Fermer + + + Snooze Update + Reporter la mise à jour + + + Reboot and Update + Redémarrer et mettre à jour + + + + AdvancedNetworking + + Back + Retour + + + Enable Tethering + Activer le partage de connexion + + + Tethering Password + Mot de passe du partage de connexion + + + EDIT + MODIFIER + + + Enter new tethering password + Entrez le nouveau mot de passe du partage de connexion + + + IP Address + Adresse IP + + + Enable Roaming + Activer l'itinérance + + + APN Setting + Paramètre APN + + + Enter APN + Entrer le nom du point d'accès + + + leave blank for automatic configuration + laisser vide pour une configuration automatique + + + Cellular Metered + Connexion cellulaire limitée + + + Prevent large data uploads when on a metered connection + Éviter les transferts de données importants sur une connexion limitée + + + + AnnotatedCameraWidget + + km/h + km/h + + + mph + mi/h + + + MAX + MAX + + + SPEED + VITESSE + + + LIMIT + LIMITE + + + + ConfirmationDialog + + Ok + Ok + + + Cancel + Annuler + + + + DeclinePage + + You must accept the Terms and Conditions in order to use openpilot. + Vous devez accepter les conditions générales pour utiliser openpilot. + + + Back + Retour + + + Decline, uninstall %1 + Refuser, désinstaller %1 + + + + DestinationWidget + + Home + Domicile + + + Work + Travail + + + No destination set + Aucune destination définie + + + home + domicile + + + work + travail + + + No %1 location set + Aucun lieu %1 défini + + + + DevicePanel + + Dongle ID + Dongle ID + + + N/A + N/A + + + Serial + N° de série + + + Driver Camera + Caméra conducteur + + + PREVIEW + APERÇU + + + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + Aperçu de la caméra orientée vers le conducteur pour assurer une bonne visibilité de la surveillance du conducteur. (véhicule doit être éteint) + + + Reset Calibration + Réinitialiser la calibration + + + RESET + RÉINITIALISER + + + Are you sure you want to reset calibration? + Êtes-vous sûr de vouloir réinitialiser la calibration ? + + + Reset + Réinitialiser + + + Review Training Guide + Revoir le guide de formation + + + REVIEW + REVOIR + + + Review the rules, features, and limitations of openpilot + Revoir les règles, fonctionnalités et limitations d'openpilot + + + Are you sure you want to review the training guide? + Êtes-vous sûr de vouloir revoir le guide de formation ? + + + Review + Revoir + + + Regulatory + Réglementaire + + + VIEW + VOIR + + + Change Language + Changer de langue + + + CHANGE + CHANGER + + + Select a language + Choisir une langue + + + Reboot + Redémarrer + + + Power Off + Éteindre + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot nécessite que l'appareil soit monté à 4° à gauche ou à droite et à 5° vers le haut ou 8° vers le bas. openpilot se calibre en continu, la réinitialisation est rarement nécessaire. + + + Your device is pointed %1° %2 and %3° %4. + Votre appareil est orienté %1° %2 et %3° %4. + + + down + bas + + + up + haut + + + left + gauche + + + right + droite + + + Are you sure you want to reboot? + Êtes-vous sûr de vouloir redémarrer ? + + + Disengage to Reboot + Désengager pour redémarrer + + + Are you sure you want to power off? + Êtes-vous sûr de vouloir éteindre ? + + + Disengage to Power Off + Désengager pour éteindre + + + + DriveStats + + Drives + Trajets + + + Hours + Heures + + + ALL TIME + DEPUIS TOUJOURS + + + PAST WEEK + CETTE SEMAINE + + + KM + KM + + + Miles + Miles + + + + DriverViewScene + + camera starting + démarrage de la caméra + + + + ExperimentalModeButton + + EXPERIMENTAL MODE ON + MODE EXPÉRIMENTAL ACTIVÉ + + + CHILL MODE ON + MODE DÉTENTE ACTIVÉ + + + + InputDialog + + Cancel + Annuler + + + Need at least %n character(s)! + + Besoin d'au moins %n caractère ! + Besoin d'au moins %n caractères ! + + + + + Installer + + Installing... + Installation... + + + + MapETA + + eta + eta + + + min + min + + + hr + h + + + + MapSettings + + NAVIGATION + NAVIGATION + + + Manage at connect.comma.ai + Gérer sur connect.comma.ai + + + + MapWindow + + Map Loading + Chargement de la carte + + + Waiting for GPS + En attente du GPS + + + Waiting for route + En attente d'un trajet + + + + MultiOptionDialog + + Select + Sélectionner + + + Cancel + Annuler + + + + Networking + + Advanced + Avancé + + + Enter password + Entrer le mot de passe + + + for "%1" + pour "%1" + + + Wrong password + Mot de passe incorrect + + + + OffroadAlert + + Device temperature too high. System cooling down before starting. Current internal component temperature: %1 + Température de l'appareil trop élevée. Le système doit refroidir avant de démarrer. Température actuelle de l'appareil : %1 + + + Immediately connect to the internet to check for updates. If you do not connect to the internet, openpilot won't engage in %1 + Connectez-vous immédiatement à internet pour vérifier les mises à jour. Si vous ne vous connectez pas à internet, openpilot ne s'engagera pas dans %1 + + + Connect to internet to check for updates. openpilot won't automatically start until it connects to internet to check for updates. + Connectez l'appareil à internet pour vérifier les mises à jour. openpilot ne démarrera pas automatiquement tant qu'il ne se connecte pas à internet pour vérifier les mises à jour. + + + Unable to download updates +%1 + Impossible de télécharger les mises à jour +%1 + + + Invalid date and time settings, system won't start. Connect to internet to set time. + Paramètres de date et d'heure invalides, le système ne démarrera pas. Connectez l'appareil à Internet pour régler l'heure. + + + Taking camera snapshots. System won't start until finished. + Capture de clichés photo. Le système ne démarrera pas tant qu'il n'est pas terminé. + + + An update to your device's operating system is downloading in the background. You will be prompted to update when it's ready to install. + Une mise à jour du système d'exploitation de votre appareil est en cours de téléchargement en arrière-plan. Vous serez invité à effectuer la mise à jour lorsqu'elle sera prête à être installée. + + + Device failed to register. It will not connect to or upload to comma.ai servers, and receives no support from comma.ai. If this is an official device, visit https://comma.ai/support. + L'appareil n'a pas réussi à s'enregistrer. Il ne se connectera pas aux serveurs de comma.ai, n'enverra rien et ne recevra aucune assistance de comma.ai. S'il s'agit d'un appareil officiel, visitez https://comma.ai/support. + + + NVMe drive not mounted. + Le disque NVMe n'est pas monté. + + + Unsupported NVMe drive detected. Device may draw significantly more power and overheat due to the unsupported NVMe. + Disque NVMe non supporté détecté. L'appareil peut consommer beaucoup plus d'énergie et surchauffer en raison du NVMe non supporté. + + + openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai. + openpilot n'a pas pu identifier votre voiture. Votre voiture n'est pas supportée ou ses ECUs ne sont pas reconnues. Veuillez soumettre un pull request pour ajouter les versions de firmware au véhicule approprié. Besoin d'aide ? Rejoignez discord.comma.ai. + + + openpilot was unable to identify your car. Check integrity of cables and ensure all connections are secure, particularly that the comma power is fully inserted in the OBD-II port of the vehicle. Need help? Join discord.comma.ai. + openpilot n'a pas pu identifier votre voiture. Vérifiez l'intégrité des câbles et assurez-vous que toutes les connexions sont correctes, en particulier l'alimentation du comma est totalement insérée dans le port OBD-II du véhicule. Besoin d'aide ? Rejoignez discord.comma.ai. + + + openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. + openpilot a détecté un changement dans la position de montage de l'appareil. Assurez-vous que l'appareil est totalement inséré dans le support et que le support est fermement fixé au pare-brise. + + + + OffroadHome + + UPDATE + MISE À JOUR + + + ALERTS + ALERTES + + + ALERT + ALERTE + + + + PairingPopup + + Pair your device to your comma account + Associez votre appareil à votre compte comma + + + Go to https://connect.comma.ai on your phone + Allez sur https://connect.comma.ai sur votre téléphone + + + Click "add new device" and scan the QR code on the right + Cliquez sur "ajouter un nouvel appareil" et scannez le code QR à droite + + + Bookmark connect.comma.ai to your home screen to use it like an app + Ajoutez connect.comma.ai à votre écran d'accueil pour l'utiliser comme une application + + + + ParamControl + + Enable + Activer + + + Cancel + Annuler + + + + PrimeAdWidget + + Upgrade Now + Mettre à niveau maintenant + + + Become a comma prime member at connect.comma.ai + Devenez membre comma prime sur connect.comma.ai + + + PRIME FEATURES: + FONCTIONNALITÉS PRIME : + + + Remote access + Accès à distance + + + 24/7 LTE connectivity + Connexion LTE 24/7 + + + 1 year of drive storage + 1 an de stockage de trajets + + + Turn-by-turn navigation + Navigation étape par étape + + + + PrimeUserWidget + + ✓ SUBSCRIBED + ✓ ABONNÉ + + + comma prime + comma prime + + + + QObject + + Reboot + Redémarrer + + + Exit + Quitter + + + dashcam + dashcam + + + openpilot + openpilot + + + %n minute(s) ago + + il y a %n minute + il y a %n minutes + + + + %n hour(s) ago + + il y a %n heure + il y a %n heures + + + + %n day(s) ago + + il y a %n jour + il y a %n jours + + + + km + km + + + m + m + + + mi + mi + + + ft + ft + + + + Reset + + Reset failed. Reboot to try again. + Réinitialisation échouée. Redémarrez pour réessayer. + + + Resetting device... +This may take up to a minute. + Réinitialisation de l'appareil... +Cela peut prendre jusqu'à une minute. + + + Are you sure you want to reset your device? + Êtes-vous sûr de vouloir réinitialiser votre appareil ? + + + System Reset + Réinitialisation du système + + + Press confirm to erase all content and settings. Press cancel to resume boot. + Appuyez sur confirmer pour effacer tout le contenu et les paramètres. Appuyez sur annuler pour reprendre le démarrage. + + + Cancel + Annuler + + + Reboot + Redémarrer + + + Confirm + Confirmer + + + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + Impossible de monter la partition data. La partition peut être corrompue. Appuyez sur confirmer pour effacer et réinitialiser votre appareil. + + + + SettingsWindow + + × + × + + + Device + Appareil + + + Network + Réseau + + + Toggles + Options + + + Software + Logiciel + + + + Setup + + Something went wrong. Reboot the device. + Un problème est survenu. Redémarrez l'appareil. + + + Ensure the entered URL is valid, and the device’s internet connection is good. + Assurez-vous que l'URL saisie est valide et que la connexion internet de l'appareil est bonne. + + + No custom software found at this URL. + Aucun logiciel personnalisé trouvé à cette URL. + + + WARNING: Low Voltage + ATTENTION : Tension faible + + + Power your device in a car with a harness or proceed at your own risk. + Alimentez votre appareil dans une voiture avec un harness ou continuez à vos risques et périls. + + + Power off + Éteindre + + + Continue + Continuer + + + Getting Started + Commencer + + + Before we get on the road, let’s finish installation and cover some details. + Avant de prendre la route, terminons l'installation et passons en revue quelques détails. + + + Connect to Wi-Fi + Se connecter au Wi-Fi + + + Back + Retour + + + Enter URL + Entrer l'URL + + + for Custom Software + pour logiciel personnalisé + + + Continue without Wi-Fi + Continuer sans Wi-Fi + + + Waiting for internet + En attente d'internet + + + Downloading... + Téléchargement... + + + Download Failed + Échec du téléchargement + + + Reboot device + Redémarrer l'appareil + + + Start over + Recommencer + + + + SetupWidget + + Finish Setup + Terminer l'installation + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + Associez votre appareil avec comma connect (connect.comma.ai) et profitez de l'offre comma prime. + + + Pair device + Associer l'appareil + + + + Sidebar + + CONNECT + CONNECTER + + + OFFLINE + HORS LIGNE + + + ONLINE + EN LIGNE + + + ERROR + ERREUR + + + TEMP + TEMP + + + HIGH + HAUT + + + GOOD + BON + + + OK + OK + + + VEHICLE + VÉHICULE + + + NO + NON + + + PANDA + PANDA + + + GPS + GPS + + + SEARCH + RECHERCHE + + + -- + -- + + + Wi-Fi + Wi-Fi + + + ETH + ETH + + + 2G + 2G + + + 3G + 3G + + + LTE + LTE + + + 5G + 5G + + + + SoftwarePanel + + Updates are only downloaded while the car is off. + Les mises à jour sont téléchargées uniquement lorsque la voiture est éteinte. + + + Current Version + Version actuelle + + + Download + Télécharger + + + CHECK + VÉRIFIER + + + Install Update + Installer la mise à jour + + + INSTALL + INSTALLER + + + Target Branch + Branche cible + + + SELECT + SÉLECTIONNER + + + Select a branch + Sélectionner une branche + + + Uninstall %1 + Désinstaller %1 + + + UNINSTALL + DÉSINSTALLER + + + Are you sure you want to uninstall? + Êtes-vous sûr de vouloir désinstaller ? + + + Uninstall + Désinstaller + + + failed to check for update + échec de la vérification de la mise à jour + + + DOWNLOAD + TÉLÉCHARGER + + + update available + mise à jour disponible + + + never + jamais + + + up to date, last checked %1 + à jour, dernière vérification %1 + + + + SshControl + + SSH Keys + Clés SSH + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + Attention : Ceci accorde l'accès SSH à toutes les clés publiques de vos paramètres GitHub. N'entrez jamais un nom d'utilisateur GitHub autre que le vôtre. Un employé de comma ne vous demandera JAMAIS d'ajouter son nom d'utilisateur GitHub. + + + ADD + AJOUTER + + + Enter your GitHub username + Entrez votre nom d'utilisateur GitHub + + + LOADING + CHARGEMENT + + + REMOVE + SUPPRIMER + + + Username '%1' has no keys on GitHub + L'utilisateur '%1' n'a pas de clés sur GitHub + + + Request timed out + Délai de la demande dépassé + + + Username '%1' doesn't exist on GitHub + L'utilisateur '%1' n'existe pas sur GitHub + + + + SshToggle + + Enable SSH + Activer SSH + + + + TermsPage + + Terms & Conditions + Termes & Conditions + + + Decline + Refuser + + + Scroll to accept + Faire défiler pour accepter + + + Agree + Accepter + + + + TogglesPanel + + Enable openpilot + Activer openpilot + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + Utilisez le système openpilot pour le régulateur de vitesse adaptatif et l'assistance au maintien de voie. Votre attention est requise en permanence pour utiliser cette fonctionnalité. La modification de ce paramètre prend effet lorsque la voiture est éteinte. + + + openpilot Longitudinal Control (Alpha) + Contrôle longitudinal openpilot (Alpha) + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + ATTENTION : le contrôle longitudinal openpilot est en alpha pour cette voiture et désactivera le freinage d'urgence automatique (AEB). + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + Sur cette voiture, openpilot utilise par défaut le régulateur de vitesse adaptatif intégré à la voiture plutôt que le contrôle longitudinal d'openpilot. Activez ceci pour passer au contrôle longitudinal openpilot. Il est recommandé d'activer le mode expérimental lors de l'activation du contrôle longitudinal openpilot alpha. + + + Experimental Mode + Mode expérimental + + + Disengage on Accelerator Pedal + Désengager avec la pédale d'accélérateur + + + When enabled, pressing the accelerator pedal will disengage openpilot. + Lorsqu'il est activé, appuyer sur la pédale d'accélérateur désengagera openpilot. + + + Enable Lane Departure Warnings + Activer les avertissements de sortie de voie + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + Recevez des alertes pour revenir dans la voie lorsque votre véhicule dérive au-delà d'une ligne de voie détectée sans clignotant activé en roulant à plus de 31 mph (50 km/h). + + + Record and Upload Driver Camera + Enregistrer et télécharger la caméra conducteur + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + Publiez les données de la caméra orientée vers le conducteur et aidez à améliorer l'algorithme de surveillance du conducteur. + + + Use Metric System + Utiliser le système métrique + + + Display speed in km/h instead of mph. + Afficher la vitesse en km/h au lieu de mph. + + + Show ETA in 24h Format + Afficher l'heure d'arrivée en format 24h + + + Use 24h format instead of am/pm + Utiliser le format 24h plutôt que am/pm + + + Show Map on Left Side of UI + Afficher la carte à gauche de l'interface + + + Show map on left side when in split screen view. + Afficher la carte à gauche en mode écran scindé. + + + Aggressive + Aggressif + + + Standard + Standard + + + Relaxed + Détendu + + + Driving Personality + Personnalité de conduite + + + Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. + Le mode standard est recommandé. En mode agressif, openpilot suivra de plus près les voitures de tête et sera plus agressif avec l'accélérateur et le frein. En mode détendu, openpilot restera plus éloigné des voitures de tête. + + + openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: + Par défaut, openpilot conduit en <b>mode détente</b>. Le mode expérimental permet d'activer des <b>fonctionnalités alpha</b> qui ne sont pas prêtes pour le mode détente. Les fonctionnalités expérimentales sont listées ci-dessous : + + + Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; mistakes should be expected. + Laissez le modèle de conduite contrôler l'accélérateur et les freins. openpilot conduira comme il pense qu'un humain le ferait, y compris s'arrêter aux feux rouges et aux panneaux stop. Comme le modèle de conduite décide de la vitesse à adopter, la vitesse définie ne servira que de limite supérieure. Cette fonctionnalité est de qualité alpha ; des erreurs sont à prévoir. + + + New Driving Visualization + Nouvelle visualisation de la conduite + + + Experimental mode is currently unavailable on this car since the car's stock ACC is used for longitudinal control. + Le mode expérimental est actuellement indisponible pour cette voiture car le régulateur de vitesse adaptatif d'origine est utilisé pour le contrôle longitudinal. + + + openpilot longitudinal control may come in a future update. + Le contrôle longitudinal openpilot pourrait être disponible dans une future mise à jour. + + + An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. + Une version alpha du contrôle longitudinal openpilot peut être testée, avec le mode expérimental, sur des branches non publiées. + + + End-to-End Longitudinal Control + Contrôle longitudinal de bout en bout + + + Navigate on openpilot + Navigation avec openpilot + + + When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc. + Lorsque la navigation dispose d'une destination, openpilot entrera les informations de la carte dans le modèle. Cela fournit un contexte utile pour le modèle et permet à openpilot de se diriger à gauche ou à droite de manière appropriée aux bifurcations/sorties. Le comportement relatif au changement de voie reste inchangé et doit toujours être activé par le conducteur. Il s'agit d'une fonctionnalité alpha ; il faut s'attendre à des erreurs, en particulier aux abords des sorties et des bifurcations. Ces erreurs peuvent inclure des franchissements involontaires de passages piétons, des prises de sortie tardives, la conduite vers des zones de séparation de type zebras, etc. + + + The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. + La visualisation de la conduite passera sur la caméra grand angle dirigée vers la route à faible vitesse afin de mieux montrer certains virages. Le logo du mode expérimental s'affichera également dans le coin supérieur droit. Lorsqu'une destination de navigation est définie et que le modèle de conduite l'utilise comme entrée, la trajectoire de conduite sur la carte deviendra verte. + + + Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + Activer le contrôle longitudinal d'openpilot (en alpha) pour autoriser le mode expérimental. + + + + Updater + + Update Required + Mise à jour requise + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + Une mise à jour du système d'exploitation est requise. Connectez votre appareil au Wi-Fi pour une mise à jour plus rapide. La taille du téléchargement est d'environ 1 Go. + + + Connect to Wi-Fi + Se connecter au Wi-Fi + + + Install + Installer + + + Back + Retour + + + Loading... + Chargement... + + + Reboot + Redémarrer + + + Update failed + Échec de la mise à jour + + + + WiFiPromptWidget + + Setup Wi-Fi + Configurer le Wi-Fi + + + Connect to Wi-Fi to upload driving data and help improve openpilot + Connectez-vous au Wi-Fi pour publier les données de conduite et aider à améliorer openpilot + + + Open Settings + Ouvrir les paramètres + + + Ready to upload + Prêt à uploader + + + Training data will be pulled periodically while your device is on Wi-Fi + Les données d'entraînement seront envoyées périodiquement lorsque votre appareil est connecté au réseau Wi-Fi + + + + WifiUI + + Scanning for networks... + Recherche de réseaux... + + + CONNECTING... + CONNEXION... + + + FORGET + OUBLIER + + + Forget Wi-Fi Network "%1"? + Oublier le réseau Wi-Fi "%1" ? + + + Forget + Oublier + + + diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index ef9eb93e80..e766204660 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -353,33 +353,6 @@ hr 時間 - - km - キロメートル - - - mi - マイル - - - - MapInstructions - - km - キロメートル - - - m - メートル - - - mi - マイル - - - ft - フィート - MapSettings @@ -616,6 +589,22 @@ %n 日前 + + km + キロメートル + + + m + メートル + + + mi + マイル + + + ft + フィート + Reset diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index b2473a3fb9..851c306a47 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -353,33 +353,6 @@ hr 시간 - - km - km - - - mi - mi - - - - MapInstructions - - km - km - - - m - m - - - mi - mi - - - ft - ft - MapSettings @@ -617,6 +590,22 @@ %n 일전 + + km + km + + + m + m + + + mi + mi + + + ft + ft + Reset diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index d102fb39ca..7aa0c7c49b 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -354,33 +354,6 @@ hr hr - - km - km - - - mi - mi - - - - MapInstructions - - km - km - - - m - m - - - mi - milha - - - ft - pés - MapSettings @@ -621,6 +594,22 @@ há %n dias + + km + km + + + m + m + + + mi + milha + + + ft + pés + Reset diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 843356c402..9ef2d8a913 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -353,33 +353,6 @@ hr ชม. - - km - กม. - - - mi - ไมล์ - - - - MapInstructions - - km - กม. - - - m - ม. - - - mi - ไมล์ - - - ft - ฟุต - MapSettings @@ -617,6 +590,22 @@ %n วันที่แล้ว + + km + กม. + + + m + ม. + + + mi + ไมล์ + + + ft + ฟุต + Reset diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts new file mode 100644 index 0000000000..ad882f5786 --- /dev/null +++ b/selfdrive/ui/translations/main_tr.ts @@ -0,0 +1,1209 @@ + + + + + AbstractAlert + + Close + Kapat + + + Snooze Update + Güncellemeyi sessize al + + + Reboot and Update + Güncelle ve Yeniden başlat + + + + AdvancedNetworking + + Back + Geri dön + + + Enable Tethering + Kişisel erişim noktasını aç + + + Tethering Password + Kişisel erişim noktasının parolası + + + EDIT + DÜZENLE + + + Enter new tethering password + Erişim noktasına yeni bir sonraki başlatılışında çekilir. parola belirleyin. + + + IP Address + IP Adresi + + + Enable Roaming + Hücresel veri aç + + + APN Setting + APN Ayarları + + + Enter APN + APN Gir + + + leave blank for automatic configuration + otomatik yapılandırma için boş bırakın + + + Cellular Metered + + + + Prevent large data uploads when on a metered connection + + + + + AnnotatedCameraWidget + + km/h + km/h + + + mph + mph + + + MAX + MAX + + + SPEED + HIZ + + + LIMIT + LİMİT + + + + ConfirmationDialog + + Ok + Tamam + + + Cancel + Vazgeç + + + + DeclinePage + + You must accept the Terms and Conditions in order to use openpilot. + Openpilotu kullanmak için Kullanıcı Koşullarını kabul etmelisiniz. + + + Back + Geri + + + Decline, uninstall %1 + Reddet, Kurulumu kaldır. %1 + + + + DestinationWidget + + Home + + + + Work + + + + No destination set + + + + home + + + + work + + + + No %1 location set + + + + + DevicePanel + + Dongle ID + Adaptör ID + + + N/A + N/A + + + Serial + Seri Numara + + + Driver Camera + Sürücü Kamerası + + + PREVIEW + ÖN İZLEME + + + Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off) + Sürücü kamerasının görüş açısını test etmek için kamerayı önizleyin (Araç kapalı olmalıdır.) + + + Reset Calibration + Kalibrasyonu sıfırla + + + RESET + SIFIRLA + + + Are you sure you want to reset calibration? + Kalibrasyon ayarını sıfırlamak istediğinizden emin misiniz? + + + Review Training Guide + Eğitim kılavuzunu inceleyin + + + REVIEW + GÖZDEN GEÇİR + + + Review the rules, features, and limitations of openpilot + openpilot sisteminin kurallarını ve sınırlamalarını gözden geçirin. + + + Are you sure you want to review the training guide? + Eğitim kılavuzunu incelemek istediğinizden emin misiniz? + + + Regulatory + Mevzuat + + + VIEW + BAK + + + Change Language + Dili değiştir + + + CHANGE + DEĞİŞTİR + + + Select a language + Dil seçin + + + Reboot + Yeniden başlat + + + Power Off + Sistemi kapat + + + openpilot requires the device to be mounted within 4° left or right and within 5° up or 8° down. openpilot is continuously calibrating, resetting is rarely required. + openpilot, cihazın 4° sola veya 5° yukarı yada 8° aşağı bakıcak şekilde monte edilmesi gerekmektedir. openpilot sürekli kendisini kalibre edilmektedir ve nadiren sıfırlama gerebilir. + + + Your device is pointed %1° %2 and %3° %4. + Cihazınız %1° %2 ve %3° %4 yönünde ayarlı + + + down + aşağı + + + up + yukarı + + + left + sol + + + right + sağ + + + Are you sure you want to reboot? + Cihazı Tekrar başlatmak istediğinizden eminmisiniz? + + + Disengage to Reboot + Bağlantıyı kes ve Cihazı Yeniden başlat + + + Are you sure you want to power off? + Cihazı kapatmak istediğizden eminmisiniz? + + + Disengage to Power Off + Bağlantıyı kes ve Cihazı kapat + + + Reset + + + + Review + + + + + DriveStats + + Drives + Sürücüler + + + Hours + Saat + + + ALL TIME + TÜM ZAMANLAR + + + PAST WEEK + GEÇEN HAFTA + + + KM + KM + + + Miles + Mil + + + + DriverViewScene + + camera starting + kamera başlatılıyor + + + + ExperimentalModeButton + + EXPERIMENTAL MODE ON + + + + CHILL MODE ON + + + + + InputDialog + + Cancel + Kapat + + + Need at least %n character(s)! + + En az %n karakter gerekli! + + + + + Installer + + Installing... + Yükleniyor... + + + + MapETA + + eta + tahmini varış süresi + + + min + dk + + + hr + saat + + + + MapSettings + + NAVIGATION + + + + Manage at connect.comma.ai + + + + + MapWindow + + Map Loading + Harita yükleniyor + + + Waiting for GPS + GPS verisi bekleniyor... + + + Waiting for route + + + + + MultiOptionDialog + + Select + Seç + + + Cancel + İptal et + + + + Networking + + Advanced + Gelişmiş Seçenekler + + + Enter password + Parolayı girin + + + for "%1" + için "%1" + + + Wrong password + Yalnış parola + + + + OffroadAlert + + Device temperature too high. System cooling down before starting. Current internal component temperature: %1 + + + + Immediately connect to the internet to check for updates. If you do not connect to the internet, openpilot won't engage in %1 + + + + Connect to internet to check for updates. openpilot won't automatically start until it connects to internet to check for updates. + + + + Unable to download updates +%1 + + + + Invalid date and time settings, system won't start. Connect to internet to set time. + + + + Taking camera snapshots. System won't start until finished. + + + + An update to your device's operating system is downloading in the background. You will be prompted to update when it's ready to install. + + + + Device failed to register. It will not connect to or upload to comma.ai servers, and receives no support from comma.ai. If this is an official device, visit https://comma.ai/support. + + + + NVMe drive not mounted. + + + + Unsupported NVMe drive detected. Device may draw significantly more power and overheat due to the unsupported NVMe. + + + + openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai. + + + + openpilot was unable to identify your car. Check integrity of cables and ensure all connections are secure, particularly that the comma power is fully inserted in the OBD-II port of the vehicle. Need help? Join discord.comma.ai. + + + + openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield. + + + + + OffroadHome + + UPDATE + GÜNCELLE + + + ALERTS + UYARILAR + + + ALERT + UYARI + + + + PairingPopup + + Pair your device to your comma account + comma.ai hesabınız ile cihazı eşleştirin + + + Go to https://connect.comma.ai on your phone + Telefonuzdan https://connect.comma.ai sitesine gidin + + + Click "add new device" and scan the QR code on the right + Yeni cihaz eklemek için sağdaki QR kodunu okutun + + + Bookmark connect.comma.ai to your home screen to use it like an app + Uygulama gibi kullanmak için connect.comma.ai sitesini yer işaretlerine ekleyin. + + + + ParamControl + + Enable + + + + Cancel + + + + + PrimeAdWidget + + Upgrade Now + Hemen yükselt + + + Become a comma prime member at connect.comma.ai + connect.comma.ai üzerinden comma prime üyesi olun + + + PRIME FEATURES: + PRIME ABONELİĞİNİN ÖZELLİKLERİ: + + + Remote access + Uzaktan erişim + + + 24/7 LTE connectivity + + + + 1 year of drive storage + + + + Turn-by-turn navigation + + + + + PrimeUserWidget + + ✓ SUBSCRIBED + ✓ ABONE + + + comma prime + comma prime + + + + QObject + + Reboot + Yeniden başlat + + + Exit + Çık + + + dashcam + araç yol kamerası + + + openpilot + openpilot + + + %n minute(s) ago + + %n dakika önce + + + + %n hour(s) ago + + %n saat önce + + + + %n day(s) ago + + %n gün önce + + + + km + km + + + m + m + + + mi + mil + + + ft + ft + + + + Reset + + Reset failed. Reboot to try again. + Sıfırlama başarız oldu. Cihazı yeniden başlatın ve tekrar deneyin. + + + Are you sure you want to reset your device? + Cihazı sıfırlamak istediğinizden eminmisiniz ? + + + System Reset + Sistemi sıfırla + + + Cancel + İptal + + + Reboot + Yeniden başlat + + + Confirm + Onayla + + + Resetting device... +This may take up to a minute. + + + + Press confirm to erase all content and settings. Press cancel to resume boot. + + + + Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device. + + + + + SettingsWindow + + × + x + + + Device + Cihaz + + + Network + Ağ + + + Toggles + Değiştirme + + + Software + Yazılım + + + + Setup + + WARNING: Low Voltage + UYARI: Düşük voltaj + + + Power your device in a car with a harness or proceed at your own risk. + Cihazınızı emniyet kemeri olan bir arabada çalıştırın veya riski kabul ederek devam edin. + + + Power off + Sistemi kapat + + + Continue + Devam et + + + Getting Started + Başlarken + + + Before we get on the road, let’s finish installation and cover some details. + Yola çıkmadan önce kurulumu bitirin ve bazı detayları gözden geçirin.. + + + Connect to Wi-Fi + Wi-Fi ile bağlan + + + Back + Geri + + + Continue without Wi-Fi + Wi-Fi bağlantısı olmadan devam edin + + + Waiting for internet + İnternet bağlantısı bekleniyor. + + + Enter URL + URL girin + + + for Custom Software + özel yazılım için + + + Downloading... + İndiriliyor... + + + Download Failed + İndirme başarısız. + + + Ensure the entered URL is valid, and the device’s internet connection is good. + Girilen URL nin geçerli olduğundan ve cihazın internet bağlantısının olduğunu kontrol edin + + + Reboot device + Cihazı yeniden başlat + + + Start over + Zacznij od początku + + + Something went wrong. Reboot the device. + + + + No custom software found at this URL. + + + + + SetupWidget + + Finish Setup + Kurulumu bitir + + + Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer. + Cihazınızı comma connect (connect.comma.ai) ile eşleştirin ve comma prime aboneliğine göz atın. + + + Pair device + Cihazı eşleştirme + + + + Sidebar + + CONNECT + BAĞLANTI + + + OFFLINE + ÇEVRİMDIŞI + + + ONLINE + ÇEVRİMİÇİ + + + ERROR + HATA + + + TEMP + SICAKLIK + + + HIGH + YÜKSEK + + + GOOD + İYİ + + + OK + TAMAM + + + VEHICLE + ARAÇ + + + NO + HAYIR + + + PANDA + PANDA + + + GPS + GPS + + + SEARCH + ARA + + + -- + -- + + + Wi-Fi + Wi-FI + + + ETH + ETH + + + 2G + 2G + + + 3G + 3G + + + LTE + LTE + + + 5G + 5G + + + + SoftwarePanel + + Uninstall %1 + Kaldır %1 + + + UNINSTALL + KALDIR + + + Are you sure you want to uninstall? + Kaldırmak istediğinden eminmisin? + + + CHECK + KONTROL ET + + + Updates are only downloaded while the car is off. + + + + Current Version + + + + Download + + + + Install Update + + + + INSTALL + + + + Target Branch + + + + SELECT + + + + Select a branch + + + + Uninstall + + + + failed to check for update + + + + DOWNLOAD + + + + update available + + + + never + + + + up to date, last checked %1 + + + + + SshControl + + SSH Keys + SSH Anahtarları + + + Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username. + UYARI: Bu, GitHub ayarlarınızdaki tüm ortak anahtarlara SSH erişimi sağlar. Asla kendi kullanıcı adınız dışında bir sonraki başlatılışında çekilir. GitHub kullanıcı adı girmeyin. + + + ADD + EKLE + + + Enter your GitHub username + Github kullanıcı adınızı giriniz + + + LOADING + YÜKLENİYOR + + + REMOVE + KALDIR + + + Username '%1' has no keys on GitHub + Kullanısının '%1' Github erişim anahtarı yok + + + Request timed out + İstek zaman aşımına uğradı + + + Username '%1' doesn't exist on GitHub + Github kullanıcısı %1 bulunamadı + + + + SshToggle + + Enable SSH + SSH aç + + + + TermsPage + + Terms & Conditions + Şartlar ve Koşullar + + + Decline + Reddet + + + Scroll to accept + Kabul etmek için kaydırın + + + Agree + Kabul et + + + + TogglesPanel + + Enable openpilot + openpilot'u aktifleştir + + + Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off. + Ayarlanabilir hız sabitleyici ve şeritte kalma yardımı için openpilot sistemini kullanın. Bu özelliği kullanırken her zaman dikkatli olmanız gerekiyor. Bu ayarın değiştirilmesi için araç kapatılıp açılması gerekiyor. + + + Enable Lane Departure Warnings + Şerit ihlali uyarı alın + + + Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h). + 50 km/s (31 mph) hızın üzerinde sürüş sırasında aracınız dönüş sinyali vermeden algılanan bir sonraki başlatılışında çekilir. şerit çizgisi ihlalinde şeride geri dönmek için uyarılar alın. + + + Use Metric System + Metrik sistemi kullan + + + Display speed in km/h instead of mph. + Hızı mph yerine km/h şeklinde görüntüleyin. + + + Record and Upload Driver Camera + Sürücü kamerasını kayıt et. + + + Upload data from the driver facing camera and help improve the driver monitoring algorithm. + Sürücüye bakan kamera verisini yükleyin ve Cihazın algoritmasını geliştirmemize yardımcı olun. + + + When enabled, pressing the accelerator pedal will disengage openpilot. + Aktifleştirilirse eğer gaz pedalına basınca openpilot devre dışı kalır. + + + Show ETA in 24h Format + Tahmini varış süresini 24 saat formatı şeklinde göster + + + Use 24h format instead of am/pm + 24 saat formatını kullan + + + Show Map on Left Side of UI + Haritayı arayüzün sol tarafında göster + + + Show map on left side when in split screen view. + Bölünmüş ekran görünümündeyken haritayı sol tarafta göster. + + + openpilot Longitudinal Control (Alpha) + + + + WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB). + + + + On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. + + + + Experimental Mode + + + + Disengage on Accelerator Pedal + + + + Aggressive + + + + Standard + + + + Relaxed + + + + Driving Personality + + + + Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. + + + + openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: + + + + End-to-End Longitudinal Control + + + + Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; mistakes should be expected. + + + + Navigate on openpilot + + + + When navigation has a destination, openpilot will input the map information into the model. This provides useful context for the model and allows openpilot to keep left or right appropriately at forks/exits. Lane change behavior is unchanged and still activated by the driver. This is an alpha quality feature; mistakes should be expected, particularly around exits and forks. These mistakes can include unintended laneline crossings, late exit taking, driving towards dividing barriers in the gore areas, etc. + + + + New Driving Visualization + + + + The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. + + + + Experimental mode is currently unavailable on this car since the car's stock ACC is used for longitudinal control. + + + + openpilot longitudinal control may come in a future update. + + + + An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. + + + + Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + + + + Updater + + Update Required + Güncelleme yapılması gerekli + + + An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB. + İşletim sistemi güncellemesi gerekmektedir. Lütfen Cihazı daha hızlı günceleyebilmesi için bir sonraki başlatılışında çekilir. Wi-Fi ağına bağlayın. Dosyanın boyutu yaklaşık 1GB dır. + + + Connect to Wi-Fi + Wi-Fi ağına bağlan + + + Install + Yükle + + + Back + Geri + + + Loading... + Yükleniyor... + + + Reboot + Yeniden başlat + + + Update failed + Güncelleme başarız oldu + + + + WiFiPromptWidget + + Setup Wi-Fi + + + + Connect to Wi-Fi to upload driving data and help improve openpilot + + + + Open Settings + + + + Ready to upload + + + + Training data will be pulled periodically while your device is on Wi-Fi + + + + + WifiUI + + Scanning for networks... + Ağ aranıyor... + + + CONNECTING... + BAĞLANILIYOR... + + + FORGET + UNUT + + + Forget Wi-Fi Network "%1"? + Wi-Fi ağını unut "%1"? + + + Forget + + + + diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 17c768eb79..48eb63338b 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -353,33 +353,6 @@ hr 小时 - - km - km - - - mi - mi - - - - MapInstructions - - km - km - - - m - m - - - mi - mi - - - ft - ft - MapSettings @@ -617,6 +590,22 @@ %n 天前 + + km + km + + + m + m + + + mi + mi + + + ft + ft + Reset diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 83ab5d8aa3..6eacb6428c 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -353,33 +353,6 @@ hr 小時 - - km - km - - - mi - mi - - - - MapInstructions - - km - km - - - m - m - - - mi - mi - - - ft - ft - MapSettings @@ -617,6 +590,22 @@ %n 天前 + + km + km + + + m + m + + + mi + mi + + + ft + ft + Reset @@ -836,27 +825,27 @@ This may take up to a minute. Wi-Fi - + ETH - + 2G - + 3G - + LTE - + 5G - + diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 95be0e3ed9..32d8ae80ad 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -293,8 +293,11 @@ void Device::setAwake(bool on) { } } -void Device::resetInteractiveTimeout() { - interactive_timeout = (ignition_on ? 10 : 30) * UI_FREQ; +void Device::resetInteractiveTimeout(int timeout) { + if (timeout == -1) { + timeout = (ignition_on ? 10 : 30); + } + interactive_timeout = timeout * UI_FREQ; } void Device::updateBrightness(const UIState &s) { diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 572065d961..31488431b1 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -212,7 +212,7 @@ signals: void interactiveTimeout(); public slots: - void resetInteractiveTimeout(); + void resetInteractiveTimeout(int timeout = -1); void update(const UIState &s); }; diff --git a/system/camerad/test/test_exposure.py b/system/camerad/test/test_exposure.py index 979272d024..8f65744da3 100755 --- a/system/camerad/test/test_exposure.py +++ b/system/camerad/test/test_exposure.py @@ -18,7 +18,9 @@ class TestCamerad(unittest.TestCase): ret = np.clip(im[:,:,2] * 0.114 + im[:,:,1] * 0.587 + im[:,:,0] * 0.299, 0, 255).astype(np.uint8) return ret - def _is_exposure_okay(self, i, med_mean=np.array([[0.2,0.4],[0.2,0.6]])): + def _is_exposure_okay(self, i, med_mean=None): + if med_mean is None: + med_mean = np.array([[0.2,0.4],[0.2,0.6]]) h, w = i.shape[:2] i = i[h//10:9*h//10,w//10:9*w//10] med_ex, mean_ex = med_mean diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 8dc74ce3db..6932ea08b6 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -83,6 +83,17 @@ def affine_irq(val, action): for i in irqs: sudo_write(str(val), f"/proc/irq/{i}/smp_affinity_list") +@lru_cache +def get_device_type(): + # lru_cache and cache can cause memory leaks when used in classes + with open("/sys/firmware/devicetree/base/model") as f: + model = f.read().strip('\x00') + model = model.split('comma ')[-1] + # TODO: remove this with AGNOS 7+ + if model.startswith('Qualcomm'): + model = 'tici' + return model + class Tici(HardwareBase): @cached_property def bus(self): @@ -105,15 +116,8 @@ class Tici(HardwareBase): with open("/VERSION") as f: return f.read().strip() - @lru_cache def get_device_type(self): - with open("/sys/firmware/devicetree/base/model") as f: - model = f.read().strip('\x00') - model = model.split('comma ')[-1] - # TODO: remove this with AGNOS 7+ - if model.startswith('Qualcomm'): - model = 'tici' - return model + return get_device_type() def get_sound_card_online(self): if os.path.isfile('/proc/asound/card0/state'): diff --git a/system/hardware/tici/tests/compare_casync_manifest.py b/system/hardware/tici/tests/compare_casync_manifest.py index b462e93ebc..6d7232bd64 100755 --- a/system/hardware/tici/tests/compare_casync_manifest.py +++ b/system/hardware/tici/tests/compare_casync_manifest.py @@ -40,7 +40,7 @@ if __name__ == "__main__": # Get content-length for each chunk with multiprocessing.Pool() as pool: szs = list(tqdm(pool.imap(get_chunk_download_size, to), total=len(to))) - chunk_sizes = {t.sha: sz for (t, sz) in zip(to, szs)} + chunk_sizes = {t.sha: sz for (t, sz) in zip(to, szs, strict=True)} sources: Dict[str, List[int]] = { 'seed': [], diff --git a/system/hardware/tici/tests/test_hardware.py b/system/hardware/tici/tests/test_hardware.py index d910b13ec4..bb22cb1594 100755 --- a/system/hardware/tici/tests/test_hardware.py +++ b/system/hardware/tici/tests/test_hardware.py @@ -15,6 +15,9 @@ class TestHardware(unittest.TestCase): if not TICI: raise unittest.SkipTest + HARDWARE.initialize_hardware() + HARDWARE.set_power_save(False) + def test_power_save_time(self): ts = [] for _ in range(5): @@ -23,7 +26,7 @@ class TestHardware(unittest.TestCase): HARDWARE.set_power_save(on) ts.append(time.monotonic() - st) - assert 0.1 < np.mean(ts) < 0.2 + assert 0.1 < np.mean(ts) < 0.25 assert max(ts) < 0.3 diff --git a/system/loggerd/encoderd.cc b/system/loggerd/encoderd.cc index 1646b1ec08..6dd1f2ae32 100644 --- a/system/loggerd/encoderd.cc +++ b/system/loggerd/encoderd.cc @@ -115,13 +115,14 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { } LOG("encoder destroy"); - for(auto &e : encoders) { + for (auto &e : encoders) { e->encoder_close(); delete e; } } -void encoderd_thread() { +template +void encoderd_thread(const LogCameraInfo (&cameras)[N]) { EncoderdState s; std::set streams; @@ -136,9 +137,9 @@ void encoderd_thread() { if (!streams.empty()) { std::vector encoder_threads; for (auto stream : streams) { - auto it = std::find_if(std::begin(cameras_logged), std::end(cameras_logged), + auto it = std::find_if(std::begin(cameras), std::end(cameras), [stream](auto &cam) { return cam.stream_type == stream; }); - assert(it != std::end(cameras_logged)); + assert(it != std::end(cameras)); ++s.max_waiting; encoder_threads.push_back(std::thread(encoder_thread, &s, *it)); } @@ -147,7 +148,7 @@ void encoderd_thread() { } } -int main() { +int main(int argc, char* argv[]) { if (!Hardware::PC()) { int ret; ret = util::set_realtime_priority(52); @@ -155,6 +156,15 @@ int main() { ret = util::set_core_affinity({3}); assert(ret == 0); } - encoderd_thread(); + if (argc > 1) { + std::string arg1(argv[1]); + if (arg1 == "--stream") { + encoderd_thread(stream_cameras_logged); + } else { + LOGE("Argument '%s' is not supported", arg1.c_str()); + } + } else { + encoderd_thread(cameras_logged); + } return 0; } diff --git a/system/loggerd/loggerd.cc b/system/loggerd/loggerd.cc index 5bbeb43d53..56fc11f62c 100644 --- a/system/loggerd/loggerd.cc +++ b/system/loggerd/loggerd.cc @@ -205,7 +205,8 @@ void loggerd_thread() { // subscribe to all socks for (const auto& it : services) { const bool encoder = strcmp(it.name+strlen(it.name)-strlen("EncodeData"), "EncodeData") == 0; - if (!it.should_log && !encoder) continue; + const bool livestream_encoder = strncmp(it.name, "livestream", strlen("livestream")) == 0; + if (!it.should_log && (!encoder || livestream_encoder)) continue; LOGD("logging %s (on port %d)", it.name, it.port); SubSocket * sock = SubSocket::create(ctx.get(), it.name); diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 4100f12f8d..531b30e9f2 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -12,7 +12,9 @@ #include "system/loggerd/logger.h" constexpr int MAIN_FPS = 20; -const int MAIN_BITRATE = 10000000; +const int MAIN_BITRATE = 1e7; +const int LIVESTREAM_BITRATE = 1e6; +const int QCAM_BITRATE = 256000; #define NO_CAMERA_PATIENCE 500 // fall back to time-based rotation if all cameras are dead @@ -26,11 +28,10 @@ const int SEGMENT_LENGTH = LOGGERD_TEST ? atoi(getenv("LOGGERD_SEGMENT_LENGTH")) constexpr char PRESERVE_ATTR_NAME[] = "user.preserve"; constexpr char PRESERVE_ATTR_VALUE = '1'; - class EncoderInfo { public: const char *publish_name; - const char *filename; + const char *filename = NULL; bool record = true; int frame_width = 1928; int frame_height = 1208; @@ -57,11 +58,13 @@ const EncoderInfo main_road_encoder_info = { .filename = "fcamera.hevc", INIT_ENCODE_FUNCTIONS(RoadEncode), }; + const EncoderInfo main_wide_road_encoder_info = { .publish_name = "wideRoadEncodeData", .filename = "ecamera.hevc", INIT_ENCODE_FUNCTIONS(WideRoadEncode), }; + const EncoderInfo main_driver_encoder_info = { .publish_name = "driverEncodeData", .filename = "dcamera.hevc", @@ -69,17 +72,40 @@ const EncoderInfo main_driver_encoder_info = { INIT_ENCODE_FUNCTIONS(DriverEncode), }; +const EncoderInfo stream_road_encoder_info = { + .publish_name = "livestreamRoadEncodeData", + .encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, + .record = false, + .bitrate = LIVESTREAM_BITRATE, + INIT_ENCODE_FUNCTIONS(LivestreamRoadEncode), +}; + +const EncoderInfo stream_wide_road_encoder_info = { + .publish_name = "livestreamWideRoadEncodeData", + .encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, + .record = false, + .bitrate = LIVESTREAM_BITRATE, + INIT_ENCODE_FUNCTIONS(LivestreamWideRoadEncode), +}; + +const EncoderInfo stream_driver_encoder_info = { + .publish_name = "livestreamDriverEncodeData", + .encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, + .record = false, + .bitrate = LIVESTREAM_BITRATE, + INIT_ENCODE_FUNCTIONS(LivestreamDriverEncode), +}; + const EncoderInfo qcam_encoder_info = { .publish_name = "qRoadEncodeData", .filename = "qcamera.ts", - .bitrate = 256000, + .bitrate = QCAM_BITRATE, .encode_type = cereal::EncodeIndex::Type::QCAMERA_H264, .frame_width = 526, .frame_height = 330, INIT_ENCODE_FUNCTIONS(QRoadEncode), }; - const LogCameraInfo road_camera_info{ .thread_name = "road_cam_encoder", .type = RoadCam, @@ -101,4 +127,26 @@ const LogCameraInfo driver_camera_info{ .encoder_infos = {main_driver_encoder_info} }; +const LogCameraInfo stream_road_camera_info{ + .thread_name = "road_cam_encoder", + .type = RoadCam, + .stream_type = VISION_STREAM_ROAD, + .encoder_infos = {stream_road_encoder_info} +}; + +const LogCameraInfo stream_wide_road_camera_info{ + .thread_name = "wide_road_cam_encoder", + .type = WideRoadCam, + .stream_type = VISION_STREAM_WIDE_ROAD, + .encoder_infos = {stream_wide_road_encoder_info} +}; + +const LogCameraInfo stream_driver_camera_info{ + .thread_name = "driver_cam_encoder", + .type = DriverCam, + .stream_type = VISION_STREAM_DRIVER, + .encoder_infos = {stream_driver_encoder_info} +}; + const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info}; +const LogCameraInfo stream_cameras_logged[] = {stream_road_camera_info, stream_wide_road_camera_info, stream_driver_camera_info}; diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index 957e6bf3a0..c151afb24f 100755 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -210,7 +210,8 @@ class TestLoggerd(unittest.TestCase): for fn in ["console-ramoops", "pmsg-ramoops-0"]: path = Path(os.path.join("/sys/fs/pstore/", fn)) if path.is_file(): - expected_val = open(path, "rb").read() + with open(path, "rb") as f: + expected_val = f.read() bootlog_val = [e.value for e in boot.pstore.entries if e.key == fn][0] self.assertEqual(expected_val, bootlog_val) diff --git a/system/sensord/rawgps/rawgpsd.py b/system/sensord/rawgps/rawgpsd.py index 54106ca2f9..d9b2c37731 100755 --- a/system/sensord/rawgps/rawgpsd.py +++ b/system/sensord/rawgps/rawgpsd.py @@ -446,7 +446,7 @@ def main() -> NoReturn: report.source = 1 # glonass measurement_status_fields = (measurementStatusFields.items(), measurementStatusGlonassFields.items()) else: - assert False + raise RuntimeError(f"invalid log_type: {log_type}") for k,v in dat.items(): if k == "version": diff --git a/system/sensord/rawgps/structs.py b/system/sensord/rawgps/structs.py index e2f1e1cdc5..bde4e0049c 100644 --- a/system/sensord/rawgps/structs.py +++ b/system/sensord/rawgps/structs.py @@ -317,8 +317,7 @@ def parse_struct(ss): elif typ in ["uint64", "uint64_t"]: st += "Q" else: - print("unknown type", typ) - assert False + raise RuntimeError(f"unknown type {typ}") if '[' in nam: cnt = int(nam.split("[")[1].split("]")[0]) st += st[-1]*(cnt-1) @@ -333,7 +332,7 @@ def dict_unpacker(ss, camelcase = False): if camelcase: nams = [name_to_camelcase(x) for x in nams] sz = calcsize(st) - return lambda x: dict(zip(nams, unpack_from(st, x))), sz + return lambda x: dict(zip(nams, unpack_from(st, x), strict=True)), sz def relist(dat): list_keys = set() diff --git a/system/ubloxd/tests/ublox.py b/system/ubloxd/tests/ublox.py index ddfea174b7..eeb6cde30a 100644 --- a/system/ubloxd/tests/ublox.py +++ b/system/ubloxd/tests/ublox.py @@ -185,8 +185,8 @@ class UBloxAttrDict(dict): def __getattr__(self, name): try: return self.__getitem__(name) - except KeyError: - raise AttributeError(name) + except KeyError as e: + raise RuntimeError(f"ublock invalid attr: {name}") from e def __setattr__(self, name, value): if name in self.__dict__: @@ -270,7 +270,7 @@ class UBloxDescriptor: return size2 = struct.calcsize(self.format2) - for c in range(count): + for _ in range(count): r = UBloxAttrDict() if size2 > len(buf): raise UBloxError("INVALID_SIZE=%u, " % len(buf)) @@ -573,10 +573,10 @@ class UBloxMessage: '''allow access to message fields''' try: return self._fields[name] - except KeyError: + except KeyError as e: if name == 'recs': return self._recs - raise AttributeError(name) + raise AttributeError(name) from e def __setattr__(self, name, value): '''allow access to message fields''' diff --git a/third_party/SConscript b/third_party/SConscript index e8d1789ee0..e5bbfaa07a 100644 --- a/third_party/SConscript +++ b/third_party/SConscript @@ -4,5 +4,3 @@ env.Library('json11', ['json11/json11.cpp'], CCFLAGS=env['CCFLAGS'] + ['-Wno-unq env.Append(CPPPATH=[Dir('json11')]) env.Library('kaitai', ['kaitai/kaitaistream.cpp'], CPPDEFINES=['KS_STR_ENCODING_NONE']) - -SConscript(['cluster/SConscript']) diff --git a/third_party/acados/Darwin/lib/libacados.dylib b/third_party/acados/Darwin/lib/libacados.dylib index ca6c280297..3270553b02 100755 Binary files a/third_party/acados/Darwin/lib/libacados.dylib and b/third_party/acados/Darwin/lib/libacados.dylib differ diff --git a/third_party/acados/Darwin/lib/libblasfeo.dylib b/third_party/acados/Darwin/lib/libblasfeo.dylib index 0217db1048..a7b55b860a 100755 Binary files a/third_party/acados/Darwin/lib/libblasfeo.dylib and b/third_party/acados/Darwin/lib/libblasfeo.dylib differ diff --git a/third_party/acados/Darwin/lib/libhpipm.dylib b/third_party/acados/Darwin/lib/libhpipm.dylib index 420ac45753..d638913f98 100755 Binary files a/third_party/acados/Darwin/lib/libhpipm.dylib and b/third_party/acados/Darwin/lib/libhpipm.dylib differ diff --git a/third_party/acados/Darwin/lib/libqpOASES_e.3.1.dylib b/third_party/acados/Darwin/lib/libqpOASES_e.3.1.dylib index 07dc6ea9b0..ab9888ff82 100755 Binary files a/third_party/acados/Darwin/lib/libqpOASES_e.3.1.dylib and b/third_party/acados/Darwin/lib/libqpOASES_e.3.1.dylib differ diff --git a/third_party/acados/Darwin/t_renderer b/third_party/acados/Darwin/t_renderer index f40327a59e..fa8e9933a8 100755 Binary files a/third_party/acados/Darwin/t_renderer and b/third_party/acados/Darwin/t_renderer differ diff --git a/third_party/acados/acados_template/__init__.py b/third_party/acados/acados_template/__init__.py index f33b75bb7b..bfbe907990 100644 --- a/third_party/acados/acados_template/__init__.py +++ b/third_party/acados/acados_template/__init__.py @@ -1,8 +1,5 @@ # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -31,13 +28,13 @@ # POSSIBILITY OF SUCH DAMAGE.; # -from .acados_model import * -from .generate_c_code_explicit_ode import * -from .generate_c_code_implicit_ode import * -from .generate_c_code_constraint import * -from .generate_c_code_nls_cost import * -from .acados_ocp import * -from .acados_sim import * -from .acados_ocp_solver import * -from .acados_sim_solver import * -from .utils import * +from .acados_model import AcadosModel +from .acados_ocp import AcadosOcp, AcadosOcpConstraints, AcadosOcpCost, AcadosOcpDims, AcadosOcpOptions +from .acados_sim import AcadosSim, AcadosSimDims, AcadosSimOpts +from .acados_ocp_solver import AcadosOcpSolver, get_simulink_default_opts, ocp_get_default_cmake_builder +from .acados_sim_solver import AcadosSimSolver, sim_get_default_cmake_builder +from .utils import print_casadi_expression, get_acados_path, get_python_interface_path, \ + get_tera_exec_path, get_tera, check_casadi_version, acados_dae_model_json_dump, \ + casadi_length, make_object_json_dumpable, J_to_idx, get_default_simulink_opts + +from .zoro_description import ZoroDescription, process_zoro_description diff --git a/third_party/acados/acados_template/acados_layout.json b/third_party/acados/acados_template/acados_layout.json index c9f0b90c73..a1cc5bbdf3 100644 --- a/third_party/acados/acados_template/acados_layout.json +++ b/third_party/acados/acados_template/acados_layout.json @@ -6,6 +6,12 @@ "str" ], "cython_include_dirs": [ + "list" + ], + "json_file": [ + "str" + ], + "shared_lib_ext": [ "str" ], "model": { @@ -15,7 +21,16 @@ "dyn_ext_fun_type" : [ "str" ], - "dyn_source_discrete" : [ + "dyn_generic_source" : [ + "str" + ], + "dyn_impl_dae_fun" : [ + "str" + ], + "dyn_impl_dae_fun_jac" : [ + "str" + ], + "dyn_impl_dae_jac" : [ "str" ], "dyn_disc_fun_jac_hess" : [ @@ -734,6 +749,9 @@ "sim_method_newton_iter": [ "int" ], + "sim_method_newton_tol": [ + "float" + ], "sim_method_jac_reuse": [ "ndarray", [ @@ -761,6 +779,12 @@ "qp_solver_iter_max": [ "int" ], + "qp_solver_cond_ric_alg": [ + "int" + ], + "qp_solver_ric_alg": [ + "int" + ], "nlp_solver_tol_stat": [ "float" ], @@ -776,6 +800,9 @@ "nlp_solver_max_iter": [ "int" ], + "nlp_solver_ext_qp_res": [ + "int" + ], "print_level": [ "int" ], @@ -794,6 +821,9 @@ "ext_cost_num_hess": [ "int" ], + "ext_fun_compile_flags": [ + "str" + ], "model_external_shared_lib_dir": [ "str" ], diff --git a/third_party/acados/acados_template/acados_model.py b/third_party/acados/acados_template/acados_model.py index e292cc7477..b7c6945442 100644 --- a/third_party/acados/acados_template/acados_model.py +++ b/third_party/acados/acados_template/acados_model.py @@ -1,8 +1,5 @@ # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -37,7 +34,7 @@ class AcadosModel(): Class containing all the information to code generate the external CasADi functions that are needed when creating an acados ocp solver or acados integrator. Thus, this class contains: - + a) the :py:attr:`name` of the model, b) all CasADi variables/expressions needed in the CasADi function generation process. """ @@ -73,7 +70,7 @@ class AcadosModel(): """ self.dyn_ext_fun_type = 'casadi' #: type of external functions for dynamics module; 'casadi' or 'generic'; Default: 'casadi' - self.dyn_source_discrete = None #: name of source file for discrete dyanamics; Default: :code:`None` + self.dyn_generic_source = None #: name of source file for discrete dyanamics; Default: :code:`None` self.dyn_disc_fun_jac_hess = None #: name of function discrete dyanamics + jacobian and hessian; Default: :code:`None` self.dyn_disc_fun_jac = None #: name of function discrete dyanamics + jacobian; Default: :code:`None` self.dyn_disc_fun = None #: name of function discrete dyanamics; Default: :code:`None` @@ -87,7 +84,9 @@ class AcadosModel(): ## for OCP # constraints + # BGH(default): lh <= h(x, u) <= uh self.con_h_expr = None #: CasADi expression for the constraint :math:`h`; Default: :code:`None` + # BGP(convex over nonlinear): lphi <= phi(r(x, u)) <= uphi self.con_phi_expr = None #: CasADi expression for the constraint phi; Default: :code:`None` self.con_r_expr = None #: CasADi expression for the constraint phi(r); Default: :code:`None` self.con_r_in_phi = None @@ -107,61 +106,49 @@ class AcadosModel(): self.cost_expr_ext_cost_custom_hess_e = None #: CasADi expression for custom hessian (only for external cost), terminal; Default: :code:`None` self.cost_expr_ext_cost_custom_hess_0 = None #: CasADi expression for custom hessian (only for external cost), initial; Default: :code:`None` - -def acados_model_strip_casadi_symbolics(model): - out = model - if 'f_impl_expr' in out.keys(): - del out['f_impl_expr'] - if 'f_expl_expr' in out.keys(): - del out['f_expl_expr'] - if 'disc_dyn_expr' in out.keys(): - del out['disc_dyn_expr'] - if 'x' in out.keys(): - del out['x'] - if 'xdot' in out.keys(): - del out['xdot'] - if 'u' in out.keys(): - del out['u'] - if 'z' in out.keys(): - del out['z'] - if 'p' in out.keys(): - del out['p'] - # constraints - if 'con_phi_expr' in out.keys(): - del out['con_phi_expr'] - if 'con_h_expr' in out.keys(): - del out['con_h_expr'] - if 'con_r_expr' in out.keys(): - del out['con_r_expr'] - if 'con_r_in_phi' in out.keys(): - del out['con_r_in_phi'] - # terminal - if 'con_phi_expr_e' in out.keys(): - del out['con_phi_expr_e'] - if 'con_h_expr_e' in out.keys(): - del out['con_h_expr_e'] - if 'con_r_expr_e' in out.keys(): - del out['con_r_expr_e'] - if 'con_r_in_phi_e' in out.keys(): - del out['con_r_in_phi_e'] - # cost - if 'cost_y_expr' in out.keys(): - del out['cost_y_expr'] - if 'cost_y_expr_e' in out.keys(): - del out['cost_y_expr_e'] - if 'cost_y_expr_0' in out.keys(): - del out['cost_y_expr_0'] - if 'cost_expr_ext_cost' in out.keys(): - del out['cost_expr_ext_cost'] - if 'cost_expr_ext_cost_e' in out.keys(): - del out['cost_expr_ext_cost_e'] - if 'cost_expr_ext_cost_0' in out.keys(): - del out['cost_expr_ext_cost_0'] - if 'cost_expr_ext_cost_custom_hess' in out.keys(): - del out['cost_expr_ext_cost_custom_hess'] - if 'cost_expr_ext_cost_custom_hess_e' in out.keys(): - del out['cost_expr_ext_cost_custom_hess_e'] - if 'cost_expr_ext_cost_custom_hess_0' in out.keys(): - del out['cost_expr_ext_cost_custom_hess_0'] - - return out + ## CONVEX_OVER_NONLINEAR convex-over-nonlinear cost: psi(y(x, u, p) - y_ref; p) + self.cost_psi_expr_0 = None + """ + CasADi expression for the outer loss function :math:`\psi(r, p)`, initial; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_0` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_psi_expr = None + """ + CasADi expression for the outer loss function :math:`\psi(r, p)`; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_psi_expr_e = None + """ + CasADi expression for the outer loss function :math:`\psi(r, p)`, terminal; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_e` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_r_in_psi_expr_0 = None + """ + CasADi expression for the argument :math:`r`; to the outer loss function :math:`\psi(r, p)`, initial; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_0` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_r_in_psi_expr = None + """ + CasADi expression for the argument :math:`r`; to the outer loss function :math:`\psi(r, p)`; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_r_in_psi_expr_e = None + """ + CasADi expression for the argument :math:`r`; to the outer loss function :math:`\psi(r, p)`, terminal; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_e` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_conl_custom_outer_hess_0 = None + """ + CasADi expression for the custom hessian of the outer loss function (only for convex-over-nonlinear cost), initial; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_0` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_conl_custom_outer_hess = None + """ + CasADi expression for the custom hessian of the outer loss function (only for convex-over-nonlinear cost); Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type` == 'CONVEX_OVER_NONLINEAR'. + """ + self.cost_conl_custom_outer_hess_e = None + """ + CasADi expression for the custom hessian of the outer loss function (only for convex-over-nonlinear cost), terminal; Default: :code:`None` + Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.cost_type_e` == 'CONVEX_OVER_NONLINEAR'. + """ diff --git a/third_party/acados/acados_template/acados_ocp.py b/third_party/acados/acados_template/acados_ocp.py index 80970239eb..ec02822ceb 100644 --- a/third_party/acados/acados_template/acados_ocp.py +++ b/third_party/acados/acados_template/acados_ocp.py @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -35,7 +32,7 @@ import numpy as np import os from .acados_model import AcadosModel -from .utils import get_acados_path, J_to_idx, J_to_idx_slack +from .utils import get_acados_path, J_to_idx, J_to_idx_slack, get_lib_ext class AcadosOcpDims: """ @@ -273,224 +270,224 @@ class AcadosOcpDims: if isinstance(nx, int) and nx > 0: self.__nx = nx else: - raise Exception('Invalid nx value, expected positive integer. Exiting.') + raise Exception('Invalid nx value, expected positive integer.') @nz.setter def nz(self, nz): if isinstance(nz, int) and nz > -1: self.__nz = nz else: - raise Exception('Invalid nz value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nz value, expected nonnegative integer.') @nu.setter def nu(self, nu): if isinstance(nu, int) and nu > -1: self.__nu = nu else: - raise Exception('Invalid nu value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nu value, expected nonnegative integer.') @np.setter def np(self, np): if isinstance(np, int) and np > -1: self.__np = np else: - raise Exception('Invalid np value, expected nonnegative integer. Exiting.') + raise Exception('Invalid np value, expected nonnegative integer.') @ny_0.setter def ny_0(self, ny_0): if isinstance(ny_0, int) and ny_0 > -1: self.__ny_0 = ny_0 else: - raise Exception('Invalid ny_0 value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ny_0 value, expected nonnegative integer.') @ny.setter def ny(self, ny): if isinstance(ny, int) and ny > -1: self.__ny = ny else: - raise Exception('Invalid ny value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ny value, expected nonnegative integer.') @ny_e.setter def ny_e(self, ny_e): if isinstance(ny_e, int) and ny_e > -1: self.__ny_e = ny_e else: - raise Exception('Invalid ny_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ny_e value, expected nonnegative integer.') @nr.setter def nr(self, nr): if isinstance(nr, int) and nr > -1: self.__nr = nr else: - raise Exception('Invalid nr value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nr value, expected nonnegative integer.') @nr_e.setter def nr_e(self, nr_e): if isinstance(nr_e, int) and nr_e > -1: self.__nr_e = nr_e else: - raise Exception('Invalid nr_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nr_e value, expected nonnegative integer.') @nh.setter def nh(self, nh): if isinstance(nh, int) and nh > -1: self.__nh = nh else: - raise Exception('Invalid nh value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nh value, expected nonnegative integer.') @nh_e.setter def nh_e(self, nh_e): if isinstance(nh_e, int) and nh_e > -1: self.__nh_e = nh_e else: - raise Exception('Invalid nh_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nh_e value, expected nonnegative integer.') @nphi.setter def nphi(self, nphi): if isinstance(nphi, int) and nphi > -1: self.__nphi = nphi else: - raise Exception('Invalid nphi value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nphi value, expected nonnegative integer.') @nphi_e.setter def nphi_e(self, nphi_e): if isinstance(nphi_e, int) and nphi_e > -1: self.__nphi_e = nphi_e else: - raise Exception('Invalid nphi_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nphi_e value, expected nonnegative integer.') @nbx.setter def nbx(self, nbx): if isinstance(nbx, int) and nbx > -1: self.__nbx = nbx else: - raise Exception('Invalid nbx value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nbx value, expected nonnegative integer.') @nbxe_0.setter def nbxe_0(self, nbxe_0): if isinstance(nbxe_0, int) and nbxe_0 > -1: self.__nbxe_0 = nbxe_0 else: - raise Exception('Invalid nbxe_0 value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nbxe_0 value, expected nonnegative integer.') @nbx_0.setter def nbx_0(self, nbx_0): if isinstance(nbx_0, int) and nbx_0 > -1: self.__nbx_0 = nbx_0 else: - raise Exception('Invalid nbx_0 value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nbx_0 value, expected nonnegative integer.') @nbx_e.setter def nbx_e(self, nbx_e): if isinstance(nbx_e, int) and nbx_e > -1: self.__nbx_e = nbx_e else: - raise Exception('Invalid nbx_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nbx_e value, expected nonnegative integer.') @nbu.setter def nbu(self, nbu): if isinstance(nbu, int) and nbu > -1: self.__nbu = nbu else: - raise Exception('Invalid nbu value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nbu value, expected nonnegative integer.') @nsbx.setter def nsbx(self, nsbx): if isinstance(nsbx, int) and nsbx > -1: self.__nsbx = nsbx else: - raise Exception('Invalid nsbx value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsbx value, expected nonnegative integer.') @nsbx_e.setter def nsbx_e(self, nsbx_e): if isinstance(nsbx_e, int) and nsbx_e > -1: self.__nsbx_e = nsbx_e else: - raise Exception('Invalid nsbx_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsbx_e value, expected nonnegative integer.') @nsbu.setter def nsbu(self, nsbu): if isinstance(nsbu, int) and nsbu > -1: self.__nsbu = nsbu else: - raise Exception('Invalid nsbu value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsbu value, expected nonnegative integer.') @nsg.setter def nsg(self, nsg): if isinstance(nsg, int) and nsg > -1: self.__nsg = nsg else: - raise Exception('Invalid nsg value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsg value, expected nonnegative integer.') @nsg_e.setter def nsg_e(self, nsg_e): if isinstance(nsg_e, int) and nsg_e > -1: self.__nsg_e = nsg_e else: - raise Exception('Invalid nsg_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsg_e value, expected nonnegative integer.') @nsh.setter def nsh(self, nsh): if isinstance(nsh, int) and nsh > -1: self.__nsh = nsh else: - raise Exception('Invalid nsh value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsh value, expected nonnegative integer.') @nsh_e.setter def nsh_e(self, nsh_e): if isinstance(nsh_e, int) and nsh_e > -1: self.__nsh_e = nsh_e else: - raise Exception('Invalid nsh_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsh_e value, expected nonnegative integer.') @nsphi.setter def nsphi(self, nsphi): if isinstance(nsphi, int) and nsphi > -1: self.__nsphi = nsphi else: - raise Exception('Invalid nsphi value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsphi value, expected nonnegative integer.') @nsphi_e.setter def nsphi_e(self, nsphi_e): if isinstance(nsphi_e, int) and nsphi_e > -1: self.__nsphi_e = nsphi_e else: - raise Exception('Invalid nsphi_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nsphi_e value, expected nonnegative integer.') @ns.setter def ns(self, ns): if isinstance(ns, int) and ns > -1: self.__ns = ns else: - raise Exception('Invalid ns value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ns value, expected nonnegative integer.') @ns_e.setter def ns_e(self, ns_e): if isinstance(ns_e, int) and ns_e > -1: self.__ns_e = ns_e else: - raise Exception('Invalid ns_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ns_e value, expected nonnegative integer.') @ng.setter def ng(self, ng): if isinstance(ng, int) and ng > -1: self.__ng = ng else: - raise Exception('Invalid ng value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ng value, expected nonnegative integer.') @ng_e.setter def ng_e(self, ng_e): if isinstance(ng_e, int) and ng_e > -1: self.__ng_e = ng_e else: - raise Exception('Invalid ng_e value, expected nonnegative integer. Exiting.') + raise Exception('Invalid ng_e value, expected nonnegative integer.') @N.setter def N(self, N): if isinstance(N, int) and N > 0: self.__N = N else: - raise Exception('Invalid N value, expected positive integer. Exiting.') + raise Exception('Invalid N value, expected positive integer.') def set(self, attr, value): setattr(self, attr, value) @@ -500,6 +497,12 @@ class AcadosOcpCost: """ Class containing the numerical data of the cost: + NOTE: all cost terms, except for the terminal one are weighted with the corresponding time step. + This means given the time steps are :math:`\Delta t_0,..., \Delta t_N`, the total cost is given by: + :math:`c_\\text{total} = \Delta t_0 \cdot c_0(x_0, u_0, p_0, z_0) + ... + \Delta t_{N-1} \cdot c_{N-1}(x_0, u_0, p_0, z_0) + c_N(x_N, p_N)`. + + This means the Lagrange cost term is given in continuous time, this makes up for a seeminglessly OCP discretization with a nonuniform time grid. + In case of LINEAR_LS: stage cost is :math:`l(x,u,z) = || V_x \, x + V_u \, u + V_z \, z - y_\\text{ref}||^2_W`, @@ -508,9 +511,15 @@ class AcadosOcpCost: In case of NONLINEAR_LS: stage cost is - :math:`l(x,u,z) = || y(x,u,z) - y_\\text{ref}||^2_W`, + :math:`l(x,u,z,p) = || y(x,u,z,p) - y_\\text{ref}||^2_W`, terminal cost is - :math:`m(x) = || y^e(x) - y_\\text{ref}^e||^2_{W^e}` + :math:`m(x,p) = || y^e(x,p) - y_\\text{ref}^e||^2_{W^e}` + + In case of CONVEX_OVER_NONLINEAR: + stage cost is + :math:`l(x,u,p) = \psi(y(x,u,p) - y_\\text{ref}, p)`, + terminal cost is + :math:`m(x, p) = \psi^e (y^e(x,p) - y_\\text{ref}^e, p)` """ def __init__(self): # initial stage @@ -548,7 +557,7 @@ class AcadosOcpCost: @property def cost_type_0(self): """Cost type at initial shooting node (0) - -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS} or :code:`None`. + -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS, CONVEX_OVER_NONLINEAR} or :code:`None`. Default: :code:`None`. .. note:: Cost at initial stage is the same as for intermediate shooting nodes if not set differently explicitly. @@ -604,10 +613,10 @@ class AcadosOcpCost: @yref_0.setter def yref_0(self, yref_0): - if isinstance(yref_0, np.ndarray): + if isinstance(yref_0, np.ndarray) and len(yref_0.shape) == 1: self.__yref_0 = yref_0 else: - raise Exception('Invalid yref_0 value, expected numpy array. Exiting.') + raise Exception('Invalid yref_0 value, expected 1-dimensional numpy array.') @W_0.setter def W_0(self, W_0): @@ -615,7 +624,7 @@ class AcadosOcpCost: self.__W_0 = W_0 else: raise Exception('Invalid cost W_0 value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vx_0.setter def Vx_0(self, Vx_0): @@ -623,7 +632,7 @@ class AcadosOcpCost: self.__Vx_0 = Vx_0 else: raise Exception('Invalid cost Vx_0 value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vu_0.setter def Vu_0(self, Vu_0): @@ -631,7 +640,7 @@ class AcadosOcpCost: self.__Vu_0 = Vu_0 else: raise Exception('Invalid cost Vu_0 value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vz_0.setter def Vz_0(self, Vz_0): @@ -639,21 +648,21 @@ class AcadosOcpCost: self.__Vz_0 = Vz_0 else: raise Exception('Invalid cost Vz_0 value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @cost_ext_fun_type_0.setter def cost_ext_fun_type_0(self, cost_ext_fun_type_0): if cost_ext_fun_type_0 in ['casadi', 'generic']: self.__cost_ext_fun_type_0 = cost_ext_fun_type_0 else: - raise Exception('Invalid cost_ext_fun_type_0 value, expected numpy array. Exiting.') + raise Exception('Invalid cost_ext_fun_type_0 value, expected numpy array.') # Lagrange term @property def cost_type(self): """ Cost type at intermediate shooting nodes (1 to N-1) - -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS}. + -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS, CONVEX_OVER_NONLINEAR}. Default: 'LINEAR_LS'. """ return self.__cost_type @@ -695,28 +704,28 @@ class AcadosOcpCost: @property def Zl(self): - """:math:`Z_l` - diagonal of Hessian wrt lower slack at intermediate shooting nodes (1 to N-1). + """:math:`Z_l` - diagonal of Hessian wrt lower slack at intermediate shooting nodes (0 to N-1). Default: :code:`np.array([])`. """ return self.__Zl @property def Zu(self): - """:math:`Z_u` - diagonal of Hessian wrt upper slack at intermediate shooting nodes (1 to N-1). + """:math:`Z_u` - diagonal of Hessian wrt upper slack at intermediate shooting nodes (0 to N-1). Default: :code:`np.array([])`. """ return self.__Zu @property def zl(self): - """:math:`z_l` - gradient wrt lower slack at intermediate shooting nodes (1 to N-1). + """:math:`z_l` - gradient wrt lower slack at intermediate shooting nodes (0 to N-1). Default: :code:`np.array([])`. """ return self.__zl @property def zu(self): - """:math:`z_u` - gradient wrt upper slack at intermediate shooting nodes (1 to N-1). + """:math:`z_u` - gradient wrt upper slack at intermediate shooting nodes (0 to N-1). Default: :code:`np.array([])`. """ return self.__zu @@ -731,19 +740,19 @@ class AcadosOcpCost: @cost_type.setter def cost_type(self, cost_type): - cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL') + cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL', 'CONVEX_OVER_NONLINEAR') if cost_type in cost_types: self.__cost_type = cost_type else: - raise Exception('Invalid cost_type value. Exiting.') + raise Exception('Invalid cost_type value.') @cost_type_0.setter def cost_type_0(self, cost_type_0): - cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL') + cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL', 'CONVEX_OVER_NONLINEAR') if cost_type_0 in cost_types: self.__cost_type_0 = cost_type_0 else: - raise Exception('Invalid cost_type_0 value. Exiting.') + raise Exception('Invalid cost_type_0 value.') @W.setter def W(self, W): @@ -751,7 +760,7 @@ class AcadosOcpCost: self.__W = W else: raise Exception('Invalid cost W value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vx.setter @@ -760,7 +769,7 @@ class AcadosOcpCost: self.__Vx = Vx else: raise Exception('Invalid cost Vx value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vu.setter def Vu(self, Vu): @@ -768,7 +777,7 @@ class AcadosOcpCost: self.__Vu = Vu else: raise Exception('Invalid cost Vu value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vz.setter def Vz(self, Vz): @@ -776,56 +785,56 @@ class AcadosOcpCost: self.__Vz = Vz else: raise Exception('Invalid cost Vz value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @yref.setter def yref(self, yref): - if isinstance(yref, np.ndarray): + if isinstance(yref, np.ndarray) and len(yref.shape) == 1: self.__yref = yref else: - raise Exception('Invalid yref value, expected numpy array. Exiting.') + raise Exception('Invalid yref value, expected 1-dimensional numpy array.') @Zl.setter def Zl(self, Zl): if isinstance(Zl, np.ndarray): self.__Zl = Zl else: - raise Exception('Invalid Zl value, expected numpy array. Exiting.') + raise Exception('Invalid Zl value, expected numpy array.') @Zu.setter def Zu(self, Zu): if isinstance(Zu, np.ndarray): self.__Zu = Zu else: - raise Exception('Invalid Zu value, expected numpy array. Exiting.') + raise Exception('Invalid Zu value, expected numpy array.') @zl.setter def zl(self, zl): if isinstance(zl, np.ndarray): self.__zl = zl else: - raise Exception('Invalid zl value, expected numpy array. Exiting.') + raise Exception('Invalid zl value, expected numpy array.') @zu.setter def zu(self, zu): if isinstance(zu, np.ndarray): self.__zu = zu else: - raise Exception('Invalid zu value, expected numpy array. Exiting.') + raise Exception('Invalid zu value, expected numpy array.') @cost_ext_fun_type.setter def cost_ext_fun_type(self, cost_ext_fun_type): if cost_ext_fun_type in ['casadi', 'generic']: self.__cost_ext_fun_type = cost_ext_fun_type else: - raise Exception('Invalid cost_ext_fun_type value, expected numpy array. Exiting.') + raise Exception("Invalid cost_ext_fun_type value, expected one in ['casadi', 'generic'].") # Mayer term @property def cost_type_e(self): """ Cost type at terminal shooting node (N) - -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS}. + -- string in {EXTERNAL, LINEAR_LS, NONLINEAR_LS, CONVEX_OVER_NONLINEAR}. Default: 'LINEAR_LS'. """ return self.__cost_type_e @@ -881,7 +890,7 @@ class AcadosOcpCost: @property def cost_ext_fun_type_e(self): - """Type of external function for cost at intermediate shooting nodes (1 to N-1). + """Type of external function for cost at terminal shooting node (N). -- string in {casadi, generic} Default: :code:'casadi'. """ @@ -889,12 +898,12 @@ class AcadosOcpCost: @cost_type_e.setter def cost_type_e(self, cost_type_e): - cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL') + cost_types = ('LINEAR_LS', 'NONLINEAR_LS', 'EXTERNAL', 'CONVEX_OVER_NONLINEAR') if cost_type_e in cost_types: self.__cost_type_e = cost_type_e else: - raise Exception('Invalid cost_type_e value. Exiting.') + raise Exception('Invalid cost_type_e value.') @W_e.setter def W_e(self, W_e): @@ -902,7 +911,7 @@ class AcadosOcpCost: self.__W_e = W_e else: raise Exception('Invalid cost W_e value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @Vx_e.setter def Vx_e(self, Vx_e): @@ -910,49 +919,49 @@ class AcadosOcpCost: self.__Vx_e = Vx_e else: raise Exception('Invalid cost Vx_e value. ' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @yref_e.setter def yref_e(self, yref_e): - if isinstance(yref_e, np.ndarray): + if isinstance(yref_e, np.ndarray) and len(yref_e.shape) == 1: self.__yref_e = yref_e else: - raise Exception('Invalid yref_e value, expected numpy array. Exiting.') + raise Exception('Invalid yref_e value, expected 1-dimensional numpy array.') @Zl_e.setter def Zl_e(self, Zl_e): if isinstance(Zl_e, np.ndarray): self.__Zl_e = Zl_e else: - raise Exception('Invalid Zl_e value, expected numpy array. Exiting.') + raise Exception('Invalid Zl_e value, expected numpy array.') @Zu_e.setter def Zu_e(self, Zu_e): if isinstance(Zu_e, np.ndarray): self.__Zu_e = Zu_e else: - raise Exception('Invalid Zu_e value, expected numpy array. Exiting.') + raise Exception('Invalid Zu_e value, expected numpy array.') @zl_e.setter def zl_e(self, zl_e): if isinstance(zl_e, np.ndarray): self.__zl_e = zl_e else: - raise Exception('Invalid zl_e value, expected numpy array. Exiting.') + raise Exception('Invalid zl_e value, expected numpy array.') @zu_e.setter def zu_e(self, zu_e): if isinstance(zu_e, np.ndarray): self.__zu_e = zu_e else: - raise Exception('Invalid zu_e value, expected numpy array. Exiting.') + raise Exception('Invalid zu_e value, expected numpy array.') @cost_ext_fun_type_e.setter def cost_ext_fun_type_e(self, cost_ext_fun_type_e): if cost_ext_fun_type_e in ['casadi', 'generic']: self.__cost_ext_fun_type_e = cost_ext_fun_type_e else: - raise Exception('Invalid cost_ext_fun_type_e value, expected numpy array. Exiting.') + raise Exception("Invalid cost_ext_fun_type_e value, expected one in ['casadi', 'generic'].") def set(self, attr, value): setattr(self, attr, value) @@ -1578,7 +1587,7 @@ class AcadosOcpConstraints: self.__constr_type = constr_type else: raise Exception('Invalid constr_type value. Possible values are:\n\n' \ - + ',\n'.join(constr_types) + '.\n\nYou have: ' + constr_type + '.\n\nExiting.') + + ',\n'.join(constr_types) + '.\n\nYou have: ' + constr_type + '.\n\n') @constr_type_e.setter def constr_type_e(self, constr_type_e): @@ -1587,7 +1596,7 @@ class AcadosOcpConstraints: self.__constr_type_e = constr_type_e else: raise Exception('Invalid constr_type_e value. Possible values are:\n\n' \ - + ',\n'.join(constr_types) + '.\n\nYou have: ' + constr_type_e + '.\n\nExiting.') + + ',\n'.join(constr_types) + '.\n\nYou have: ' + constr_type_e + '.\n\n') # initial x @lbx_0.setter @@ -1595,35 +1604,35 @@ class AcadosOcpConstraints: if isinstance(lbx_0, np.ndarray): self.__lbx_0 = lbx_0 else: - raise Exception('Invalid lbx_0 value. Exiting.') + raise Exception('Invalid lbx_0 value.') @ubx_0.setter def ubx_0(self, ubx_0): if isinstance(ubx_0, np.ndarray): self.__ubx_0 = ubx_0 else: - raise Exception('Invalid ubx_0 value. Exiting.') + raise Exception('Invalid ubx_0 value.') @idxbx_0.setter def idxbx_0(self, idxbx_0): if isinstance(idxbx_0, np.ndarray): self.__idxbx_0 = idxbx_0 else: - raise Exception('Invalid idxbx_0 value. Exiting.') + raise Exception('Invalid idxbx_0 value.') @Jbx_0.setter def Jbx_0(self, Jbx_0): if isinstance(Jbx_0, np.ndarray): self.__idxbx_0 = J_to_idx(Jbx_0) else: - raise Exception('Invalid Jbx_0 value. Exiting.') + raise Exception('Invalid Jbx_0 value.') @idxbxe_0.setter def idxbxe_0(self, idxbxe_0): if isinstance(idxbxe_0, np.ndarray): self.__idxbxe_0 = idxbxe_0 else: - raise Exception('Invalid idxbxe_0 value. Exiting.') + raise Exception('Invalid idxbxe_0 value.') @x0.setter @@ -1634,7 +1643,7 @@ class AcadosOcpConstraints: self.__idxbx_0 = np.arange(x0.size) self.__idxbxe_0 = np.arange(x0.size) else: - raise Exception('Invalid x0 value. Exiting.') + raise Exception('Invalid x0 value.') # bounds on x @lbx.setter @@ -1642,28 +1651,28 @@ class AcadosOcpConstraints: if isinstance(lbx, np.ndarray): self.__lbx = lbx else: - raise Exception('Invalid lbx value. Exiting.') + raise Exception('Invalid lbx value.') @ubx.setter def ubx(self, ubx): if isinstance(ubx, np.ndarray): self.__ubx = ubx else: - raise Exception('Invalid ubx value. Exiting.') + raise Exception('Invalid ubx value.') @idxbx.setter def idxbx(self, idxbx): if isinstance(idxbx, np.ndarray): self.__idxbx = idxbx else: - raise Exception('Invalid idxbx value. Exiting.') + raise Exception('Invalid idxbx value.') @Jbx.setter def Jbx(self, Jbx): if isinstance(Jbx, np.ndarray): self.__idxbx = J_to_idx(Jbx) else: - raise Exception('Invalid Jbx value. Exiting.') + raise Exception('Invalid Jbx value.') # bounds on u @lbu.setter @@ -1671,28 +1680,28 @@ class AcadosOcpConstraints: if isinstance(lbu, np.ndarray): self.__lbu = lbu else: - raise Exception('Invalid lbu value. Exiting.') + raise Exception('Invalid lbu value.') @ubu.setter def ubu(self, ubu): if isinstance(ubu, np.ndarray): self.__ubu = ubu else: - raise Exception('Invalid ubu value. Exiting.') + raise Exception('Invalid ubu value.') @idxbu.setter def idxbu(self, idxbu): if isinstance(idxbu, np.ndarray): self.__idxbu = idxbu else: - raise Exception('Invalid idxbu value. Exiting.') + raise Exception('Invalid idxbu value.') @Jbu.setter def Jbu(self, Jbu): if isinstance(Jbu, np.ndarray): self.__idxbu = J_to_idx(Jbu) else: - raise Exception('Invalid Jbu value. Exiting.') + raise Exception('Invalid Jbu value.') # bounds on x at shooting node N @lbx_e.setter @@ -1700,28 +1709,28 @@ class AcadosOcpConstraints: if isinstance(lbx_e, np.ndarray): self.__lbx_e = lbx_e else: - raise Exception('Invalid lbx_e value. Exiting.') + raise Exception('Invalid lbx_e value.') @ubx_e.setter def ubx_e(self, ubx_e): if isinstance(ubx_e, np.ndarray): self.__ubx_e = ubx_e else: - raise Exception('Invalid ubx_e value. Exiting.') + raise Exception('Invalid ubx_e value.') @idxbx_e.setter def idxbx_e(self, idxbx_e): if isinstance(idxbx_e, np.ndarray): self.__idxbx_e = idxbx_e else: - raise Exception('Invalid idxbx_e value. Exiting.') + raise Exception('Invalid idxbx_e value.') @Jbx_e.setter def Jbx_e(self, Jbx_e): if isinstance(Jbx_e, np.ndarray): self.__idxbx_e = J_to_idx(Jbx_e) else: - raise Exception('Invalid Jbx_e value. Exiting.') + raise Exception('Invalid Jbx_e value.') # polytopic constraints @D.setter @@ -1730,7 +1739,7 @@ class AcadosOcpConstraints: self.__D = D else: raise Exception('Invalid constraint D value.' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @C.setter def C(self, C): @@ -1738,21 +1747,21 @@ class AcadosOcpConstraints: self.__C = C else: raise Exception('Invalid constraint C value.' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @lg.setter def lg(self, lg): if isinstance(lg, np.ndarray): self.__lg = lg else: - raise Exception('Invalid lg value. Exiting.') + raise Exception('Invalid lg value.') @ug.setter def ug(self, ug): if isinstance(ug, np.ndarray): self.__ug = ug else: - raise Exception('Invalid ug value. Exiting.') + raise Exception('Invalid ug value.') # polytopic constraints at shooting node N @C_e.setter @@ -1761,21 +1770,21 @@ class AcadosOcpConstraints: self.__C_e = C_e else: raise Exception('Invalid constraint C_e value.' \ - + 'Should be 2 dimensional numpy array. Exiting.') + + 'Should be 2 dimensional numpy array.') @lg_e.setter def lg_e(self, lg_e): if isinstance(lg_e, np.ndarray): self.__lg_e = lg_e else: - raise Exception('Invalid lg_e value. Exiting.') + raise Exception('Invalid lg_e value.') @ug_e.setter def ug_e(self, ug_e): if isinstance(ug_e, np.ndarray): self.__ug_e = ug_e else: - raise Exception('Invalid ug_e value. Exiting.') + raise Exception('Invalid ug_e value.') # nonlinear constraints @lh.setter @@ -1783,14 +1792,14 @@ class AcadosOcpConstraints: if isinstance(lh, np.ndarray): self.__lh = lh else: - raise Exception('Invalid lh value. Exiting.') + raise Exception('Invalid lh value.') @uh.setter def uh(self, uh): if isinstance(uh, np.ndarray): self.__uh = uh else: - raise Exception('Invalid uh value. Exiting.') + raise Exception('Invalid uh value.') # convex-over-nonlinear constraints @lphi.setter @@ -1798,14 +1807,14 @@ class AcadosOcpConstraints: if isinstance(lphi, np.ndarray): self.__lphi = lphi else: - raise Exception('Invalid lphi value. Exiting.') + raise Exception('Invalid lphi value.') @uphi.setter def uphi(self, uphi): if isinstance(uphi, np.ndarray): self.__uphi = uphi else: - raise Exception('Invalid uphi value. Exiting.') + raise Exception('Invalid uphi value.') # nonlinear constraints at shooting node N @lh_e.setter @@ -1813,14 +1822,14 @@ class AcadosOcpConstraints: if isinstance(lh_e, np.ndarray): self.__lh_e = lh_e else: - raise Exception('Invalid lh_e value. Exiting.') + raise Exception('Invalid lh_e value.') @uh_e.setter def uh_e(self, uh_e): if isinstance(uh_e, np.ndarray): self.__uh_e = uh_e else: - raise Exception('Invalid uh_e value. Exiting.') + raise Exception('Invalid uh_e value.') # convex-over-nonlinear constraints at shooting node N @lphi_e.setter @@ -1828,14 +1837,14 @@ class AcadosOcpConstraints: if isinstance(lphi_e, np.ndarray): self.__lphi_e = lphi_e else: - raise Exception('Invalid lphi_e value. Exiting.') + raise Exception('Invalid lphi_e value.') @uphi_e.setter def uphi_e(self, uphi_e): if isinstance(uphi_e, np.ndarray): self.__uphi_e = uphi_e else: - raise Exception('Invalid uphi_e value. Exiting.') + raise Exception('Invalid uphi_e value.') # SLACK bounds # soft bounds on x @@ -1844,28 +1853,28 @@ class AcadosOcpConstraints: if isinstance(lsbx, np.ndarray): self.__lsbx = lsbx else: - raise Exception('Invalid lsbx value. Exiting.') + raise Exception('Invalid lsbx value.') @usbx.setter def usbx(self, usbx): if isinstance(usbx, np.ndarray): self.__usbx = usbx else: - raise Exception('Invalid usbx value. Exiting.') + raise Exception('Invalid usbx value.') @idxsbx.setter def idxsbx(self, idxsbx): if isinstance(idxsbx, np.ndarray): self.__idxsbx = idxsbx else: - raise Exception('Invalid idxsbx value. Exiting.') + raise Exception('Invalid idxsbx value.') @Jsbx.setter def Jsbx(self, Jsbx): if isinstance(Jsbx, np.ndarray): self.__idxsbx = J_to_idx_slack(Jsbx) else: - raise Exception('Invalid Jsbx value, expected numpy array. Exiting.') + raise Exception('Invalid Jsbx value, expected numpy array.') # soft bounds on u @lsbu.setter @@ -1873,28 +1882,28 @@ class AcadosOcpConstraints: if isinstance(lsbu, np.ndarray): self.__lsbu = lsbu else: - raise Exception('Invalid lsbu value. Exiting.') + raise Exception('Invalid lsbu value.') @usbu.setter def usbu(self, usbu): if isinstance(usbu, np.ndarray): self.__usbu = usbu else: - raise Exception('Invalid usbu value. Exiting.') + raise Exception('Invalid usbu value.') @idxsbu.setter def idxsbu(self, idxsbu): if isinstance(idxsbu, np.ndarray): self.__idxsbu = idxsbu else: - raise Exception('Invalid idxsbu value. Exiting.') + raise Exception('Invalid idxsbu value.') @Jsbu.setter def Jsbu(self, Jsbu): if isinstance(Jsbu, np.ndarray): self.__idxsbu = J_to_idx_slack(Jsbu) else: - raise Exception('Invalid Jsbu value. Exiting.') + raise Exception('Invalid Jsbu value.') # soft bounds on x at shooting node N @lsbx_e.setter @@ -1902,28 +1911,28 @@ class AcadosOcpConstraints: if isinstance(lsbx_e, np.ndarray): self.__lsbx_e = lsbx_e else: - raise Exception('Invalid lsbx_e value. Exiting.') + raise Exception('Invalid lsbx_e value.') @usbx_e.setter def usbx_e(self, usbx_e): if isinstance(usbx_e, np.ndarray): self.__usbx_e = usbx_e else: - raise Exception('Invalid usbx_e value. Exiting.') + raise Exception('Invalid usbx_e value.') @idxsbx_e.setter def idxsbx_e(self, idxsbx_e): if isinstance(idxsbx_e, np.ndarray): self.__idxsbx_e = idxsbx_e else: - raise Exception('Invalid idxsbx_e value. Exiting.') + raise Exception('Invalid idxsbx_e value.') @Jsbx_e.setter def Jsbx_e(self, Jsbx_e): if isinstance(Jsbx_e, np.ndarray): self.__idxsbx_e = J_to_idx_slack(Jsbx_e) else: - raise Exception('Invalid Jsbx_e value. Exiting.') + raise Exception('Invalid Jsbx_e value.') # soft bounds on general linear constraints @@ -1932,28 +1941,28 @@ class AcadosOcpConstraints: if isinstance(lsg, np.ndarray): self.__lsg = lsg else: - raise Exception('Invalid lsg value. Exiting.') + raise Exception('Invalid lsg value.') @usg.setter def usg(self, usg): if isinstance(usg, np.ndarray): self.__usg = usg else: - raise Exception('Invalid usg value. Exiting.') + raise Exception('Invalid usg value.') @idxsg.setter def idxsg(self, idxsg): if isinstance(idxsg, np.ndarray): self.__idxsg = idxsg else: - raise Exception('Invalid idxsg value. Exiting.') + raise Exception('Invalid idxsg value.') @Jsg.setter def Jsg(self, Jsg): if isinstance(Jsg, np.ndarray): self.__idxsg = J_to_idx_slack(Jsg) else: - raise Exception('Invalid Jsg value, expected numpy array. Exiting.') + raise Exception('Invalid Jsg value, expected numpy array.') # soft bounds on nonlinear constraints @@ -1962,21 +1971,21 @@ class AcadosOcpConstraints: if isinstance(lsh, np.ndarray): self.__lsh = lsh else: - raise Exception('Invalid lsh value. Exiting.') + raise Exception('Invalid lsh value.') @ush.setter def ush(self, ush): if isinstance(ush, np.ndarray): self.__ush = ush else: - raise Exception('Invalid ush value. Exiting.') + raise Exception('Invalid ush value.') @idxsh.setter def idxsh(self, idxsh): if isinstance(idxsh, np.ndarray): self.__idxsh = idxsh else: - raise Exception('Invalid idxsh value. Exiting.') + raise Exception('Invalid idxsh value.') @Jsh.setter @@ -1984,7 +1993,7 @@ class AcadosOcpConstraints: if isinstance(Jsh, np.ndarray): self.__idxsh = J_to_idx_slack(Jsh) else: - raise Exception('Invalid Jsh value, expected numpy array. Exiting.') + raise Exception('Invalid Jsh value, expected numpy array.') # soft bounds on convex-over-nonlinear constraints @lsphi.setter @@ -1992,28 +2001,28 @@ class AcadosOcpConstraints: if isinstance(lsphi, np.ndarray): self.__lsphi = lsphi else: - raise Exception('Invalid lsphi value. Exiting.') + raise Exception('Invalid lsphi value.') @usphi.setter def usphi(self, usphi): if isinstance(usphi, np.ndarray): self.__usphi = usphi else: - raise Exception('Invalid usphi value. Exiting.') + raise Exception('Invalid usphi value.') @idxsphi.setter def idxsphi(self, idxsphi): if isinstance(idxsphi, np.ndarray): self.__idxsphi = idxsphi else: - raise Exception('Invalid idxsphi value. Exiting.') + raise Exception('Invalid idxsphi value.') @Jsphi.setter def Jsphi(self, Jsphi): if isinstance(Jsphi, np.ndarray): self.__idxsphi = J_to_idx_slack(Jsphi) else: - raise Exception('Invalid Jsphi value, expected numpy array. Exiting.') + raise Exception('Invalid Jsphi value, expected numpy array.') # soft bounds on general linear constraints at shooting node N @lsg_e.setter @@ -2021,28 +2030,28 @@ class AcadosOcpConstraints: if isinstance(lsg_e, np.ndarray): self.__lsg_e = lsg_e else: - raise Exception('Invalid lsg_e value. Exiting.') + raise Exception('Invalid lsg_e value.') @usg_e.setter def usg_e(self, usg_e): if isinstance(usg_e, np.ndarray): self.__usg_e = usg_e else: - raise Exception('Invalid usg_e value. Exiting.') + raise Exception('Invalid usg_e value.') @idxsg_e.setter def idxsg_e(self, idxsg_e): if isinstance(idxsg_e, np.ndarray): self.__idxsg_e = idxsg_e else: - raise Exception('Invalid idxsg_e value. Exiting.') + raise Exception('Invalid idxsg_e value.') @Jsg_e.setter def Jsg_e(self, Jsg_e): if isinstance(Jsg_e, np.ndarray): self.__idxsg_e = J_to_idx_slack(Jsg_e) else: - raise Exception('Invalid Jsg_e value, expected numpy array. Exiting.') + raise Exception('Invalid Jsg_e value, expected numpy array.') # soft bounds on nonlinear constraints at shooting node N @lsh_e.setter @@ -2050,28 +2059,28 @@ class AcadosOcpConstraints: if isinstance(lsh_e, np.ndarray): self.__lsh_e = lsh_e else: - raise Exception('Invalid lsh_e value. Exiting.') + raise Exception('Invalid lsh_e value.') @ush_e.setter def ush_e(self, ush_e): if isinstance(ush_e, np.ndarray): self.__ush_e = ush_e else: - raise Exception('Invalid ush_e value. Exiting.') + raise Exception('Invalid ush_e value.') @idxsh_e.setter def idxsh_e(self, idxsh_e): if isinstance(idxsh_e, np.ndarray): self.__idxsh_e = idxsh_e else: - raise Exception('Invalid idxsh_e value. Exiting.') + raise Exception('Invalid idxsh_e value.') @Jsh_e.setter def Jsh_e(self, Jsh_e): if isinstance(Jsh_e, np.ndarray): self.__idxsh_e = J_to_idx_slack(Jsh_e) else: - raise Exception('Invalid Jsh_e value, expected numpy array. Exiting.') + raise Exception('Invalid Jsh_e value, expected numpy array.') # soft bounds on convex-over-nonlinear constraints at shooting node N @@ -2080,28 +2089,28 @@ class AcadosOcpConstraints: if isinstance(lsphi_e, np.ndarray): self.__lsphi_e = lsphi_e else: - raise Exception('Invalid lsphi_e value. Exiting.') + raise Exception('Invalid lsphi_e value.') @usphi_e.setter def usphi_e(self, usphi_e): if isinstance(usphi_e, np.ndarray): self.__usphi_e = usphi_e else: - raise Exception('Invalid usphi_e value. Exiting.') + raise Exception('Invalid usphi_e value.') @idxsphi_e.setter def idxsphi_e(self, idxsphi_e): if isinstance(idxsphi_e, np.ndarray): self.__idxsphi_e = idxsphi_e else: - raise Exception('Invalid idxsphi_e value. Exiting.') + raise Exception('Invalid idxsphi_e value.') @Jsphi_e.setter def Jsphi_e(self, Jsphi_e): if isinstance(Jsphi_e, np.ndarray): self.__idxsphi_e = J_to_idx_slack(Jsphi_e) else: - raise Exception('Invalid Jsphi_e value. Exiting.') + raise Exception('Invalid Jsphi_e value.') def set(self, attr, value): setattr(self, attr, value) @@ -2124,6 +2133,7 @@ class AcadosOcpOptions: self.__sim_method_num_stages = 4 # number of stages in the integrator self.__sim_method_num_steps = 1 # number of steps in the integrator self.__sim_method_newton_iter = 3 # number of Newton iterations in simulation method + self.__sim_method_newton_tol = 0.0 self.__sim_method_jac_reuse = 0 self.__qp_solver_tol_stat = None # QP solver stationarity tolerance self.__qp_solver_tol_eq = None # QP solver equality tolerance @@ -2132,16 +2142,17 @@ class AcadosOcpOptions: self.__qp_solver_iter_max = 50 # QP solver max iter self.__qp_solver_cond_N = None # QP solver: new horizon after partial condensing self.__qp_solver_warm_start = 0 + self.__qp_solver_cond_ric_alg = 1 + self.__qp_solver_ric_alg = 1 self.__nlp_solver_tol_stat = 1e-6 # NLP solver stationarity tolerance self.__nlp_solver_tol_eq = 1e-6 # NLP solver equality tolerance self.__nlp_solver_tol_ineq = 1e-6 # NLP solver inequality self.__nlp_solver_tol_comp = 1e-6 # NLP solver complementarity self.__nlp_solver_max_iter = 100 # NLP solver maximum number of iterations + self.__nlp_solver_ext_qp_res = 0 self.__Tsim = None # automatically calculated as tf/N self.__print_level = 0 # print level self.__initialize_t_slacks = 0 # possible values: 0, 1 - self.__model_external_shared_lib_dir = None # path to the the .so lib - self.__model_external_shared_lib_name = None # name of the the .so lib self.__regularize_method = None self.__time_steps = None self.__shooting_nodes = None @@ -2156,16 +2167,93 @@ class AcadosOcpOptions: self.__full_step_dual = 0 self.__eps_sufficient_descent = 1e-4 self.__hpipm_mode = 'BALANCE' - + # TODO: move those out? they are more about generation than about the acados OCP solver. + self.__ext_fun_compile_flags = '-O2' + self.__model_external_shared_lib_dir = None # path to the the .so lib + self.__model_external_shared_lib_name = None # name of the the .so lib + self.__custom_update_filename = '' + self.__custom_update_header_filename = '' + self.__custom_templates = [] + self.__custom_update_copy = True @property def qp_solver(self): """QP solver to be used in the NLP solver. - String in ('PARTIAL_CONDENSING_HPIPM', 'FULL_CONDENSING_QPOASES', 'FULL_CONDENSING_HPIPM', 'PARTIAL_CONDENSING_QPDUNES', 'PARTIAL_CONDENSING_OSQP'). + String in ('PARTIAL_CONDENSING_HPIPM', 'FULL_CONDENSING_QPOASES', 'FULL_CONDENSING_HPIPM', 'PARTIAL_CONDENSING_QPDUNES', 'PARTIAL_CONDENSING_OSQP', 'FULL_CONDENSING_DAQP'). Default: 'PARTIAL_CONDENSING_HPIPM'. """ return self.__qp_solver + @property + def ext_fun_compile_flags(self): + """ + String with compiler flags for external function compilation. + Default: '-O2'. + """ + return self.__ext_fun_compile_flags + + + @property + def custom_update_filename(self): + """ + Filename of the custom C function to update solver data and parameters in between solver calls + + This file has to implement the functions + int custom_update_init_function([model.name]_solver_capsule* capsule); + int custom_update_function([model.name]_solver_capsule* capsule); + int custom_update_terminate_function([model.name]_solver_capsule* capsule); + + + Default: ''. + """ + return self.__custom_update_filename + + + @property + def custom_templates(self): + """ + List of tuples of the form: + (input_filename, output_filename) + + Custom templates are render in OCP solver generation. + + Default: []. + """ + return self.__custom_templates + + + @property + def custom_update_header_filename(self): + """ + Header filename of the custom C function to update solver data and parameters in between solver calls + + This file has to declare the custom_update functions and look as follows: + + ``` + // Called at the end of solver creation. + // This is allowed to allocate memory and store the pointer to it into capsule->custom_update_memory. + int custom_update_init_function([model.name]_solver_capsule* capsule); + + // Custom update function that can be called between solver calls + int custom_update_function([model.name]_solver_capsule* capsule, double* data, int data_len); + + // Called just before destroying the solver. + // Responsible to free allocated memory, stored at capsule->custom_update_memory. + int custom_update_terminate_function([model.name]_solver_capsule* capsule); + + Default: ''. + """ + return self.__custom_update_header_filename + + @property + def custom_update_copy(self): + """ + Boolean; + If True, the custom update function files are copied into the `code_export_directory`. + """ + return self.__custom_update_copy + + @property def hpipm_mode(self): """ @@ -2230,6 +2318,13 @@ class AcadosOcpOptions: """Regularization method for the Hessian. String in ('NO_REGULARIZE', 'MIRROR', 'PROJECT', 'PROJECT_REDUC_HESS', 'CONVEXIFY') or :code:`None`. + - MIRROR: performs eigenvalue decomposition H = V^T D V and sets D_ii = max(eps, abs(D_ii)) + - PROJECT: performs eigenvalue decomposition H = V^T D V and sets D_ii = max(eps, D_ii) + - CONVEXIFY: Algorithm 6 from Verschueren2017, https://cdn.syscop.de/publications/Verschueren2017.pdf + - PROJECT_REDUC_HESS: experimental + + Note: default eps = 1e-4 + Default: :code:`None`. """ return self.__regularize_method @@ -2279,6 +2374,15 @@ class AcadosOcpOptions: """ return self.__sim_method_newton_iter + @property + def sim_method_newton_tol(self): + """ + Tolerance of Newton system in simulation method. + Type: float: 0.0 means not used + Default: 0.0 + """ + return self.__sim_method_newton_tol + @property def sim_method_jac_reuse(self): """ @@ -2328,10 +2432,42 @@ class AcadosOcpOptions: @property def qp_solver_warm_start(self): - """QP solver: Warm starting. - 0: no warm start; 1: warm start; 2: hot start.""" + """ + QP solver: Warm starting. + 0: no warm start; 1: warm start; 2: hot start. + Default: 0 + """ return self.__qp_solver_warm_start + @property + def qp_solver_cond_ric_alg(self): + """ + QP solver: Determines which algorithm is used in HPIPM condensing. + 0: dont factorize hessian in the condensing; 1: factorize. + Default: 1 + """ + return self.__qp_solver_cond_ric_alg + + @property + def qp_solver_ric_alg(self): + """ + QP solver: Determines which algorithm is used in HPIPM OCP QP solver. + 0 classical Riccati, 1 square-root Riccati. + + Note: taken from [HPIPM paper]: + + (a) the classical implementation requires the reduced Hessian with respect to the dynamics + equality constraints to be positive definite, but allows the full-space Hessian to be indefinite) + (b) the square-root implementation, which in order to reduce the flop count employs the Cholesky + factorization of the Riccati recursion matrix, and therefore requires the full-space Hessian to be positive definite + + [HPIPM paper]: HPIPM: a high-performance quadratic programming framework for model predictive control, Frison and Diehl, 2020 + https://cdn.syscop.de/publications/Frison2020a.pdf + + Default: 1 + """ + return self.__qp_solver_ric_alg + @property def qp_solver_iter_max(self): """ @@ -2429,6 +2565,15 @@ class AcadosOcpOptions: """NLP solver inequality tolerance""" return self.__nlp_solver_tol_ineq + @property + def nlp_solver_ext_qp_res(self): + """Determines if residuals of QP are computed externally within NLP solver (for debugging) + + Type: int; 0 or 1; + Default: 0. + """ + return self.__nlp_solver_ext_qp_res + @property def nlp_solver_tol_comp(self): """NLP solver complementarity tolerance""" @@ -2531,12 +2676,13 @@ class AcadosOcpOptions: def qp_solver(self, qp_solver): qp_solvers = ('PARTIAL_CONDENSING_HPIPM', \ 'FULL_CONDENSING_QPOASES', 'FULL_CONDENSING_HPIPM', \ - 'PARTIAL_CONDENSING_QPDUNES', 'PARTIAL_CONDENSING_OSQP') + 'PARTIAL_CONDENSING_QPDUNES', 'PARTIAL_CONDENSING_OSQP', \ + 'FULL_CONDENSING_DAQP') if qp_solver in qp_solvers: self.__qp_solver = qp_solver else: raise Exception('Invalid qp_solver value. Possible values are:\n\n' \ - + ',\n'.join(qp_solvers) + '.\n\nYou have: ' + qp_solver + '.\n\nExiting.') + + ',\n'.join(qp_solvers) + '.\n\nYou have: ' + qp_solver + '.\n\n') @regularize_method.setter def regularize_method(self, regularize_method): @@ -2546,7 +2692,7 @@ class AcadosOcpOptions: self.__regularize_method = regularize_method else: raise Exception('Invalid regularize_method value. Possible values are:\n\n' \ - + ',\n'.join(regularize_methods) + '.\n\nYou have: ' + regularize_method + '.\n\nExiting.') + + ',\n'.join(regularize_methods) + '.\n\nYou have: ' + regularize_method + '.\n\n') @collocation_type.setter def collocation_type(self, collocation_type): @@ -2555,7 +2701,7 @@ class AcadosOcpOptions: self.__collocation_type = collocation_type else: raise Exception('Invalid collocation_type value. Possible values are:\n\n' \ - + ',\n'.join(collocation_types) + '.\n\nYou have: ' + collocation_type + '.\n\nExiting.') + + ',\n'.join(collocation_types) + '.\n\nYou have: ' + collocation_type + '.\n\n') @hpipm_mode.setter def hpipm_mode(self, hpipm_mode): @@ -2564,7 +2710,48 @@ class AcadosOcpOptions: self.__hpipm_mode = hpipm_mode else: raise Exception('Invalid hpipm_mode value. Possible values are:\n\n' \ - + ',\n'.join(hpipm_modes) + '.\n\nYou have: ' + hpipm_mode + '.\n\nExiting.') + + ',\n'.join(hpipm_modes) + '.\n\nYou have: ' + hpipm_mode + '.\n\n') + + @ext_fun_compile_flags.setter + def ext_fun_compile_flags(self, ext_fun_compile_flags): + if isinstance(ext_fun_compile_flags, str): + self.__ext_fun_compile_flags = ext_fun_compile_flags + else: + raise Exception('Invalid ext_fun_compile_flags, expected a string.\n') + + + @custom_update_filename.setter + def custom_update_filename(self, custom_update_filename): + if isinstance(custom_update_filename, str): + self.__custom_update_filename = custom_update_filename + else: + raise Exception('Invalid custom_update_filename, expected a string.\n') + + @custom_templates.setter + def custom_templates(self, custom_templates): + if not isinstance(custom_templates, list): + raise Exception('Invalid custom_templates, expected a list.\n') + for tup in custom_templates: + if not isinstance(tup, tuple): + raise Exception('Invalid custom_templates, shoubld be list of tuples.\n') + for s in tup: + if not isinstance(s, str): + raise Exception('Invalid custom_templates, shoubld be list of tuples of strings.\n') + self.__custom_templates = custom_templates + + @custom_update_header_filename.setter + def custom_update_header_filename(self, custom_update_header_filename): + if isinstance(custom_update_header_filename, str): + self.__custom_update_header_filename = custom_update_header_filename + else: + raise Exception('Invalid custom_update_header_filename, expected a string.\n') + + @custom_update_copy.setter + def custom_update_copy(self, custom_update_copy): + if isinstance(custom_update_copy, bool): + self.__custom_update_copy = custom_update_copy + else: + raise Exception('Invalid custom_update_copy, expected a bool.\n') @hessian_approx.setter def hessian_approx(self, hessian_approx): @@ -2573,7 +2760,7 @@ class AcadosOcpOptions: self.__hessian_approx = hessian_approx else: raise Exception('Invalid hessian_approx value. Possible values are:\n\n' \ - + ',\n'.join(hessian_approxs) + '.\n\nYou have: ' + hessian_approx + '.\n\nExiting.') + + ',\n'.join(hessian_approxs) + '.\n\nYou have: ' + hessian_approx + '.\n\n') @integrator_type.setter def integrator_type(self, integrator_type): @@ -2582,7 +2769,7 @@ class AcadosOcpOptions: self.__integrator_type = integrator_type else: raise Exception('Invalid integrator_type value. Possible values are:\n\n' \ - + ',\n'.join(integrator_types) + '.\n\nYou have: ' + integrator_type + '.\n\nExiting.') + + ',\n'.join(integrator_types) + '.\n\nYou have: ' + integrator_type + '.\n\n') @tf.setter def tf(self, tf): @@ -2619,7 +2806,7 @@ class AcadosOcpOptions: self.__globalization = globalization else: raise Exception('Invalid globalization value. Possible values are:\n\n' \ - + ',\n'.join(globalization_types) + '.\n\nYou have: ' + globalization + '.\n\nExiting.') + + ',\n'.join(globalization_types) + '.\n\nYou have: ' + globalization + '.\n\n') @alpha_min.setter def alpha_min(self, alpha_min): @@ -2655,7 +2842,7 @@ class AcadosOcpOptions: if isinstance(eps_sufficient_descent, float) and eps_sufficient_descent > 0: self.__eps_sufficient_descent = eps_sufficient_descent else: - raise Exception('Invalid eps_sufficient_descent value. eps_sufficient_descent must be a positive float. Exiting') + raise Exception('Invalid eps_sufficient_descent value. eps_sufficient_descent must be a positive float.') @sim_method_num_stages.setter def sim_method_num_stages(self, sim_method_num_stages): @@ -2663,7 +2850,7 @@ class AcadosOcpOptions: # if isinstance(sim_method_num_stages, int): # self.__sim_method_num_stages = sim_method_num_stages # else: - # raise Exception('Invalid sim_method_num_stages value. sim_method_num_stages must be an integer. Exiting.') + # raise Exception('Invalid sim_method_num_stages value. sim_method_num_stages must be an integer.') self.__sim_method_num_stages = sim_method_num_stages @@ -2673,7 +2860,7 @@ class AcadosOcpOptions: # if isinstance(sim_method_num_steps, int): # self.__sim_method_num_steps = sim_method_num_steps # else: - # raise Exception('Invalid sim_method_num_steps value. sim_method_num_steps must be an integer. Exiting.') + # raise Exception('Invalid sim_method_num_steps value. sim_method_num_steps must be an integer.') self.__sim_method_num_steps = sim_method_num_steps @@ -2683,7 +2870,7 @@ class AcadosOcpOptions: if isinstance(sim_method_newton_iter, int): self.__sim_method_newton_iter = sim_method_newton_iter else: - raise Exception('Invalid sim_method_newton_iter value. sim_method_newton_iter must be an integer. Exiting.') + raise Exception('Invalid sim_method_newton_iter value. sim_method_newton_iter must be an integer.') @sim_method_jac_reuse.setter def sim_method_jac_reuse(self, sim_method_jac_reuse): @@ -2699,42 +2886,57 @@ class AcadosOcpOptions: self.__nlp_solver_type = nlp_solver_type else: raise Exception('Invalid nlp_solver_type value. Possible values are:\n\n' \ - + ',\n'.join(nlp_solver_types) + '.\n\nYou have: ' + nlp_solver_type + '.\n\nExiting.') + + ',\n'.join(nlp_solver_types) + '.\n\nYou have: ' + nlp_solver_type + '.\n\n') @nlp_solver_step_length.setter def nlp_solver_step_length(self, nlp_solver_step_length): if isinstance(nlp_solver_step_length, float) and nlp_solver_step_length > 0: self.__nlp_solver_step_length = nlp_solver_step_length else: - raise Exception('Invalid nlp_solver_step_length value. nlp_solver_step_length must be a positive float. Exiting') + raise Exception('Invalid nlp_solver_step_length value. nlp_solver_step_length must be a positive float.') @levenberg_marquardt.setter def levenberg_marquardt(self, levenberg_marquardt): if isinstance(levenberg_marquardt, float) and levenberg_marquardt >= 0: self.__levenberg_marquardt = levenberg_marquardt else: - raise Exception('Invalid levenberg_marquardt value. levenberg_marquardt must be a positive float. Exiting') + raise Exception('Invalid levenberg_marquardt value. levenberg_marquardt must be a positive float.') @qp_solver_iter_max.setter def qp_solver_iter_max(self, qp_solver_iter_max): if isinstance(qp_solver_iter_max, int) and qp_solver_iter_max > 0: self.__qp_solver_iter_max = qp_solver_iter_max else: - raise Exception('Invalid qp_solver_iter_max value. qp_solver_iter_max must be a positive int. Exiting') + raise Exception('Invalid qp_solver_iter_max value. qp_solver_iter_max must be a positive int.') + + @qp_solver_ric_alg.setter + def qp_solver_ric_alg(self, qp_solver_ric_alg): + if qp_solver_ric_alg in [0, 1]: + self.__qp_solver_ric_alg = qp_solver_ric_alg + else: + raise Exception(f'Invalid qp_solver_ric_alg value. qp_solver_ric_alg must be in [0, 1], got {qp_solver_ric_alg}.') + + @qp_solver_cond_ric_alg.setter + def qp_solver_cond_ric_alg(self, qp_solver_cond_ric_alg): + if qp_solver_cond_ric_alg in [0, 1]: + self.__qp_solver_cond_ric_alg = qp_solver_cond_ric_alg + else: + raise Exception(f'Invalid qp_solver_cond_ric_alg value. qp_solver_cond_ric_alg must be in [0, 1], got {qp_solver_cond_ric_alg}.') + @qp_solver_cond_N.setter def qp_solver_cond_N(self, qp_solver_cond_N): if isinstance(qp_solver_cond_N, int) and qp_solver_cond_N >= 0: self.__qp_solver_cond_N = qp_solver_cond_N else: - raise Exception('Invalid qp_solver_cond_N value. qp_solver_cond_N must be a positive int. Exiting') + raise Exception('Invalid qp_solver_cond_N value. qp_solver_cond_N must be a positive int.') @qp_solver_warm_start.setter def qp_solver_warm_start(self, qp_solver_warm_start): if qp_solver_warm_start in [0, 1, 2]: self.__qp_solver_warm_start = qp_solver_warm_start else: - raise Exception('Invalid qp_solver_warm_start value. qp_solver_warm_start must be 0 or 1 or 2. Exiting') + raise Exception('Invalid qp_solver_warm_start value. qp_solver_warm_start must be 0 or 1 or 2.') @qp_tol.setter def qp_tol(self, qp_tol): @@ -2744,35 +2946,35 @@ class AcadosOcpOptions: self.__qp_solver_tol_stat = qp_tol self.__qp_solver_tol_comp = qp_tol else: - raise Exception('Invalid qp_tol value. qp_tol must be a positive float. Exiting') + raise Exception('Invalid qp_tol value. qp_tol must be a positive float.') @qp_solver_tol_stat.setter def qp_solver_tol_stat(self, qp_solver_tol_stat): if isinstance(qp_solver_tol_stat, float) and qp_solver_tol_stat > 0: self.__qp_solver_tol_stat = qp_solver_tol_stat else: - raise Exception('Invalid qp_solver_tol_stat value. qp_solver_tol_stat must be a positive float. Exiting') + raise Exception('Invalid qp_solver_tol_stat value. qp_solver_tol_stat must be a positive float.') @qp_solver_tol_eq.setter def qp_solver_tol_eq(self, qp_solver_tol_eq): if isinstance(qp_solver_tol_eq, float) and qp_solver_tol_eq > 0: self.__qp_solver_tol_eq = qp_solver_tol_eq else: - raise Exception('Invalid qp_solver_tol_eq value. qp_solver_tol_eq must be a positive float. Exiting') + raise Exception('Invalid qp_solver_tol_eq value. qp_solver_tol_eq must be a positive float.') @qp_solver_tol_ineq.setter def qp_solver_tol_ineq(self, qp_solver_tol_ineq): if isinstance(qp_solver_tol_ineq, float) and qp_solver_tol_ineq > 0: self.__qp_solver_tol_ineq = qp_solver_tol_ineq else: - raise Exception('Invalid qp_solver_tol_ineq value. qp_solver_tol_ineq must be a positive float. Exiting') + raise Exception('Invalid qp_solver_tol_ineq value. qp_solver_tol_ineq must be a positive float.') @qp_solver_tol_comp.setter def qp_solver_tol_comp(self, qp_solver_tol_comp): if isinstance(qp_solver_tol_comp, float) and qp_solver_tol_comp > 0: self.__qp_solver_tol_comp = qp_solver_tol_comp else: - raise Exception('Invalid qp_solver_tol_comp value. qp_solver_tol_comp must be a positive float. Exiting') + raise Exception('Invalid qp_solver_tol_comp value. qp_solver_tol_comp must be a positive float.') @tol.setter def tol(self, tol): @@ -2782,35 +2984,42 @@ class AcadosOcpOptions: self.__nlp_solver_tol_stat = tol self.__nlp_solver_tol_comp = tol else: - raise Exception('Invalid tol value. tol must be a positive float. Exiting') + raise Exception('Invalid tol value. tol must be a positive float.') @nlp_solver_tol_stat.setter def nlp_solver_tol_stat(self, nlp_solver_tol_stat): if isinstance(nlp_solver_tol_stat, float) and nlp_solver_tol_stat > 0: self.__nlp_solver_tol_stat = nlp_solver_tol_stat else: - raise Exception('Invalid nlp_solver_tol_stat value. nlp_solver_tol_stat must be a positive float. Exiting') + raise Exception('Invalid nlp_solver_tol_stat value. nlp_solver_tol_stat must be a positive float.') @nlp_solver_tol_eq.setter def nlp_solver_tol_eq(self, nlp_solver_tol_eq): if isinstance(nlp_solver_tol_eq, float) and nlp_solver_tol_eq > 0: self.__nlp_solver_tol_eq = nlp_solver_tol_eq else: - raise Exception('Invalid nlp_solver_tol_eq value. nlp_solver_tol_eq must be a positive float. Exiting') + raise Exception('Invalid nlp_solver_tol_eq value. nlp_solver_tol_eq must be a positive float.') @nlp_solver_tol_ineq.setter def nlp_solver_tol_ineq(self, nlp_solver_tol_ineq): if isinstance(nlp_solver_tol_ineq, float) and nlp_solver_tol_ineq > 0: self.__nlp_solver_tol_ineq = nlp_solver_tol_ineq else: - raise Exception('Invalid nlp_solver_tol_ineq value. nlp_solver_tol_ineq must be a positive float. Exiting') + raise Exception('Invalid nlp_solver_tol_ineq value. nlp_solver_tol_ineq must be a positive float.') + + @nlp_solver_ext_qp_res.setter + def nlp_solver_ext_qp_res(self, nlp_solver_ext_qp_res): + if nlp_solver_ext_qp_res in [0, 1]: + self.__nlp_solver_ext_qp_res = nlp_solver_ext_qp_res + else: + raise Exception('Invalid nlp_solver_ext_qp_res value. nlp_solver_ext_qp_res must be in [0, 1].') @nlp_solver_tol_comp.setter def nlp_solver_tol_comp(self, nlp_solver_tol_comp): if isinstance(nlp_solver_tol_comp, float) and nlp_solver_tol_comp > 0: self.__nlp_solver_tol_comp = nlp_solver_tol_comp else: - raise Exception('Invalid nlp_solver_tol_comp value. nlp_solver_tol_comp must be a positive float. Exiting') + raise Exception('Invalid nlp_solver_tol_comp value. nlp_solver_tol_comp must be a positive float.') @nlp_solver_max_iter.setter def nlp_solver_max_iter(self, nlp_solver_max_iter): @@ -2818,14 +3027,14 @@ class AcadosOcpOptions: if isinstance(nlp_solver_max_iter, int) and nlp_solver_max_iter > 0: self.__nlp_solver_max_iter = nlp_solver_max_iter else: - raise Exception('Invalid nlp_solver_max_iter value. nlp_solver_max_iter must be a positive int. Exiting') + raise Exception('Invalid nlp_solver_max_iter value. nlp_solver_max_iter must be a positive int.') @print_level.setter def print_level(self, print_level): if isinstance(print_level, int) and print_level >= 0: self.__print_level = print_level else: - raise Exception('Invalid print_level value. print_level takes one of the values >=0. Exiting') + raise Exception('Invalid print_level value. print_level takes one of the values >=0.') @model_external_shared_lib_dir.setter def model_external_shared_lib_dir(self, model_external_shared_lib_dir): @@ -2833,47 +3042,47 @@ class AcadosOcpOptions: self.__model_external_shared_lib_dir = model_external_shared_lib_dir else: raise Exception('Invalid model_external_shared_lib_dir value. Str expected.' \ - + '.\n\nYou have: ' + type(model_external_shared_lib_dir) + '.\n\nExiting.') + + '.\n\nYou have: ' + type(model_external_shared_lib_dir) + '.\n\n') @model_external_shared_lib_name.setter def model_external_shared_lib_name(self, model_external_shared_lib_name): if isinstance(model_external_shared_lib_name, str) : if model_external_shared_lib_name[-3:] == '.so' : raise Exception('Invalid model_external_shared_lib_name value. Remove the .so extension.' \ - + '.\n\nYou have: ' + type(model_external_shared_lib_name) + '.\n\nExiting.') + + '.\n\nYou have: ' + type(model_external_shared_lib_name) + '.\n\n') else : self.__model_external_shared_lib_name = model_external_shared_lib_name else: raise Exception('Invalid model_external_shared_lib_name value. Str expected.' \ - + '.\n\nYou have: ' + type(model_external_shared_lib_name) + '.\n\nExiting.') + + '.\n\nYou have: ' + type(model_external_shared_lib_name) + '.\n\n') @exact_hess_constr.setter def exact_hess_constr(self, exact_hess_constr): if exact_hess_constr in [0, 1]: self.__exact_hess_constr = exact_hess_constr else: - raise Exception('Invalid exact_hess_constr value. exact_hess_constr takes one of the values 0, 1. Exiting') + raise Exception('Invalid exact_hess_constr value. exact_hess_constr takes one of the values 0, 1.') @exact_hess_cost.setter def exact_hess_cost(self, exact_hess_cost): if exact_hess_cost in [0, 1]: self.__exact_hess_cost = exact_hess_cost else: - raise Exception('Invalid exact_hess_cost value. exact_hess_cost takes one of the values 0, 1. Exiting') + raise Exception('Invalid exact_hess_cost value. exact_hess_cost takes one of the values 0, 1.') @exact_hess_dyn.setter def exact_hess_dyn(self, exact_hess_dyn): if exact_hess_dyn in [0, 1]: self.__exact_hess_dyn = exact_hess_dyn else: - raise Exception('Invalid exact_hess_dyn value. exact_hess_dyn takes one of the values 0, 1. Exiting') + raise Exception('Invalid exact_hess_dyn value. exact_hess_dyn takes one of the values 0, 1.') @ext_cost_num_hess.setter def ext_cost_num_hess(self, ext_cost_num_hess): if ext_cost_num_hess in [0, 1]: self.__ext_cost_num_hess = ext_cost_num_hess else: - raise Exception('Invalid ext_cost_num_hess value. ext_cost_num_hess takes one of the values 0, 1. Exiting') + raise Exception('Invalid ext_cost_num_hess value. ext_cost_num_hess takes one of the values 0, 1.') def set(self, attr, value): setattr(self, attr, value) @@ -2893,6 +3102,7 @@ class AcadosOcp: - :py:attr:`solver_options` of type :py:class:`acados_template.acados_ocp.AcadosOcpOptions` - :py:attr:`acados_include_path` (set automatically) + - :py:attr:`shared_lib_ext` (set automatically) - :py:attr:`acados_lib_path` (set automatically) - :py:attr:`parameter_values` - used to initialize the parameters (can be changed) """ @@ -2914,14 +3124,16 @@ class AcadosOcp: """Constraints definitions, type :py:class:`acados_template.acados_ocp.AcadosOcpConstraints`""" self.solver_options = AcadosOcpOptions() """Solver Options, type :py:class:`acados_template.acados_ocp.AcadosOcpOptions`""" - + self.acados_include_path = os.path.join(acados_path, 'include').replace(os.sep, '/') # the replace part is important on Windows for CMake """Path to acados include directory (set automatically), type: `string`""" self.acados_lib_path = os.path.join(acados_path, 'lib').replace(os.sep, '/') # the replace part is important on Windows for CMake """Path to where acados library is located, type: `string`""" + self.shared_lib_ext = get_lib_ext() - import numpy - self.cython_include_dirs = numpy.get_include() + # get cython paths + from sysconfig import get_paths + self.cython_include_dirs = [np.get_include(), get_paths()['include']] self.__parameter_values = np.array([]) self.__problem_class = 'OCP' diff --git a/third_party/acados/acados_template/acados_ocp_solver.py b/third_party/acados/acados_template/acados_ocp_solver.py index beeda2cb0c..ffc9cf4b0e 100644 --- a/third_party/acados/acados_template/acados_ocp_solver.py +++ b/third_party/acados/acados_template/acados_ocp_solver.py @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -38,26 +35,29 @@ import json import numpy as np from datetime import datetime import importlib +import shutil + +from subprocess import DEVNULL, call, STDOUT + from ctypes import POINTER, cast, CDLL, c_void_p, c_char_p, c_double, c_int, c_int64, byref from copy import deepcopy +from pathlib import Path -from .generate_c_code_explicit_ode import generate_c_code_explicit_ode -from .generate_c_code_implicit_ode import generate_c_code_implicit_ode -from .generate_c_code_gnsf import generate_c_code_gnsf -from .generate_c_code_discrete_dynamics import generate_c_code_discrete_dynamics -from .generate_c_code_constraint import generate_c_code_constraint -from .generate_c_code_nls_cost import generate_c_code_nls_cost -from .generate_c_code_external_cost import generate_c_code_external_cost +from .casadi_function_generation import generate_c_code_explicit_ode, \ + generate_c_code_implicit_ode, generate_c_code_gnsf, generate_c_code_discrete_dynamics, \ + generate_c_code_constraint, generate_c_code_nls_cost, generate_c_code_conl_cost, \ + generate_c_code_external_cost +from .gnsf.detect_gnsf_structure import detect_gnsf_structure from .acados_ocp import AcadosOcp -from .acados_model import acados_model_strip_casadi_symbolics +from .acados_model import AcadosModel from .utils import is_column, is_empty, casadi_length, render_template,\ - format_class_dict, ocp_check_against_layout, np_array_to_list, make_model_consistent,\ - set_up_imported_gnsf_model, get_ocp_nlp_layout, get_python_interface_path + format_class_dict, make_object_json_dumpable, make_model_consistent,\ + set_up_imported_gnsf_model, get_ocp_nlp_layout, get_python_interface_path, get_lib_ext, check_casadi_version from .builders import CMakeBuilder -def make_ocp_dims_consistent(acados_ocp): +def make_ocp_dims_consistent(acados_ocp: AcadosOcp): dims = acados_ocp.dims cost = acados_ocp.cost constraints = acados_ocp.constraints @@ -105,6 +105,9 @@ def make_ocp_dims_consistent(acados_ocp): model.cost_expr_ext_cost_0 = model.cost_expr_ext_cost model.cost_expr_ext_cost_custom_hess_0 = model.cost_expr_ext_cost_custom_hess + model.cost_psi_expr_0 = model.cost_psi_expr + model.cost_r_in_psi_expr_0 = model.cost_r_in_psi_expr + if cost.cost_type_0 == 'LINEAR_LS': ny_0 = cost.W_0.shape[0] if cost.Vx_0.shape[0] != ny_0 or cost.Vu_0.shape[0] != ny_0: @@ -133,6 +136,22 @@ def make_ocp_dims_consistent(acados_ocp): f'\nGot W_0[{cost.W.shape}], yref_0[{cost.yref_0.shape}]\n') dims.ny_0 = ny_0 + elif cost.cost_type_0 == 'CONVEX_OVER_NONLINEAR': + if is_empty(model.cost_y_expr_0): + raise Exception('cost_y_expr_0 and/or cost_y_expr not provided.') + ny_0 = casadi_length(model.cost_y_expr_0) + if is_empty(model.cost_r_in_psi_expr_0) or casadi_length(model.cost_r_in_psi_expr_0) != ny_0: + raise Exception('inconsistent dimension ny_0: regarding cost_y_expr_0 and cost_r_in_psi_0.') + if is_empty(model.cost_psi_expr_0) or casadi_length(model.cost_psi_expr_0) != 1: + raise Exception('cost_psi_expr_0 not provided or not scalar-valued.') + if cost.yref_0.shape[0] != ny_0: + raise Exception('inconsistent dimension: regarding yref_0 and cost_y_expr_0, cost_r_in_psi_0.') + dims.ny_0 = ny_0 + + if not (opts.hessian_approx=='EXACT' and opts.exact_hess_cost==False) and opts.hessian_approx != 'GAUSS_NEWTON': + raise Exception("\nWith CONVEX_OVER_NONLINEAR cost type, possible Hessian approximations are:\n" + "GAUSS_NEWTON or EXACT with 'exact_hess_cost' == False.\n") + elif cost.cost_type_0 == 'EXTERNAL': if opts.hessian_approx == 'GAUSS_NEWTON' and opts.ext_cost_num_hess == 0 and model.cost_expr_ext_cost_custom_hess_0 is None: print("\nWARNING: Gauss-Newton Hessian approximation with EXTERNAL cost type not possible!\n" @@ -171,6 +190,23 @@ def make_ocp_dims_consistent(acados_ocp): f'\nGot W[{cost.W.shape}], yref[{cost.yref.shape}]\n') dims.ny = ny + elif cost.cost_type == 'CONVEX_OVER_NONLINEAR': + if is_empty(model.cost_y_expr): + raise Exception('cost_y_expr and/or cost_y_expr not provided.') + ny = casadi_length(model.cost_y_expr) + if is_empty(model.cost_r_in_psi_expr) or casadi_length(model.cost_r_in_psi_expr) != ny: + raise Exception('inconsistent dimension ny: regarding cost_y_expr and cost_r_in_psi.') + if is_empty(model.cost_psi_expr) or casadi_length(model.cost_psi_expr) != 1: + raise Exception('cost_psi_expr not provided or not scalar-valued.') + if cost.yref.shape[0] != ny: + raise Exception('inconsistent dimension: regarding yref and cost_y_expr, cost_r_in_psi.') + dims.ny = ny + + if not (opts.hessian_approx=='EXACT' and opts.exact_hess_cost==False) and opts.hessian_approx != 'GAUSS_NEWTON': + raise Exception("\nWith CONVEX_OVER_NONLINEAR cost type, possible Hessian approximations are:\n" + "GAUSS_NEWTON or EXACT with 'exact_hess_cost' == False.\n") + + elif cost.cost_type == 'EXTERNAL': if opts.hessian_approx == 'GAUSS_NEWTON' and opts.ext_cost_num_hess == 0 and model.cost_expr_ext_cost_custom_hess is None: print("\nWARNING: Gauss-Newton Hessian approximation with EXTERNAL cost type not possible!\n" @@ -202,6 +238,24 @@ def make_ocp_dims_consistent(acados_ocp): raise Exception('inconsistent dimension: regarding W_e, yref_e.') dims.ny_e = ny_e + elif cost.cost_type_e == 'CONVEX_OVER_NONLINEAR': + if is_empty(model.cost_y_expr_e): + raise Exception('cost_y_expr_e not provided.') + ny_e = casadi_length(model.cost_y_expr_e) + if is_empty(model.cost_r_in_psi_expr_e) or casadi_length(model.cost_r_in_psi_expr_e) != ny_e: + raise Exception('inconsistent dimension ny_e: regarding cost_y_expr_e and cost_r_in_psi_e.') + if is_empty(model.cost_psi_expr_e) or casadi_length(model.cost_psi_expr_e) != 1: + raise Exception('cost_psi_expr_e not provided or not scalar-valued.') + if cost.yref_e.shape[0] != ny_e: + raise Exception('inconsistent dimension: regarding yref_e and cost_y_expr_e, cost_r_in_psi_e.') + dims.ny_e = ny_e + + if not (opts.hessian_approx=='EXACT' and opts.exact_hess_cost==False) and opts.hessian_approx != 'GAUSS_NEWTON': + raise Exception("\nWith CONVEX_OVER_NONLINEAR cost type, possible Hessian approximations are:\n" + "GAUSS_NEWTON or EXACT with 'exact_hess_cost' == False.\n") + + + elif cost.cost_type_e == 'EXTERNAL': if opts.hessian_approx == 'GAUSS_NEWTON' and opts.ext_cost_num_hess == 0 and model.cost_expr_ext_cost_custom_hess_e is None: print("\nWARNING: Gauss-Newton Hessian approximation with EXTERNAL cost type not possible!\n" @@ -213,16 +267,13 @@ def make_ocp_dims_consistent(acados_ocp): ## constraints # initial - if (constraints.lbx_0 == [] and constraints.ubx_0 == []): - dims.nbx_0 = 0 - else: - this_shape = constraints.lbx_0.shape - other_shape = constraints.ubx_0.shape - if not this_shape == other_shape: - raise Exception('lbx_0, ubx_0 have different shapes!') - if not is_column(constraints.lbx_0): - raise Exception('lbx_0, ubx_0 must be column vectors!') - dims.nbx_0 = constraints.lbx_0.size + this_shape = constraints.lbx_0.shape + other_shape = constraints.ubx_0.shape + if not this_shape == other_shape: + raise Exception('lbx_0, ubx_0 have different shapes!') + if not is_column(constraints.lbx_0): + raise Exception('lbx_0, ubx_0 must be column vectors!') + dims.nbx_0 = constraints.lbx_0.size if all(constraints.lbx_0 == constraints.ubx_0) and dims.nbx_0 == dims.nx \ and dims.nbxe_0 is None \ @@ -230,8 +281,10 @@ def make_ocp_dims_consistent(acados_ocp): and all(constraints.idxbxe_0 == constraints.idxbx_0): # case: x0 was set: nbx0 are all equlities. dims.nbxe_0 = dims.nbx_0 + elif constraints.idxbxe_0 is not None: + dims.nbxe_0 = constraints.idxbxe_0.shape[0] elif dims.nbxe_0 is None: - # case: x0 was not set -> dont assume nbx0 to be equality constraints. + # case: x0 and idxbxe_0 were not set -> dont assume nbx0 to be equality constraints. dims.nbxe_0 = 0 # path @@ -309,6 +362,8 @@ def make_ocp_dims_consistent(acados_ocp): # Slack dimensions nsbx = constraints.idxsbx.shape[0] + if nsbx > nbx: + raise Exception(f'inconsistent dimension nsbx = {nsbx}. Is greater than nbx = {nbx}.') if is_empty(constraints.lsbx): constraints.lsbx = np.zeros((nsbx,)) elif constraints.lsbx.shape[0] != nsbx: @@ -320,6 +375,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsbx = nsbx nsbu = constraints.idxsbu.shape[0] + if nsbu > nbu: + raise Exception(f'inconsistent dimension nsbu = {nsbu}. Is greater than nbu = {nbu}.') if is_empty(constraints.lsbu): constraints.lsbu = np.zeros((nsbu,)) elif constraints.lsbu.shape[0] != nsbu: @@ -331,6 +388,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsbu = nsbu nsh = constraints.idxsh.shape[0] + if nsh > nh: + raise Exception(f'inconsistent dimension nsh = {nsh}. Is greater than nh = {nh}.') if is_empty(constraints.lsh): constraints.lsh = np.zeros((nsh,)) elif constraints.lsh.shape[0] != nsh: @@ -342,6 +401,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsh = nsh nsphi = constraints.idxsphi.shape[0] + if nsphi > dims.nphi: + raise Exception(f'inconsistent dimension nsphi = {nsphi}. Is greater than nphi = {dims.nphi}.') if is_empty(constraints.lsphi): constraints.lsphi = np.zeros((nsphi,)) elif constraints.lsphi.shape[0] != nsphi: @@ -353,6 +414,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsphi = nsphi nsg = constraints.idxsg.shape[0] + if nsg > ng: + raise Exception(f'inconsistent dimension nsg = {nsg}. Is greater than ng = {ng}.') if is_empty(constraints.lsg): constraints.lsg = np.zeros((nsg,)) elif constraints.lsg.shape[0] != nsg: @@ -386,6 +449,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.ns = ns nsbx_e = constraints.idxsbx_e.shape[0] + if nsbx_e > nbx_e: + raise Exception(f'inconsistent dimension nsbx_e = {nsbx_e}. Is greater than nbx_e = {nbx_e}.') if is_empty(constraints.lsbx_e): constraints.lsbx_e = np.zeros((nsbx_e,)) elif constraints.lsbx_e.shape[0] != nsbx_e: @@ -397,6 +462,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsbx_e = nsbx_e nsh_e = constraints.idxsh_e.shape[0] + if nsh_e > nh_e: + raise Exception(f'inconsistent dimension nsh_e = {nsh_e}. Is greater than nh_e = {nh_e}.') if is_empty(constraints.lsh_e): constraints.lsh_e = np.zeros((nsh_e,)) elif constraints.lsh_e.shape[0] != nsh_e: @@ -408,6 +475,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsh_e = nsh_e nsg_e = constraints.idxsg_e.shape[0] + if nsg_e > ng_e: + raise Exception(f'inconsistent dimension nsg_e = {nsg_e}. Is greater than ng_e = {ng_e}.') if is_empty(constraints.lsg_e): constraints.lsg_e = np.zeros((nsg_e,)) elif constraints.lsg_e.shape[0] != nsg_e: @@ -419,6 +488,8 @@ def make_ocp_dims_consistent(acados_ocp): dims.nsg_e = nsg_e nsphi_e = constraints.idxsphi_e.shape[0] + if nsphi_e > dims.nphi_e: + raise Exception(f'inconsistent dimension nsphi_e = {nsphi_e}. Is greater than nphi_e = {dims.nphi_e}.') if is_empty(constraints.lsphi_e): constraints.lsphi_e = np.zeros((nsphi_e,)) elif constraints.lsphi_e.shape[0] != nsphi_e: @@ -525,7 +596,7 @@ def get_simulink_default_opts(): return simulink_default_opts -def ocp_formulation_json_dump(acados_ocp, simulink_opts, json_file='acados_ocp_nlp.json'): +def ocp_formulation_json_dump(acados_ocp, simulink_opts=None, json_file='acados_ocp_nlp.json'): # Load acados_ocp_nlp structure description ocp_layout = get_ocp_nlp_layout() @@ -543,20 +614,11 @@ def ocp_formulation_json_dump(acados_ocp, simulink_opts, json_file='acados_ocp_n ocp_nlp_dict = format_class_dict(ocp_nlp_dict) - # strip symbolics - ocp_nlp_dict['model'] = acados_model_strip_casadi_symbolics(ocp_nlp_dict['model']) - - # strip shooting_nodes - ocp_nlp_dict['solver_options'].pop('shooting_nodes', None) - dims_dict = format_class_dict(acados_ocp.dims.__dict__) - - ocp_check_against_layout(ocp_nlp_dict, dims_dict) - - # add simulink options - ocp_nlp_dict['simulink_opts'] = simulink_opts + if simulink_opts is not None: + ocp_nlp_dict['simulink_opts'] = simulink_opts with open(json_file, 'w') as f: - json.dump(ocp_nlp_dict, f, default=np_array_to_list, indent=4, sort_keys=True) + json.dump(ocp_nlp_dict, f, default=make_object_json_dumpable, indent=4, sort_keys=True) @@ -587,7 +649,7 @@ def ocp_formulation_json_load(json_file='acados_ocp_nlp.json'): return acados_ocp -def ocp_generate_external_functions(acados_ocp, model): +def ocp_generate_external_functions(acados_ocp: AcadosOcp, model: AcadosModel): model = make_model_consistent(model) @@ -595,27 +657,32 @@ def ocp_generate_external_functions(acados_ocp, model): opts = dict(generate_hess=1) else: opts = dict(generate_hess=0) + + # create code_export_dir, model_dir code_export_dir = acados_ocp.code_export_directory opts['code_export_directory'] = code_export_dir + model_dir = os.path.join(code_export_dir, model.name + '_model') + if not os.path.exists(model_dir): + os.makedirs(model_dir) - if acados_ocp.model.dyn_ext_fun_type != 'casadi': - raise Exception("ocp_generate_external_functions: dyn_ext_fun_type only supports 'casadi' for now.\ - Extending the Python interface with generic function support is welcome.") - - if acados_ocp.solver_options.integrator_type == 'ERK': - # explicit model -- generate C code - generate_c_code_explicit_ode(model, opts) - elif acados_ocp.solver_options.integrator_type == 'IRK': - # implicit model -- generate C code - generate_c_code_implicit_ode(model, opts) - elif acados_ocp.solver_options.integrator_type == 'LIFTED_IRK': - generate_c_code_implicit_ode(model, opts) - elif acados_ocp.solver_options.integrator_type == 'GNSF': - generate_c_code_gnsf(model, opts) - elif acados_ocp.solver_options.integrator_type == 'DISCRETE': - generate_c_code_discrete_dynamics(model, opts) + check_casadi_version() + # TODO: remove dir gen from all the generate_c_* functions + if acados_ocp.model.dyn_ext_fun_type == 'casadi': + if acados_ocp.solver_options.integrator_type == 'ERK': + generate_c_code_explicit_ode(model, opts) + elif acados_ocp.solver_options.integrator_type == 'IRK': + generate_c_code_implicit_ode(model, opts) + elif acados_ocp.solver_options.integrator_type == 'LIFTED_IRK': + generate_c_code_implicit_ode(model, opts) + elif acados_ocp.solver_options.integrator_type == 'GNSF': + generate_c_code_gnsf(model, opts) + elif acados_ocp.solver_options.integrator_type == 'DISCRETE': + generate_c_code_discrete_dynamics(model, opts) + else: + raise Exception("ocp_generate_external_functions: unknown integrator type.") else: - raise Exception("ocp_generate_external_functions: unknown integrator type.") + target_location = os.path.join(code_export_dir, model_dir, model.dyn_generic_source) + shutil.copyfile(model.dyn_generic_source, target_location) if acados_ocp.dims.nphi > 0 or acados_ocp.dims.nh > 0: generate_c_code_constraint(model, model.name, False, opts) @@ -623,28 +690,24 @@ def ocp_generate_external_functions(acados_ocp, model): if acados_ocp.dims.nphi_e > 0 or acados_ocp.dims.nh_e > 0: generate_c_code_constraint(model, model.name, True, opts) - # dummy matrices - if not acados_ocp.cost.cost_type_0 == 'LINEAR_LS': - acados_ocp.cost.Vx_0 = np.zeros((acados_ocp.dims.ny_0, acados_ocp.dims.nx)) - acados_ocp.cost.Vu_0 = np.zeros((acados_ocp.dims.ny_0, acados_ocp.dims.nu)) - if not acados_ocp.cost.cost_type == 'LINEAR_LS': - acados_ocp.cost.Vx = np.zeros((acados_ocp.dims.ny, acados_ocp.dims.nx)) - acados_ocp.cost.Vu = np.zeros((acados_ocp.dims.ny, acados_ocp.dims.nu)) - if not acados_ocp.cost.cost_type_e == 'LINEAR_LS': - acados_ocp.cost.Vx_e = np.zeros((acados_ocp.dims.ny_e, acados_ocp.dims.nx)) - if acados_ocp.cost.cost_type_0 == 'NONLINEAR_LS': generate_c_code_nls_cost(model, model.name, 'initial', opts) + elif acados_ocp.cost.cost_type_0 == 'CONVEX_OVER_NONLINEAR': + generate_c_code_conl_cost(model, model.name, 'initial', opts) elif acados_ocp.cost.cost_type_0 == 'EXTERNAL': generate_c_code_external_cost(model, 'initial', opts) if acados_ocp.cost.cost_type == 'NONLINEAR_LS': generate_c_code_nls_cost(model, model.name, 'path', opts) + elif acados_ocp.cost.cost_type == 'CONVEX_OVER_NONLINEAR': + generate_c_code_conl_cost(model, model.name, 'path', opts) elif acados_ocp.cost.cost_type == 'EXTERNAL': generate_c_code_external_cost(model, 'path', opts) if acados_ocp.cost.cost_type_e == 'NONLINEAR_LS': generate_c_code_nls_cost(model, model.name, 'terminal', opts) + elif acados_ocp.cost.cost_type_e == 'CONVEX_OVER_NONLINEAR': + generate_c_code_conl_cost(model, model.name, 'terminal', opts) elif acados_ocp.cost.cost_type_e == 'EXTERNAL': generate_c_code_external_cost(model, 'terminal', opts) @@ -659,9 +722,8 @@ def ocp_get_default_cmake_builder() -> CMakeBuilder: return cmake_builder -def ocp_render_templates(acados_ocp, json_file, cmake_builder=None): - name = acados_ocp.model.name +def ocp_render_templates(acados_ocp: AcadosOcp, json_file, cmake_builder=None, simulink_opts=None): # setting up loader and environment json_path = os.path.abspath(json_file) @@ -669,132 +731,69 @@ def ocp_render_templates(acados_ocp, json_file, cmake_builder=None): if not os.path.exists(json_path): raise Exception(f'Path "{json_path}" not found!') - code_export_dir = acados_ocp.code_export_directory - template_dir = code_export_dir + # Render templates + template_list = __ocp_get_template_list(acados_ocp, cmake_builder=cmake_builder, simulink_opts=simulink_opts) + for tup in template_list: + if len(tup) > 2: + output_dir = tup[2] + else: + output_dir = acados_ocp.code_export_directory + render_template(tup[0], tup[1], output_dir, json_path) - ## Render templates - in_file = 'main.in.c' - out_file = f'main_{name}.c' - render_template(in_file, out_file, template_dir, json_path) + # Custom templates + acados_template_path = os.path.dirname(os.path.abspath(__file__)) + custom_template_glob = os.path.join(acados_template_path, 'custom_update_templates', '*') + for tup in acados_ocp.solver_options.custom_templates: + render_template(tup[0], tup[1], acados_ocp.code_export_directory, json_path, template_glob=custom_template_glob) - in_file = 'acados_solver.in.c' - out_file = f'acados_solver_{name}.c' - render_template(in_file, out_file, template_dir, json_path) + return - in_file = 'acados_solver.in.h' - out_file = f'acados_solver_{name}.h' - render_template(in_file, out_file, template_dir, json_path) - in_file = 'acados_solver.in.pxd' - out_file = f'acados_solver.pxd' - render_template(in_file, out_file, template_dir, json_path) +def __ocp_get_template_list(acados_ocp: AcadosOcp, cmake_builder=None, simulink_opts=None) -> list: + """ + returns a list of tuples in the form: + (input_filename, output_filname) + or + (input_filename, output_filname, output_directory) + """ + name = acados_ocp.model.name + code_export_directory = acados_ocp.code_export_directory + template_list = [] + + template_list.append(('main.in.c', f'main_{name}.c')) + template_list.append(('acados_solver.in.c', f'acados_solver_{name}.c')) + template_list.append(('acados_solver.in.h', f'acados_solver_{name}.h')) + template_list.append(('acados_solver.in.pxd', f'acados_solver.pxd')) if cmake_builder is not None: - in_file = 'CMakeLists.in.txt' - out_file = 'CMakeLists.txt' - render_template(in_file, out_file, template_dir, json_path) + template_list.append(('CMakeLists.in.txt', 'CMakeLists.txt')) else: - in_file = 'Makefile.in' - out_file = 'Makefile' - render_template(in_file, out_file, template_dir, json_path) + template_list.append(('Makefile.in', 'Makefile')) - in_file = 'acados_solver_sfun.in.c' - out_file = f'acados_solver_sfunction_{name}.c' - render_template(in_file, out_file, template_dir, json_path) - - in_file = 'make_sfun.in.m' - out_file = f'make_sfun_{name}.m' - render_template(in_file, out_file, template_dir, json_path) # sim - in_file = 'acados_sim_solver.in.c' - out_file = f'acados_sim_solver_{name}.c' - render_template(in_file, out_file, template_dir, json_path) + template_list.append(('acados_sim_solver.in.c', f'acados_sim_solver_{name}.c')) + template_list.append(('acados_sim_solver.in.h', f'acados_sim_solver_{name}.h')) + template_list.append(('main_sim.in.c', f'main_sim_{name}.c')) - in_file = 'acados_sim_solver.in.h' - out_file = f'acados_sim_solver_{name}.h' - render_template(in_file, out_file, template_dir, json_path) + # model + model_dir = os.path.join(code_export_directory, f'{name}_model') + template_list.append(('model.in.h', f'{name}_model.h', model_dir)) + # constraints + constraints_dir = os.path.join(code_export_directory, f'{name}_constraints') + template_list.append(('constraints.in.h', f'{name}_constraints.h', constraints_dir)) + # cost + cost_dir = os.path.join(code_export_directory, f'{name}_cost') + template_list.append(('cost.in.h', f'{name}_cost.h', cost_dir)) - in_file = 'main_sim.in.c' - out_file = f'main_sim_{name}.c' - render_template(in_file, out_file, template_dir, json_path) + # Simulink + if simulink_opts is not None: + template_file = os.path.join('matlab_templates', 'acados_solver_sfun.in.c') + template_list.append((template_file, f'acados_solver_sfunction_{name}.c')) + template_file = os.path.join('matlab_templates', 'acados_solver_sfun.in.c') + template_list.append((template_file, f'make_sfun_{name}.m')) - ## folder model - template_dir = os.path.join(code_export_dir, name + '_model') - in_file = 'model.in.h' - out_file = f'{name}_model.h' - render_template(in_file, out_file, template_dir, json_path) - - # constraints on convex over nonlinear function - if acados_ocp.constraints.constr_type == 'BGP' and acados_ocp.dims.nphi > 0: - # constraints on outer function - template_dir = os.path.join(code_export_dir, name + '_constraints') - in_file = 'phi_constraint.in.h' - out_file = f'{name}_phi_constraint.h' - render_template(in_file, out_file, template_dir, json_path) - - # terminal constraints on convex over nonlinear function - if acados_ocp.constraints.constr_type_e == 'BGP' and acados_ocp.dims.nphi_e > 0: - # terminal constraints on outer function - template_dir = os.path.join(code_export_dir, name + '_constraints') - in_file = 'phi_e_constraint.in.h' - out_file = f'{name}_phi_e_constraint.h' - render_template(in_file, out_file, template_dir, json_path) - - # nonlinear constraints - if acados_ocp.constraints.constr_type == 'BGH' and acados_ocp.dims.nh > 0: - template_dir = os.path.join(code_export_dir, name + '_constraints') - in_file = 'h_constraint.in.h' - out_file = f'{name}_h_constraint.h' - render_template(in_file, out_file, template_dir, json_path) - - # terminal nonlinear constraints - if acados_ocp.constraints.constr_type_e == 'BGH' and acados_ocp.dims.nh_e > 0: - template_dir = os.path.join(code_export_dir, name + '_constraints') - in_file = 'h_e_constraint.in.h' - out_file = f'{name}_h_e_constraint.h' - render_template(in_file, out_file, template_dir, json_path) - - # initial stage Nonlinear LS cost function - if acados_ocp.cost.cost_type_0 == 'NONLINEAR_LS': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'cost_y_0_fun.in.h' - out_file = f'{name}_cost_y_0_fun.h' - render_template(in_file, out_file, template_dir, json_path) - # external cost - terminal - elif acados_ocp.cost.cost_type_0 == 'EXTERNAL': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'external_cost_0.in.h' - out_file = f'{name}_external_cost_0.h' - render_template(in_file, out_file, template_dir, json_path) - - # path Nonlinear LS cost function - if acados_ocp.cost.cost_type == 'NONLINEAR_LS': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'cost_y_fun.in.h' - out_file = f'{name}_cost_y_fun.h' - render_template(in_file, out_file, template_dir, json_path) - - # terminal Nonlinear LS cost function - if acados_ocp.cost.cost_type_e == 'NONLINEAR_LS': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'cost_y_e_fun.in.h' - out_file = f'{name}_cost_y_e_fun.h' - render_template(in_file, out_file, template_dir, json_path) - - # external cost - if acados_ocp.cost.cost_type == 'EXTERNAL': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'external_cost.in.h' - out_file = f'{name}_external_cost.h' - render_template(in_file, out_file, template_dir, json_path) - - # external cost - terminal - if acados_ocp.cost.cost_type_e == 'EXTERNAL': - template_dir = os.path.join(code_export_dir, name + '_cost') - in_file = 'external_cost_e.in.h' - out_file = f'{name}_external_cost_e.h' - render_template(in_file, out_file, template_dir, json_path) + return template_list def remove_x0_elimination(acados_ocp): @@ -820,7 +819,7 @@ class AcadosOcpSolver: dlclose.argtypes = [c_void_p] @classmethod - def generate(cls, acados_ocp, json_file='acados_ocp_nlp.json', simulink_opts=None, cmake_builder: CMakeBuilder = None): + def generate(cls, acados_ocp: AcadosOcp, json_file='acados_ocp_nlp.json', simulink_opts=None, cmake_builder: CMakeBuilder = None): """ Generates the code for an acados OCP solver, given the description in acados_ocp. :param acados_ocp: type AcadosOcp - description of the OCP for acados @@ -834,15 +833,15 @@ class AcadosOcpSolver: model = acados_ocp.model acados_ocp.code_export_directory = os.path.abspath(acados_ocp.code_export_directory) - if simulink_opts is None: - simulink_opts = get_simulink_default_opts() - # make dims consistent make_ocp_dims_consistent(acados_ocp) # module dependent post processing if acados_ocp.solver_options.integrator_type == 'GNSF': - set_up_imported_gnsf_model(acados_ocp) + if 'gnsf_model' in acados_ocp.__dict__: + set_up_imported_gnsf_model(acados_ocp) + else: + detect_gnsf_structure(acados_ocp) if acados_ocp.solver_options.qp_solver == 'PARTIAL_CONDENSING_QPDUNES': remove_x0_elimination(acados_ocp) @@ -854,15 +853,23 @@ class AcadosOcpSolver: ocp_generate_external_functions(acados_ocp, model) # dump to json - ocp_formulation_json_dump(acados_ocp, simulink_opts, json_file) + acados_ocp.json_file = json_file + ocp_formulation_json_dump(acados_ocp, simulink_opts=simulink_opts, json_file=json_file) # render templates - ocp_render_templates(acados_ocp, json_file, cmake_builder=cmake_builder) - acados_ocp.json_file = json_file + ocp_render_templates(acados_ocp, json_file, cmake_builder=cmake_builder, simulink_opts=simulink_opts) + + # copy custom update function + if acados_ocp.solver_options.custom_update_filename != "" and acados_ocp.solver_options.custom_update_copy: + target_location = os.path.join(acados_ocp.code_export_directory, acados_ocp.solver_options.custom_update_filename) + shutil.copyfile(acados_ocp.solver_options.custom_update_filename, target_location) + if acados_ocp.solver_options.custom_update_header_filename != "" and acados_ocp.solver_options.custom_update_copy: + target_location = os.path.join(acados_ocp.code_export_directory, acados_ocp.solver_options.custom_update_header_filename) + shutil.copyfile(acados_ocp.solver_options.custom_update_header_filename, target_location) @classmethod - def build(cls, code_export_dir, with_cython=False, cmake_builder: CMakeBuilder = None): + def build(cls, code_export_dir, with_cython=False, cmake_builder: CMakeBuilder = None, verbose: bool = True): """ Builds the code for an acados OCP solver, that has been generated in code_export_dir :param code_export_dir: directory in which acados OCP solver has been generated, see generate() @@ -870,19 +877,36 @@ class AcadosOcpSolver: :param cmake_builder: type :py:class:`~acados_template.builders.CMakeBuilder` generate a `CMakeLists.txt` and use the `CMake` pipeline instead of a `Makefile` (`CMake` seems to be the better option in conjunction with `MS Visual Studio`); default: `None` + :param verbose: indicating if build command is printed """ code_export_dir = os.path.abspath(code_export_dir) - cwd=os.getcwd() + cwd = os.getcwd() os.chdir(code_export_dir) if with_cython: - os.system('make clean_ocp_cython') - os.system('make ocp_cython') + call( + ['make', 'clean_all'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) + call( + ['make', 'ocp_cython'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) else: if cmake_builder is not None: cmake_builder.exec(code_export_dir) else: - os.system('make clean_ocp_shared_lib') - os.system('make ocp_shared_lib') + call( + ['make', 'clean_ocp_shared_lib'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) + call( + ['make', 'ocp_shared_lib'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) os.chdir(cwd) @@ -910,7 +934,7 @@ class AcadosOcpSolver: acados_ocp_json['dims']['N']) - def __init__(self, acados_ocp, json_file='acados_ocp_nlp.json', simulink_opts=None, build=True, generate=True, cmake_builder: CMakeBuilder = None): + def __init__(self, acados_ocp: AcadosOcp, json_file='acados_ocp_nlp.json', simulink_opts=None, build=True, generate=True, cmake_builder: CMakeBuilder = None, verbose=True): self.solver_created = False if generate: @@ -927,15 +951,13 @@ class AcadosOcpSolver: code_export_directory = acados_ocp_json['code_export_directory'] if build: - self.build(code_export_directory, with_cython=False, cmake_builder=cmake_builder) + self.build(code_export_directory, with_cython=False, cmake_builder=cmake_builder, verbose=verbose) # prepare library loading lib_prefix = 'lib' - lib_ext = '.so' + lib_ext = get_lib_ext() if os.name == 'nt': lib_prefix = '' - lib_ext = '' - # ToDo: check for mac # Load acados library to avoid unloading the library. # This is necessary if acados was compiled with OpenMP, since the OpenMP threads can't be destroyed. @@ -970,16 +992,23 @@ class AcadosOcpSolver: assert getattr(self.shared_lib, f"{self.model_name}_acados_create")(self.capsule)==0 self.solver_created = True + self.acados_ocp = acados_ocp + # get pointers solver self.__get_pointers_solver() self.status = 0 + # gettable fields + self.__qp_dynamics_fields = ['A', 'B', 'b'] + self.__qp_cost_fields = ['Q', 'R', 'S', 'q', 'r'] + self.__qp_constraint_fields = ['C', 'D', 'lg', 'ug', 'lbx', 'ubx', 'lbu', 'ubu'] + def __get_pointers_solver(self): - """ - Private function to get the pointers for solver - """ + # """ + # Private function to get the pointers for solver + # """ # get pointers solver getattr(self.shared_lib, f"{self.model_name}_acados_get_nlp_opts").argtypes = [c_void_p] getattr(self.shared_lib, f"{self.model_name}_acados_get_nlp_opts").restype = c_void_p @@ -1010,6 +1039,25 @@ class AcadosOcpSolver: self.nlp_solver = getattr(self.shared_lib, f"{self.model_name}_acados_get_nlp_solver")(self.capsule) + + def solve_for_x0(self, x0_bar): + """ + Wrapper around `solve()` which sets initial state constraint, solves the OCP, and returns u0. + """ + self.set(0, "lbx", x0_bar) + self.set(0, "ubx", x0_bar) + + status = self.solve() + + if status == 2: + print("Warning: acados_ocp_solver reached maximum iterations.") + elif status != 0: + raise Exception(f'acados acados_ocp_solver returned status {status}') + + u0 = self.get(0, "u") + return u0 + + def solve(self): """ Solve the ocp with current input. @@ -1021,13 +1069,31 @@ class AcadosOcpSolver: return self.status - def reset(self): + def custom_update(self, data_: np.ndarray): + """ + A custom function that can be implemented by a user to be called between solver calls. + By default this does nothing. + The idea is to have a convenient wrapper to do complex updates of parameters and numerical data efficiently in C, + in a function that is compiled into the solver library and can be conveniently used in the Python environment. + """ + data = np.ascontiguousarray(data_, dtype=np.float64) + c_data = cast(data.ctypes.data, POINTER(c_double)) + data_len = len(data) + + getattr(self.shared_lib, f"{self.model_name}_acados_custom_update").argtypes = [c_void_p, POINTER(c_double), c_int] + getattr(self.shared_lib, f"{self.model_name}_acados_custom_update").restype = c_int + status = getattr(self.shared_lib, f"{self.model_name}_acados_custom_update")(self.capsule, c_data, data_len) + + return status + + + def reset(self, reset_qp_solver_mem=1): """ Sets current iterate to all zeros. """ - getattr(self.shared_lib, f"{self.model_name}_acados_reset").argtypes = [c_void_p] + getattr(self.shared_lib, f"{self.model_name}_acados_reset").argtypes = [c_void_p, c_int] getattr(self.shared_lib, f"{self.model_name}_acados_reset").restype = c_int - getattr(self.shared_lib, f"{self.model_name}_acados_reset")(self.capsule) + getattr(self.shared_lib, f"{self.model_name}_acados_reset")(self.capsule, reset_qp_solver_mem) return @@ -1175,18 +1241,17 @@ class AcadosOcpSolver: field = field_ if (field_ not in all_fields): - raise Exception('AcadosOcpSolver.get(): {} is an invalid argument.\ - \n Possible values are {}. Exiting.'.format(field_, all_fields)) + raise Exception(f'AcadosOcpSolver.get(stage={stage_}, field={field_}): \'{field_}\' is an invalid argument.\ + \n Possible values are {all_fields}.') if not isinstance(stage_, int): - raise Exception('AcadosOcpSolver.get(): stage index must be Integer.') + raise Exception(f'AcadosOcpSolver.get(stage={stage_}, field={field_}): stage index must be an integer, got type {type(stage_)}.') if stage_ < 0 or stage_ > self.N: - raise Exception('AcadosOcpSolver.get(): stage index must be in [0, N], got: {}.'.format(stage_)) + raise Exception(f'AcadosOcpSolver.get(stage={stage_}, field={field_}): stage index must be in [0, {self.N}], got: {stage_}.') if stage_ == self.N and field_ == 'pi': - raise Exception('AcadosOcpSolver.get(): field {} does not exist at final stage {}.'\ - .format(field_, stage_)) + raise Exception(f'AcadosOcpSolver.get(stage={stage_}, field={field_}): field \'{field_}\' does not exist at final stage {stage_}.') if field_ in sens_fields: field = field_.replace('sens_', '') @@ -1265,15 +1330,15 @@ class AcadosOcpSolver: return - def store_iterate(self, filename='', overwrite=False): + def store_iterate(self, filename: str = '', overwrite=False): """ Stores the current iterate of the ocp solver in a json file. - :param filename: if not set, use model_name + timestamp + '.json' + :param filename: if not set, use f'{self.model_name}_iterate.json' :param overwrite: if false and filename exists add timestamp to filename """ if filename == '': - filename += self.model_name + '_' + 'iterate' + '.json' + filename = f'{self.model_name}_iterate.json' if not overwrite: # append timestamp @@ -1284,23 +1349,70 @@ class AcadosOcpSolver: # get iterate: solution = dict() + lN = len(str(self.N+1)) for i in range(self.N+1): - solution['x_'+str(i)] = self.get(i,'x') - solution['u_'+str(i)] = self.get(i,'u') - solution['z_'+str(i)] = self.get(i,'z') - solution['lam_'+str(i)] = self.get(i,'lam') - solution['t_'+str(i)] = self.get(i, 't') - solution['sl_'+str(i)] = self.get(i, 'sl') - solution['su_'+str(i)] = self.get(i, 'su') - for i in range(self.N): - solution['pi_'+str(i)] = self.get(i,'pi') + i_string = f'{i:0{lN}d}' + solution['x_'+i_string] = self.get(i,'x') + solution['u_'+i_string] = self.get(i,'u') + solution['z_'+i_string] = self.get(i,'z') + solution['lam_'+i_string] = self.get(i,'lam') + solution['t_'+i_string] = self.get(i, 't') + solution['sl_'+i_string] = self.get(i, 'sl') + solution['su_'+i_string] = self.get(i, 'su') + if i < self.N: + solution['pi_'+i_string] = self.get(i,'pi') + + for k in list(solution.keys()): + if len(solution[k]) == 0: + del solution[k] # save with open(filename, 'w') as f: - json.dump(solution, f, default=np_array_to_list, indent=4, sort_keys=True) + json.dump(solution, f, default=make_object_json_dumpable, indent=4, sort_keys=True) print("stored current iterate in ", os.path.join(os.getcwd(), filename)) + + def dump_last_qp_to_json(self, filename: str = '', overwrite=False): + """ + Dumps the latest QP data into a json file + + :param filename: if not set, use model_name + timestamp + '.json' + :param overwrite: if false and filename exists add timestamp to filename + """ + if filename == '': + filename = f'{self.model_name}_QP.json' + + if not overwrite: + # append timestamp + if os.path.isfile(filename): + filename = filename[:-5] + filename += datetime.utcnow().strftime('%Y-%m-%d-%H:%M:%S.%f') + '.json' + + # get QP data: + qp_data = dict() + + lN = len(str(self.N+1)) + for field in self.__qp_dynamics_fields: + for i in range(self.N): + qp_data[f'{field}_{i:0{lN}d}'] = self.get_from_qp_in(i,field) + + for field in self.__qp_constraint_fields + self.__qp_cost_fields: + for i in range(self.N+1): + qp_data[f'{field}_{i:0{lN}d}'] = self.get_from_qp_in(i,field) + + # remove empty fields + for k in list(qp_data.keys()): + if len(qp_data[k]) == 0: + del qp_data[k] + + # save + with open(filename, 'w') as f: + json.dump(qp_data, f, default=make_object_json_dumpable, indent=4, sort_keys=True) + print("stored qp from solver memory in ", os.path.join(os.getcwd(), filename)) + + + def load_iterate(self, filename): """ Loads the iterate stored in json file with filename into the ocp solver. @@ -1412,7 +1524,7 @@ class AcadosOcpSolver: return self.get_residuals() else: - raise Exception(f'AcadosOcpSolver.get_stats(): {field} is not a valid argument.' + raise Exception(f'AcadosOcpSolver.get_stats(): \'{field}\' is not a valid argument.' + f'\n Possible values are {fields}.') @@ -1440,6 +1552,12 @@ class AcadosOcpSolver: def get_residuals(self, recompute=False): """ Returns an array of the form [res_stat, res_eq, res_ineq, res_comp]. + This residual has to be computed for SQP_RTI solver, since it is not available by default. + + - res_stat: stationarity residual + - res_eq: residual wrt equality constraints (dynamics) + - res_ineq: residual wrt inequality constraints (constraints) + - res_comp: residual wrt complementarity conditions """ # compute residuals if RTI if self.solver_options['nlp_solver_type'] == 'SQP_RTI' or recompute: @@ -1499,24 +1617,22 @@ class AcadosOcpSolver: value_ = np.array([value_]) value_ = value_.astype(float) - field = field_ - field = field.encode('utf-8') + field = field_.encode('utf-8') stage = c_int(stage_) # treat parameters separately if field_ == 'p': - getattr(self.shared_lib, f"{self.model_name}_acados_update_params").argtypes = [c_void_p, c_int, POINTER(c_double)] + getattr(self.shared_lib, f"{self.model_name}_acados_update_params").argtypes = [c_void_p, c_int, POINTER(c_double), c_int] getattr(self.shared_lib, f"{self.model_name}_acados_update_params").restype = c_int value_data = cast(value_.ctypes.data, POINTER(c_double)) assert getattr(self.shared_lib, f"{self.model_name}_acados_update_params")(self.capsule, stage, value_data, value_.shape[0])==0 else: - if field_ not in constraints_fields + cost_fields + out_fields: - raise Exception("AcadosOcpSolver.set(): {} is not a valid argument.\ - \nPossible values are {}. Exiting.".format(field, \ - constraints_fields + cost_fields + out_fields + ['p'])) + if field_ not in constraints_fields + cost_fields + out_fields + mem_fields: + raise Exception(f"AcadosOcpSolver.set(): '{field}' is not a valid argument.\n" + f" Possible values are {constraints_fields + cost_fields + out_fields + mem_fields + ['p']}.") self.shared_lib.ocp_nlp_dims_get_from_attr.argtypes = \ [c_void_p, c_void_p, c_void_p, c_int, c_char_p] @@ -1526,8 +1642,8 @@ class AcadosOcpSolver: self.nlp_dims, self.nlp_out, stage_, field) if value_.shape[0] != dims: - msg = 'AcadosOcpSolver.set(): mismatching dimension for field "{}" '.format(field_) - msg += 'with dimension {} (you have {})'.format(dims, value_.shape[0]) + msg = f'AcadosOcpSolver.set(): mismatching dimension for field "{field_}" ' + msg += f'with dimension {dims} (you have {value_.shape[0]})' raise Exception(msg) value_data = cast(value_.ctypes.data, POINTER(c_double)) @@ -1553,6 +1669,13 @@ class AcadosOcpSolver: [c_void_p, c_void_p, c_int, c_char_p, c_void_p] self.shared_lib.ocp_nlp_set(self.nlp_config, \ self.nlp_solver, stage, field, value_data_p) + # also set z_guess, when setting z. + if field_ == 'z': + field = 'z_guess'.encode('utf-8') + self.shared_lib.ocp_nlp_set.argtypes = \ + [c_void_p, c_void_p, c_int, c_char_p, c_void_p] + self.shared_lib.ocp_nlp_set(self.nlp_config, \ + self.nlp_solver, stage, field, value_data_p) return @@ -1561,7 +1684,7 @@ class AcadosOcpSolver: Set numerical data in the cost module of the solver. :param stage: integer corresponding to shooting node - :param field: string, e.g. 'yref', 'W', 'ext_cost_num_hess' + :param field: string, e.g. 'yref', 'W', 'ext_cost_num_hess', 'zl', 'zu', 'Zl', 'Zu' :param value: of appropriate size """ # cast value_ to avoid conversion issues @@ -1595,7 +1718,7 @@ class AcadosOcpSolver: raise Exception("Ambiguity in API detected.\n" "Are you making an acados model from scrach? Add api='new' to cost_set and carry on.\n" "Are you seeing this error suddenly in previously running code? Read on.\n" - " You are relying on a now-fixed bug in cost_set for field '{}'.\n".format(field_) + + f" You are relying on a now-fixed bug in cost_set for field '{field_}'.\n" + " acados_template now correctly passes on any matrices to acados in column major format.\n" + " Two options to fix this error: \n" + " * Add api='old' to cost_set to restore old incorrect behaviour\n" + @@ -1663,7 +1786,7 @@ class AcadosOcpSolver: raise Exception("Ambiguity in API detected.\n" "Are you making an acados model from scrach? Add api='new' to constraints_set and carry on.\n" "Are you seeing this error suddenly in previously running code? Read on.\n" - " You are relying on a now-fixed bug in constraints_set for field '{}'.\n".format(field_) + + f" You are relying on a now-fixed bug in constraints_set for field '{field}'.\n" + " acados_template now correctly passes on any matrices to acados in column major format.\n" + " Two options to fix this error: \n" + " * Add api='old' to constraints_set to restore old incorrect behaviour\n" + @@ -1676,7 +1799,7 @@ class AcadosOcpSolver: # Get elements in column major order value_ = np.ravel(value_, order='F') else: - raise Exception("Unknown api: '{}'".format(api)) + raise Exception(f"Unknown api: '{api}'") if value_shape != tuple(dims): raise Exception(f'AcadosOcpSolver.constraints_set(): mismatching dimension' + @@ -1693,27 +1816,35 @@ class AcadosOcpSolver: return - def dynamics_get(self, stage_, field_): + def get_from_qp_in(self, stage_: int, field_: str): """ - Get numerical data from the dynamics module of the solver: + Get numerical data from the current QP. :param stage: integer corresponding to shooting node - :param field: string, e.g. 'A' + :param field: string in ['A', 'B', 'b', 'Q', 'R', 'S', 'q', 'r', 'C', 'D', 'lg', 'ug', 'lbx', 'ubx', 'lbu', 'ubu'] """ + # idx* should be added too.. + if not isinstance(stage_, int): + raise TypeError("stage should be int") + if stage_ > self.N: + raise Exception("stage should be <= self.N") + if field_ in self.__qp_dynamics_fields and stage_ >= self.N: + raise ValueError(f"dynamics field {field_} not available at terminal stage") + if field_ not in self.__qp_dynamics_fields + self.__qp_cost_fields + self.__qp_constraint_fields: + raise Exception(f"field {field_} not supported.") - field = field_ - field = field.encode('utf-8') + field = field_.encode('utf-8') stage = c_int(stage_) # get dims - self.shared_lib.ocp_nlp_dynamics_dims_get_from_attr.argtypes = \ + self.shared_lib.ocp_nlp_qp_dims_get_from_attr.argtypes = \ [c_void_p, c_void_p, c_void_p, c_int, c_char_p, POINTER(c_int)] - self.shared_lib.ocp_nlp_dynamics_dims_get_from_attr.restype = c_int + self.shared_lib.ocp_nlp_qp_dims_get_from_attr.restype = c_int dims = np.ascontiguousarray(np.zeros((2,)), dtype=np.intc) dims_data = cast(dims.ctypes.data, POINTER(c_int)) - self.shared_lib.ocp_nlp_dynamics_dims_get_from_attr(self.nlp_config, \ + self.shared_lib.ocp_nlp_qp_dims_get_from_attr(self.nlp_config, \ self.nlp_dims, self.nlp_out, stage_, field, dims_data) # create output data @@ -1748,32 +1879,34 @@ class AcadosOcpSolver: - qp_mu0: for HPIPM QP solvers: initial value for complementarity slackness - warm_start_first_qp: indicates if first QP in SQP is warm_started """ - int_fields = ['print_level', 'rti_phase', 'initialize_t_slacks', 'qp_warm_start', 'line_search_use_sufficient_descent', 'full_step_dual', 'globalization_use_SOC', 'warm_start_first_qp'] - double_fields = ['step_length', 'tol_eq', 'tol_stat', 'tol_ineq', 'tol_comp', 'alpha_min', 'alpha_reduction', 'eps_sufficient_descent', - 'qp_tol_stat', 'qp_tol_eq', 'qp_tol_ineq', 'qp_tol_comp', 'qp_tau_min', 'qp_mu0'] + int_fields = ['print_level', 'rti_phase', 'initialize_t_slacks', 'qp_warm_start', + 'line_search_use_sufficient_descent', 'full_step_dual', 'globalization_use_SOC', 'warm_start_first_qp'] + double_fields = ['step_length', 'tol_eq', 'tol_stat', 'tol_ineq', 'tol_comp', 'alpha_min', 'alpha_reduction', + 'eps_sufficient_descent', 'qp_tol_stat', 'qp_tol_eq', 'qp_tol_ineq', 'qp_tol_comp', 'qp_tau_min', 'qp_mu0'] string_fields = ['globalization'] # check field availability and type if field_ in int_fields: if not isinstance(value_, int): - raise Exception('solver option {} must be of type int. You have {}.'.format(field_, type(value_))) + raise Exception(f'solver option \'{field_}\' must be of type int. You have {type(value_)}.') else: value_ctypes = c_int(value_) elif field_ in double_fields: if not isinstance(value_, float): - raise Exception('solver option {} must be of type float. You have {}.'.format(field_, type(value_))) + raise Exception(f'solver option \'{field_}\' must be of type float. You have {type(value_)}.') else: value_ctypes = c_double(value_) elif field_ in string_fields: if not isinstance(value_, str): - raise Exception('solver option {} must be of type str. You have {}.'.format(field_, type(value_))) + raise Exception(f'solver option \'{field_}\' must be of type str. You have {type(value_)}.') else: value_ctypes = value_.encode('utf-8') else: - raise Exception('AcadosOcpSolver.options_set() does not support field {}.'\ - '\n Possible values are {}.'.format(field_, ', '.join(int_fields + double_fields + string_fields))) + fields = ', '.join(int_fields + double_fields + string_fields) + raise Exception(f'AcadosOcpSolver.options_set() does not support field \'{field_}\'.\n'\ + f' Possible values are {fields}.') if field_ == 'rti_phase': @@ -1802,6 +1935,44 @@ class AcadosOcpSolver: return + def set_params_sparse(self, stage_, idx_values_, param_values_): + """ + set parameters of the solvers external function partially: + Pseudo: solver.param[idx_values_] = param_values_; + Parameters: + :param stage_: integer corresponding to shooting node + :param idx_values_: 0 based np array (or iterable) of integers: indices of parameter to be set + :param param_values_: new parameter values as numpy array + """ + + # if not isinstance(idx_values_, np.ndarray) or not issubclass(type(idx_values_[0]), np.integer): + # raise Exception('idx_values_ must be np.array of integers.') + + if not isinstance(param_values_, np.ndarray): + raise Exception('param_values_ must be np.array.') + elif np.float64 != param_values_.dtype: + raise TypeError('param_values_ must be np.array of float64.') + + if param_values_.shape[0] != len(idx_values_): + raise Exception(f'param_values_ and idx_values_ must be of the same size.' + + f' Got sizes idx {param_values_.shape[0]}, param_values {len(idx_values_)}.') + + if any(idx_values_ >= self.acados_ocp.dims.np): + raise Exception(f'idx_values_ contains value >= np = {self.acados_ocp.dims.np}') + + stage = c_int(stage_) + n_update = c_int(len(param_values_)) + + param_data = cast(param_values_.ctypes.data, POINTER(c_double)) + c_idx_values = np.ascontiguousarray(idx_values_, dtype=np.intc) + idx_data = cast(c_idx_values.ctypes.data, POINTER(c_int)) + + getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse").argtypes = \ + [c_void_p, c_int, POINTER(c_int), POINTER(c_double), c_int] + getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse").restype = c_int + getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse") \ + (self.capsule, stage, idx_data, param_data, n_update) + def __del__(self): if self.solver_created: getattr(self.shared_lib, f"{self.model_name}_acados_free").argtypes = [c_void_p] @@ -1815,4 +1986,6 @@ class AcadosOcpSolver: try: self.dlclose(self.shared_lib._handle) except: + print(f"WARNING: acados Python interface could not close shared_lib handle of AcadosOcpSolver {self.model_name}.\n", + "Attempting to create a new one with the same name will likely result in the old one being used!") pass diff --git a/third_party/acados/acados_template/acados_ocp_solver_pyx.pyx b/third_party/acados/acados_template/acados_ocp_solver_pyx.pyx index fe7fa8425a..acd7f02d0a 100644 --- a/third_party/acados/acados_template/acados_ocp_solver_pyx.pyx +++ b/third_party/acados/acados_template/acados_ocp_solver_pyx.pyx @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -63,7 +60,6 @@ cdef class AcadosOcpSolverCython: cdef acados_solver_common.ocp_nlp_in *nlp_in cdef acados_solver_common.ocp_nlp_solver *nlp_solver - cdef int status cdef bint solver_created cdef str model_name @@ -88,7 +84,6 @@ cdef class AcadosOcpSolverCython: # get pointers solver self.__get_pointers_solver() - self.status = 0 def __get_pointers_solver(self): @@ -105,6 +100,24 @@ cdef class AcadosOcpSolverCython: self.nlp_solver = acados_solver.acados_get_nlp_solver(self.capsule) + def solve_for_x0(self, x0_bar): + """ + Wrapper around `solve()` which sets initial state constraint, solves the OCP, and returns u0. + """ + self.set(0, "lbx", x0_bar) + self.set(0, "ubx", x0_bar) + + status = self.solve() + + if status == 2: + print("Warning: acados_ocp_solver reached maximum iterations.") + elif status != 0: + raise Exception(f'acados acados_ocp_solver returned status {status}') + + u0 = self.get(0, "u") + return u0 + + def solve(self): """ Solve the ocp with current input. @@ -112,11 +125,24 @@ cdef class AcadosOcpSolverCython: return acados_solver.acados_solve(self.capsule) - def reset(self): + def reset(self, reset_qp_solver_mem=1): """ Sets current iterate to all zeros. """ - return acados_solver.acados_reset(self.capsule) + return acados_solver.acados_reset(self.capsule, reset_qp_solver_mem) + + + def custom_update(self, data_): + """ + A custom function that can be implemented by a user to be called between solver calls. + By default this does nothing. + The idea is to have a convenient wrapper to do complex updates of parameters and numerical data efficiently in C, + in a function that is compiled into the solver library and can be conveniently used in the Python environment. + """ + data_len = len(data_) + cdef cnp.ndarray[cnp.float64_t, ndim=1] data = np.ascontiguousarray(data_, dtype=np.float64) + + return acados_solver.acados_custom_update(self.capsule, data.data, data_len) def set_new_time_steps(self, new_time_steps): @@ -253,7 +279,7 @@ cdef class AcadosOcpSolverCython: if field_ not in out_fields: raise Exception('AcadosOcpSolverCython.get(): {} is an invalid argument.\ - \n Possible values are {}. Exiting.'.format(field_, out_fields)) + \n Possible values are {}.'.format(field_, out_fields)) if stage < 0 or stage > self.N: raise Exception('AcadosOcpSolverCython.get(): stage index must be in [0, N], got: {}.'.format(self.N)) @@ -310,16 +336,22 @@ cdef class AcadosOcpSolverCython: # get iterate: solution = dict() + lN = len(str(self.N+1)) for i in range(self.N+1): - solution['x_'+str(i)] = self.get(i,'x') - solution['u_'+str(i)] = self.get(i,'u') - solution['z_'+str(i)] = self.get(i,'z') - solution['lam_'+str(i)] = self.get(i,'lam') - solution['t_'+str(i)] = self.get(i, 't') - solution['sl_'+str(i)] = self.get(i, 'sl') - solution['su_'+str(i)] = self.get(i, 'su') - for i in range(self.N): - solution['pi_'+str(i)] = self.get(i,'pi') + i_string = f'{i:0{lN}d}' + solution['x_'+i_string] = self.get(i,'x') + solution['u_'+i_string] = self.get(i,'u') + solution['z_'+i_string] = self.get(i,'z') + solution['lam_'+i_string] = self.get(i,'lam') + solution['t_'+i_string] = self.get(i, 't') + solution['sl_'+i_string] = self.get(i, 'sl') + solution['su_'+i_string] = self.get(i, 'su') + if i < self.N: + solution['pi_'+i_string] = self.get(i,'pi') + + for k in list(solution.keys()): + if len(solution[k]) == 0: + del solution[k] # save with open(filename, 'w') as f: @@ -508,6 +540,8 @@ cdef class AcadosOcpSolverCython: sl: slack variables of soft lower inequality constraints \n su: slack variables of soft upper inequality constraints \n """ + if not isinstance(value_, np.ndarray): + raise Exception(f"set: value must be numpy array, got {type(value_)}.") cost_fields = ['y_ref', 'yref'] constraints_fields = ['lbx', 'ubx', 'lbu', 'ubu'] out_fields = ['x', 'u', 'pi', 'lam', 't', 'z', 'sl', 'su'] @@ -523,7 +557,7 @@ cdef class AcadosOcpSolverCython: else: if field_ not in constraints_fields + cost_fields + out_fields: raise Exception("AcadosOcpSolverCython.set(): {} is not a valid argument.\ - \nPossible values are {}. Exiting.".format(field, \ + \nPossible values are {}.".format(field, \ constraints_fields + cost_fields + out_fields + ['p'])) dims = acados_solver_common.ocp_nlp_dims_get_from_attr(self.nlp_config, @@ -547,6 +581,11 @@ cdef class AcadosOcpSolverCython: acados_solver_common.ocp_nlp_set(self.nlp_config, \ self.nlp_solver, stage, field, value.data) + if field_ == 'z': + field = 'z_guess'.encode('utf-8') + acados_solver_common.ocp_nlp_set(self.nlp_config, \ + self.nlp_solver, stage, field, value.data) + return def cost_set(self, int stage, str field_, value_): """ @@ -556,6 +595,8 @@ cdef class AcadosOcpSolverCython: :param field: string, e.g. 'yref', 'W', 'ext_cost_num_hess' :param value: of appropriate size """ + if not isinstance(value_, np.ndarray): + raise Exception(f"cost_set: value must be numpy array, got {type(value_)}.") field = field_.encode('utf-8') cdef int dims[2] @@ -589,6 +630,9 @@ cdef class AcadosOcpSolverCython: :param field: string in ['lbx', 'ubx', 'lbu', 'ubu', 'lg', 'ug', 'lh', 'uh', 'uphi', 'C', 'D'] :param value: of appropriate size """ + if not isinstance(value_, np.ndarray): + raise Exception(f"constraints_set: value must be numpy array, got {type(value_)}.") + field = field_.encode('utf-8') cdef int dims[2] @@ -606,7 +650,7 @@ cdef class AcadosOcpSolverCython: # Get elements in column major order value = np.asfortranarray(value_) - if value_shape[0] != dims[0] or value_shape[1] != dims[1]: + if value_shape != tuple(dims): raise Exception(f'AcadosOcpSolverCython.constraints_set(): mismatching dimension' + f' for field "{field_}" at stage {stage} with dimension {tuple(dims)} (you have {value_shape})') @@ -616,7 +660,7 @@ cdef class AcadosOcpSolverCython: return - def dynamics_get(self, int stage, str field_): + def get_from_qp_in(self, int stage, str field_): """ Get numerical data from the dynamics module of the solver: @@ -627,7 +671,7 @@ cdef class AcadosOcpSolverCython: # get dims cdef int[2] dims - acados_solver_common.ocp_nlp_dynamics_dims_get_from_attr(self.nlp_config, self.nlp_dims, self.nlp_out, stage, field, &dims[0]) + acados_solver_common.ocp_nlp_qp_dims_get_from_attr(self.nlp_config, self.nlp_dims, self.nlp_out, stage, field, &dims[0]) # create output data cdef cnp.ndarray[cnp.float64_t, ndim=2] out = np.zeros((dims[0], dims[1]), order='F') @@ -701,6 +745,50 @@ cdef class AcadosOcpSolverCython: '\n Possible values are {}.'.format(field_, ', '.join(int_fields + double_fields + string_fields))) + def set_params_sparse(self, int stage, idx_values_, param_values_): + """ + set parameters of the solvers external function partially: + Pseudo: solver.param[idx_values_] = param_values_; + Parameters: + :param stage_: integer corresponding to shooting node + :param idx_values_: 0 based integer array corresponding to parameter indices to be set + :param param_values_: new parameter values as numpy array + """ + + if not isinstance(param_values_, np.ndarray): + raise Exception('param_values_ must be np.array.') + + if param_values_.shape[0] != len(idx_values_): + raise Exception(f'param_values_ and idx_values_ must be of the same size.' + + f' Got sizes idx {param_values_.shape[0]}, param_values {len(idx_values_)}.') + + # n_update = c_int(len(param_values_)) + + # param_data = cast(param_values_.ctypes.data, POINTER(c_double)) + # c_idx_values = np.ascontiguousarray(idx_values_, dtype=np.intc) + # idx_data = cast(c_idx_values.ctypes.data, POINTER(c_int)) + + # getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse").argtypes = \ + # [c_void_p, c_int, POINTER(c_int), POINTER(c_double), c_int] + # getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse").restype = c_int + # getattr(self.shared_lib, f"{self.model_name}_acados_update_params_sparse") \ + # (self.capsule, stage, idx_data, param_data, n_update) + + cdef cnp.ndarray[cnp.float64_t, ndim=1] value = np.ascontiguousarray(param_values_, dtype=np.float64) + # cdef cnp.ndarray[cnp.intc, ndim=1] idx = np.ascontiguousarray(idx_values_, dtype=np.intc) + + # NOTE: this does throw an error somehow: + # ValueError: Buffer dtype mismatch, expected 'int object' but got 'int' + # cdef cnp.ndarray[cnp.int, ndim=1] idx = np.ascontiguousarray(idx_values_, dtype=np.intc) + + cdef cnp.ndarray[cnp.int32_t, ndim=1] idx = np.ascontiguousarray(idx_values_, dtype=np.int32) + cdef int n_update = value.shape[0] + # print(f"in set_params_sparse Cython n_update {n_update}") + + assert acados_solver.acados_update_params_sparse(self.capsule, stage, idx.data, value.data, n_update) == 0 + return + + def __del__(self): if self.solver_created: acados_solver.acados_free(self.capsule) diff --git a/third_party/acados/acados_template/acados_sim.py b/third_party/acados/acados_template/acados_sim.py index 93d5f298db..c0d6937a49 100644 --- a/third_party/acados/acados_template/acados_sim.py +++ b/third_party/acados/acados_template/acados_sim.py @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -33,10 +30,9 @@ # import numpy as np -import casadi as ca import os from .acados_model import AcadosModel -from .utils import get_acados_path +from .utils import get_acados_path, get_lib_ext class AcadosSimDims: """ @@ -73,28 +69,28 @@ class AcadosSimDims: if isinstance(nx, int) and nx > 0: self.__nx = nx else: - raise Exception('Invalid nx value, expected positive integer. Exiting.') + raise Exception('Invalid nx value, expected positive integer.') @nz.setter def nz(self, nz): if isinstance(nz, int) and nz > -1: self.__nz = nz else: - raise Exception('Invalid nz value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nz value, expected nonnegative integer.') @nu.setter def nu(self, nu): if isinstance(nu, int) and nu > -1: self.__nu = nu else: - raise Exception('Invalid nu value, expected nonnegative integer. Exiting.') + raise Exception('Invalid nu value, expected nonnegative integer.') @np.setter def np(self, np): if isinstance(np, int) and np > -1: self.__np = np else: - raise Exception('Invalid np value, expected nonnegative integer. Exiting.') + raise Exception('Invalid np value, expected nonnegative integer.') def set(self, attr, value): setattr(self, attr, value) @@ -112,13 +108,16 @@ class AcadosSimOpts: self.__sim_method_num_stages = 1 self.__sim_method_num_steps = 1 self.__sim_method_newton_iter = 3 + # doubles + self.__sim_method_newton_tol = 0.0 # bools self.__sens_forw = True self.__sens_adj = False self.__sens_algebraic = False self.__sens_hess = False - self.__output_z = False + self.__output_z = True self.__sim_method_jac_reuse = 0 + self.__ext_fun_compile_flags = '-O2' @property def integrator_type(self): @@ -140,6 +139,15 @@ class AcadosSimOpts: """Number of Newton iterations in simulation method. Default: 3""" return self.__sim_method_newton_iter + @property + def newton_tol(self): + """ + Tolerance for Newton system solved in implicit integrator (IRK, GNSF). + 0.0 means this is not used and exactly newton_iter iterations are carried out. + Default: 0.0 + """ + return self.__sim_method_newton_tol + @property def sens_forw(self): """Boolean determining if forward sensitivities are computed. Default: True""" @@ -162,7 +170,7 @@ class AcadosSimOpts: @property def output_z(self): - """Boolean determining if values for algebraic variables (corresponding to start of simulation interval) are computed. Default: False""" + """Boolean determining if values for algebraic variables (corresponding to start of simulation interval) are computed. Default: True""" return self.__output_z @property @@ -184,6 +192,21 @@ class AcadosSimOpts: """ return self.__collocation_type + @property + def ext_fun_compile_flags(self): + """ + String with compiler flags for external function compilation. + Default: '-O2'. + """ + return self.__ext_fun_compile_flags + + @ext_fun_compile_flags.setter + def ext_fun_compile_flags(self, ext_fun_compile_flags): + if isinstance(ext_fun_compile_flags, str): + self.__ext_fun_compile_flags = ext_fun_compile_flags + else: + raise Exception('Invalid ext_fun_compile_flags, expected a string.\n') + @integrator_type.setter def integrator_type(self, integrator_type): integrator_types = ('ERK', 'IRK', 'GNSF') @@ -191,7 +214,7 @@ class AcadosSimOpts: self.__integrator_type = integrator_type else: raise Exception('Invalid integrator_type value. Possible values are:\n\n' \ - + ',\n'.join(integrator_types) + '.\n\nYou have: ' + integrator_type + '.\n\nExiting.') + + ',\n'.join(integrator_types) + '.\n\nYou have: ' + integrator_type + '.\n\n') @collocation_type.setter def collocation_type(self, collocation_type): @@ -200,7 +223,7 @@ class AcadosSimOpts: self.__collocation_type = collocation_type else: raise Exception('Invalid collocation_type value. Possible values are:\n\n' \ - + ',\n'.join(collocation_types) + '.\n\nYou have: ' + collocation_type + '.\n\nExiting.') + + ',\n'.join(collocation_types) + '.\n\nYou have: ' + collocation_type + '.\n\n') @T.setter def T(self, T): @@ -227,6 +250,13 @@ class AcadosSimOpts: else: raise Exception('Invalid newton_iter value. newton_iter must be an integer.') + @newton_tol.setter + def newton_tol(self, newton_tol): + if isinstance(newton_tol, float): + self.__sim_method_newton_tol = newton_tol + else: + raise Exception('Invalid newton_tol value. newton_tol must be an float.') + @sens_forw.setter def sens_forw(self, sens_forw): if sens_forw in (True, False): @@ -280,6 +310,7 @@ class AcadosSim: - :py:attr:`solver_options` of type :py:class:`acados_template.acados_sim.AcadosSimOpts` - :py:attr:`acados_include_path` (set automatically) + - :py:attr:`shared_lib_ext` (set automatically) - :py:attr:`acados_lib_path` (set automatically) - :py:attr:`parameter_values` - used to initialize the parameters (can be changed) @@ -301,9 +332,14 @@ class AcadosSim: self.code_export_directory = 'c_generated_code' """Path to where code will be exported. Default: `c_generated_code`.""" + self.shared_lib_ext = get_lib_ext() + + # get cython paths + from sysconfig import get_paths + self.cython_include_dirs = [np.get_include(), get_paths()['include']] - self.cython_include_dirs = '' self.__parameter_values = np.array([]) + self.__problem_class = 'SIM' @property def parameter_values(self): diff --git a/third_party/acados/acados_template/acados_sim_layout.json b/third_party/acados/acados_template/acados_sim_layout.json index 25b149613b..e3ca4b575b 100644 --- a/third_party/acados/acados_template/acados_sim_layout.json +++ b/third_party/acados/acados_template/acados_sim_layout.json @@ -42,6 +42,12 @@ ], "sim_method_newton_iter": [ "int" + ], + "sim_method_newton_tol": [ + "float" + ], + "ext_fun_compile_flags": [ + "str" ] } } diff --git a/third_party/acados/acados_template/acados_sim_solver.py b/third_party/acados/acados_template/acados_sim_solver.py index 3588dd38cd..612f439eaf 100644 --- a/third_party/acados/acados_template/acados_sim_solver.py +++ b/third_party/acados/acados_template/acados_sim_solver.py @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -32,56 +29,58 @@ # POSSIBILITY OF SUCH DAMAGE.; # -import sys, os, json +import sys +import os +import json +import importlib import numpy as np -from ctypes import * +from subprocess import DEVNULL, call, STDOUT + +from ctypes import POINTER, cast, CDLL, c_void_p, c_char_p, c_double, c_int, c_bool, byref from copy import deepcopy -from .generate_c_code_explicit_ode import generate_c_code_explicit_ode -from .generate_c_code_implicit_ode import generate_c_code_implicit_ode -from .generate_c_code_gnsf import generate_c_code_gnsf +from .casadi_function_generation import generate_c_code_implicit_ode, generate_c_code_gnsf, generate_c_code_explicit_ode from .acados_sim import AcadosSim from .acados_ocp import AcadosOcp -from .acados_model import acados_model_strip_casadi_symbolics -from .utils import is_column, render_template, format_class_dict, np_array_to_list,\ - make_model_consistent, set_up_imported_gnsf_model, get_python_interface_path +from .utils import is_column, render_template, format_class_dict, make_object_json_dumpable,\ + make_model_consistent, set_up_imported_gnsf_model, get_python_interface_path, get_lib_ext,\ + casadi_length, is_empty, check_casadi_version from .builders import CMakeBuilder +from .gnsf.detect_gnsf_structure import detect_gnsf_structure -def make_sim_dims_consistent(acados_sim): + +def make_sim_dims_consistent(acados_sim: AcadosSim): dims = acados_sim.dims model = acados_sim.model # nx if is_column(model.x): - dims.nx = model.x.shape[0] + dims.nx = casadi_length(model.x) else: - raise Exception("model.x should be column vector!") + raise Exception('model.x should be column vector!') # nu - if is_column(model.u): - dims.nu = model.u.shape[0] - elif model.u == None or model.u == []: + if is_empty(model.u): dims.nu = 0 else: - raise Exception("model.u should be column vector or None!") + dims.nu = casadi_length(model.u) # nz - if is_column(model.z): - dims.nz = model.z.shape[0] - elif model.z == None or model.z == []: + if is_empty(model.z): dims.nz = 0 else: - raise Exception("model.z should be column vector or None!") + dims.nz = casadi_length(model.z) # np - if is_column(model.p): - dims.np = model.p.shape[0] - elif model.p == None or model.p == []: + if is_empty(model.p): dims.np = 0 else: - raise Exception("model.p should be column vector or None!") + dims.np = casadi_length(model.p) + if acados_sim.parameter_values.shape[0] != dims.np: + raise Exception('inconsistent dimension np, regarding model.p and parameter_values.' + \ + f'\nGot np = {dims.np}, acados_sim.parameter_values.shape = {acados_sim.parameter_values.shape[0]}\n') def get_sim_layout(): @@ -92,7 +91,7 @@ def get_sim_layout(): return sim_layout -def sim_formulation_json_dump(acados_sim, json_file='acados_sim.json'): +def sim_formulation_json_dump(acados_sim: AcadosSim, json_file='acados_sim.json'): # Load acados_sim structure description sim_layout = get_sim_layout() @@ -105,11 +104,10 @@ def sim_formulation_json_dump(acados_sim, json_file='acados_sim.json'): # Copy sim object attributes dictionaries sim_dict[key]=dict(getattr(acados_sim, key).__dict__) - sim_dict['model'] = acados_model_strip_casadi_symbolics(sim_dict['model']) sim_json = format_class_dict(sim_dict) with open(json_file, 'w') as f: - json.dump(sim_json, f, default=np_array_to_list, indent=4, sort_keys=True) + json.dump(sim_json, f, default=make_object_json_dumpable, indent=4, sort_keys=True) def sim_get_default_cmake_builder() -> CMakeBuilder: @@ -122,47 +120,49 @@ def sim_get_default_cmake_builder() -> CMakeBuilder: return cmake_builder -def sim_render_templates(json_file, model_name, code_export_dir, cmake_options: CMakeBuilder = None): +def sim_render_templates(json_file, model_name: str, code_export_dir, cmake_options: CMakeBuilder = None): # setting up loader and environment json_path = os.path.join(os.getcwd(), json_file) if not os.path.exists(json_path): raise Exception(f"{json_path} not found!") - template_dir = code_export_dir - - ## Render templates + # Render templates in_file = 'acados_sim_solver.in.c' out_file = f'acados_sim_solver_{model_name}.c' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, code_export_dir, json_path) in_file = 'acados_sim_solver.in.h' out_file = f'acados_sim_solver_{model_name}.h' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, code_export_dir, json_path) + + in_file = 'acados_sim_solver.in.pxd' + out_file = f'acados_sim_solver.pxd' + render_template(in_file, out_file, code_export_dir, json_path) # Builder if cmake_options is not None: in_file = 'CMakeLists.in.txt' out_file = 'CMakeLists.txt' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, code_export_dir, json_path) else: in_file = 'Makefile.in' out_file = 'Makefile' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, code_export_dir, json_path) in_file = 'main_sim.in.c' out_file = f'main_sim_{model_name}.c' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, code_export_dir, json_path) - ## folder model - template_dir = os.path.join(code_export_dir, model_name + '_model') + # folder model + model_dir = os.path.join(code_export_dir, model_name + '_model') in_file = 'model.in.h' out_file = f'{model_name}_model.h' - render_template(in_file, out_file, template_dir, json_path) + render_template(in_file, out_file, model_dir, json_path) -def sim_generate_casadi_functions(acados_sim): +def sim_generate_external_functions(acados_sim: AcadosSim): model = acados_sim.model model = make_model_consistent(model) @@ -170,7 +170,16 @@ def sim_generate_casadi_functions(acados_sim): opts = dict(generate_hess = acados_sim.solver_options.sens_hess, code_export_directory = acados_sim.code_export_directory) + + # create code_export_dir, model_dir + code_export_dir = acados_sim.code_export_directory + opts['code_export_directory'] = code_export_dir + model_dir = os.path.join(code_export_dir, model.name + '_model') + if not os.path.exists(model_dir): + os.makedirs(model_dir) + # generate external functions + check_casadi_version() if integrator_type == 'ERK': generate_c_code_explicit_ode(model, opts) elif integrator_type == 'IRK': @@ -190,62 +199,117 @@ class AcadosSimSolver: the `CMake` pipeline instead of a `Makefile` (`CMake` seems to be the better option in conjunction with `MS Visual Studio`); default: `None` """ - def __init__(self, acados_sim_, json_file='acados_sim.json', build=True, cmake_builder: CMakeBuilder = None): + if sys.platform=="win32": + from ctypes import wintypes + from ctypes import WinDLL + dlclose = WinDLL('kernel32', use_last_error=True).FreeLibrary + dlclose.argtypes = [wintypes.HMODULE] + else: + dlclose = CDLL(None).dlclose + dlclose.argtypes = [c_void_p] - self.solver_created = False - if isinstance(acados_sim_, AcadosOcp): - # set up acados_sim_ - acados_sim = AcadosSim() - acados_sim.model = acados_sim_.model - acados_sim.dims.nx = acados_sim_.dims.nx - acados_sim.dims.nu = acados_sim_.dims.nu - acados_sim.dims.nz = acados_sim_.dims.nz - acados_sim.dims.np = acados_sim_.dims.np - acados_sim.solver_options.integrator_type = acados_sim_.solver_options.integrator_type - acados_sim.code_export_directory = acados_sim_.code_export_directory + @classmethod + def generate(cls, acados_sim: AcadosSim, json_file='acados_sim.json', cmake_builder: CMakeBuilder = None): + """ + Generates the code for an acados sim solver, given the description in acados_sim + """ - elif isinstance(acados_sim_, AcadosSim): - acados_sim = acados_sim_ + acados_sim.code_export_directory = os.path.abspath(acados_sim.code_export_directory) - acados_sim.__problem_class = 'SIM' - - model_name = acados_sim.model.name + # make dims consistent make_sim_dims_consistent(acados_sim) - # reuse existing json and casadi functions, when creating integrator from ocp - if isinstance(acados_sim_, AcadosSim): - if acados_sim.solver_options.integrator_type == 'GNSF': + # module dependent post processing + if acados_sim.solver_options.integrator_type == 'GNSF': + if acados_sim.solver_options.sens_hess == True: + raise Exception("AcadosSimSolver: GNSF does not support sens_hess = True.") + if 'gnsf_model' in acados_sim.__dict__: set_up_imported_gnsf_model(acados_sim) - - sim_generate_casadi_functions(acados_sim) - sim_formulation_json_dump(acados_sim, json_file) - - code_export_dir = acados_sim.code_export_directory - if build: - # render templates - sim_render_templates(json_file, model_name, code_export_dir, cmake_builder) - - # Compile solver - cwd = os.getcwd() - code_export_dir = os.path.abspath(code_export_dir) - os.chdir(code_export_dir) - if cmake_builder is not None: - cmake_builder.exec(code_export_dir) else: - os.system('make sim_shared_lib') - os.chdir(cwd) + detect_gnsf_structure(acados_sim) - self.sim_struct = acados_sim - model_name = self.sim_struct.model.name + # generate external functions + sim_generate_external_functions(acados_sim) + + # dump to json + sim_formulation_json_dump(acados_sim, json_file) + + # render templates + sim_render_templates(json_file, acados_sim.model.name, acados_sim.code_export_directory, cmake_builder) + + + @classmethod + def build(cls, code_export_dir, with_cython=False, cmake_builder: CMakeBuilder = None, verbose: bool = True): + # Compile solver + cwd = os.getcwd() + os.chdir(code_export_dir) + if with_cython: + call( + ['make', 'clean_sim_cython'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) + call( + ['make', 'sim_cython'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) + else: + if cmake_builder is not None: + cmake_builder.exec(code_export_dir, verbose=verbose) + else: + call( + ['make', 'sim_shared_lib'], + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) + os.chdir(cwd) + + + @classmethod + def create_cython_solver(cls, json_file): + """ + """ + with open(json_file, 'r') as f: + acados_sim_json = json.load(f) + code_export_directory = acados_sim_json['code_export_directory'] + + importlib.invalidate_caches() + rel_code_export_directory = os.path.relpath(code_export_directory) + acados_sim_solver_pyx = importlib.import_module(f'{rel_code_export_directory}.acados_sim_solver_pyx') + + AcadosSimSolverCython = getattr(acados_sim_solver_pyx, 'AcadosSimSolverCython') + return AcadosSimSolverCython(acados_sim_json['model']['name']) + + def __init__(self, acados_sim, json_file='acados_sim.json', generate=True, build=True, cmake_builder: CMakeBuilder = None, verbose: bool = True): + + self.solver_created = False + self.acados_sim = acados_sim + model_name = acados_sim.model.name self.model_name = model_name + code_export_dir = os.path.abspath(acados_sim.code_export_directory) + + # reuse existing json and casadi functions, when creating integrator from ocp + if generate and not isinstance(acados_sim, AcadosOcp): + self.generate(acados_sim, json_file=json_file, cmake_builder=cmake_builder) + + if build: + self.build(code_export_dir, cmake_builder=cmake_builder, verbose=True) + + # prepare library loading + lib_prefix = 'lib' + lib_ext = get_lib_ext() + if os.name == 'nt': + lib_prefix = '' + # Load acados library to avoid unloading the library. # This is necessary if acados was compiled with OpenMP, since the OpenMP threads can't be destroyed. # Unloading a library which uses OpenMP results in a segfault (on any platform?). # see [https://stackoverflow.com/questions/34439956/vc-crash-when-freeing-a-dll-built-with-openmp] # or [https://python.hotexamples.com/examples/_ctypes/-/dlclose/python-dlclose-function-examples.html] - libacados_name = 'libacados.so' + libacados_name = f'{lib_prefix}acados{lib_ext}' libacados_filepath = os.path.join(acados_sim.acados_lib_path, libacados_name) self.__acados_lib = CDLL(libacados_filepath) # find out if acados was compiled with OpenMP @@ -257,19 +321,12 @@ class AcadosSimSolver: print('acados was compiled with OpenMP.') else: print('acados was compiled without OpenMP.') + libacados_sim_solver_name = f'{lib_prefix}acados_sim_solver_{self.model_name}{lib_ext}' + self.shared_lib_name = os.path.join(code_export_dir, libacados_sim_solver_name) - # Ctypes - lib_prefix = 'lib' - lib_ext = '.so' - if os.name == 'nt': - lib_prefix = '' - lib_ext = '' - self.shared_lib_name = os.path.join(code_export_dir, f'{lib_prefix}acados_sim_solver_{model_name}{lib_ext}') - print(f'self.shared_lib_name = "{self.shared_lib_name}"') - + # get shared_lib self.shared_lib = CDLL(self.shared_lib_name) - # create capsule getattr(self.shared_lib, f"{model_name}_acados_sim_solver_create_capsule").restype = c_void_p self.capsule = getattr(self.shared_lib, f"{model_name}_acados_sim_solver_create_capsule")() @@ -304,23 +361,34 @@ class AcadosSimSolver: getattr(self.shared_lib, f"{model_name}_acados_get_sim_solver").restype = c_void_p self.sim_solver = getattr(self.shared_lib, f"{model_name}_acados_get_sim_solver")(self.capsule) - nu = self.sim_struct.dims.nu - nx = self.sim_struct.dims.nx - nz = self.sim_struct.dims.nz - self.gettable = { - 'x': nx, - 'xn': nx, - 'u': nu, - 'z': nz, - 'S_forw': nx*(nx+nu), - 'Sx': nx*nx, - 'Su': nx*nu, - 'S_adj': nx+nu, - 'S_hess': (nx+nu)*(nx+nu), - 'S_algebraic': (nz)*(nx+nu), - } + self.gettable_vectors = ['x', 'u', 'z', 'S_adj'] + self.gettable_matrices = ['S_forw', 'Sx', 'Su', 'S_hess', 'S_algebraic'] + self.gettable_scalars = ['CPUtime', 'time_tot', 'ADtime', 'time_ad', 'LAtime', 'time_la'] - self.settable = ['S_adj', 'T', 'x', 'u', 'xdot', 'z', 'p'] # S_forw + + def simulate(self, x=None, u=None, z=None, p=None): + """ + Simulate the system forward for the given x, u, z, p and return x_next. + Wrapper around `solve()` taking care of setting/getting inputs/outputs. + """ + if x is not None: + self.set('x', x) + if u is not None: + self.set('u', u) + if z is not None: + self.set('z', z) + if p is not None: + self.set('p', p) + + status = self.solve() + + if status == 2: + print("Warning: acados_sim_solver reached maximum iterations.") + elif status != 0: + raise Exception(f'acados_sim_solver for model {self.model_name} returned status {status}.') + + x_next = self.get('x') + return x_next def solve(self): @@ -338,55 +406,64 @@ class AcadosSimSolver: """ Get the last solution of the solver. - :param str field: string in ['x', 'u', 'z', 'S_forw', 'Sx', 'Su', 'S_adj', 'S_hess', 'S_algebraic'] + :param str field: string in ['x', 'u', 'z', 'S_forw', 'Sx', 'Su', 'S_adj', 'S_hess', 'S_algebraic', 'CPUtime', 'time_tot', 'ADtime', 'time_ad', 'LAtime', 'time_la'] """ - field = field_ - field = field.encode('utf-8') + field = field_.encode('utf-8') - if field_ in self.gettable.keys(): + if field_ in self.gettable_vectors: + # get dims + dims = np.ascontiguousarray(np.zeros((2,)), dtype=np.intc) + dims_data = cast(dims.ctypes.data, POINTER(c_int)) + + self.shared_lib.sim_dims_get_from_attr.argtypes = [c_void_p, c_void_p, c_char_p, POINTER(c_int)] + self.shared_lib.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, dims_data) # allocate array - dims = self.gettable[field_] - out = np.ascontiguousarray(np.zeros((dims,)), dtype=np.float64) + out = np.ascontiguousarray(np.zeros((dims[0],)), dtype=np.float64) out_data = cast(out.ctypes.data, POINTER(c_double)) self.shared_lib.sim_out_get.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p] self.shared_lib.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, out_data) - if field_ == 'S_forw': - nu = self.sim_struct.dims.nu - nx = self.sim_struct.dims.nx - out = out.reshape(nx, nx+nu, order='F') - elif field_ == 'Sx': - nx = self.sim_struct.dims.nx - out = out.reshape(nx, nx, order='F') - elif field_ == 'Su': - nx = self.sim_struct.dims.nx - nu = self.sim_struct.dims.nu - out = out.reshape(nx, nu, order='F') - elif field_ == 'S_hess': - nx = self.sim_struct.dims.nx - nu = self.sim_struct.dims.nu - out = out.reshape(nx+nu, nx+nu, order='F') - elif field_ == 'S_algebraic': - nx = self.sim_struct.dims.nx - nu = self.sim_struct.dims.nu - nz = self.sim_struct.dims.nz - out = out.reshape(nz, nx+nu, order='F') + elif field_ in self.gettable_matrices: + # get dims + dims = np.ascontiguousarray(np.zeros((2,)), dtype=np.intc) + dims_data = cast(dims.ctypes.data, POINTER(c_int)) + + self.shared_lib.sim_dims_get_from_attr.argtypes = [c_void_p, c_void_p, c_char_p, POINTER(c_int)] + self.shared_lib.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, dims_data) + + out = np.zeros((dims[0], dims[1]), order='F') + out_data = cast(out.ctypes.data, POINTER(c_double)) + + self.shared_lib.sim_out_get.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p] + self.shared_lib.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, out_data) + + elif field_ in self.gettable_scalars: + scalar = c_double() + scalar_data = byref(scalar) + self.shared_lib.sim_out_get.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p] + self.shared_lib.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, scalar_data) + + out = scalar.value else: raise Exception(f'AcadosSimSolver.get(): Unknown field {field_},' \ - f' available fields are {", ".join(self.gettable.keys())}') + f' available fields are {", ".join(self.gettable_vectors+self.gettable_matrices)}, {", ".join(self.gettable_scalars)}') return out - def set(self, field_, value_): + + def set(self, field_: str, value_): """ Set numerical data inside the solver. - :param field: string in ['p', 'S_adj', 'T', 'x', 'u', 'xdot', 'z'] + :param field: string in ['x', 'u', 'p', 'xdot', 'z', 'seed_adj', 'T'] :param value: the value with appropriate size. """ + settable = ['x', 'u', 'p', 'xdot', 'z', 'seed_adj', 'T'] # S_forw + + # TODO: check and throw error here. then remove checks in Cython for speed # cast value_ to avoid conversion issues if isinstance(value_, (float, int)): value_ = np.array([value_]) @@ -395,12 +472,11 @@ class AcadosSimSolver: value_data = cast(value_.ctypes.data, POINTER(c_double)) value_data_p = cast((value_data), c_void_p) - field = field_ - field = field.encode('utf-8') + field = field_.encode('utf-8') # treat parameters separately if field_ == 'p': - model_name = self.sim_struct.model.name + model_name = self.acados_sim.model.name getattr(self.shared_lib, f"{model_name}_acados_sim_update_params").argtypes = [c_void_p, POINTER(c_double), c_int] value_data = cast(value_.ctypes.data, POINTER(c_double)) getattr(self.shared_lib, f"{model_name}_acados_sim_update_params")(self.capsule, value_data, value_.shape[0]) @@ -420,19 +496,46 @@ class AcadosSimSolver: value_shape = (value_shape[0], 0) if value_shape != tuple(dims): - raise Exception('AcadosSimSolver.set(): mismatching dimension' \ - ' for field "{}" with dimension {} (you have {})'.format(field_, tuple(dims), value_shape)) + raise Exception(f'AcadosSimSolver.set(): mismatching dimension' \ + f' for field "{field_}" with dimension {tuple(dims)} (you have {value_shape}).') # set if field_ in ['xdot', 'z']: self.shared_lib.sim_solver_set.argtypes = [c_void_p, c_char_p, c_void_p] self.shared_lib.sim_solver_set(self.sim_solver, field, value_data_p) - elif field_ in self.settable: + elif field_ in settable: self.shared_lib.sim_in_set.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p] self.shared_lib.sim_in_set(self.sim_config, self.sim_dims, self.sim_in, field, value_data_p) else: raise Exception(f'AcadosSimSolver.set(): Unknown field {field_},' \ - f' available fields are {", ".join(self.settable)}') + f' available fields are {", ".join(settable)}') + + return + + + def options_set(self, field_: str, value_: bool): + """ + Set solver options + + :param field: string in ['sens_forw', 'sens_adj', 'sens_hess'] + :param value: Boolean + """ + fields = ['sens_forw', 'sens_adj', 'sens_hess'] + if field_ not in fields: + raise Exception(f"field {field_} not supported. Supported values are {', '.join(fields)}.\n") + + field = field_.encode('utf-8') + value_ctypes = c_bool(value_) + + if not isinstance(value_, bool): + raise TypeError("options_set: expected boolean for value") + + # only allow setting + if getattr(self.acados_sim.solver_options, field_) or value_ == False: + self.shared_lib.sim_opts_set.argtypes = [c_void_p, c_void_p, c_char_p, POINTER(c_bool)] + self.shared_lib.sim_opts_set(self.sim_config, self.sim_opts, field, value_ctypes) + else: + raise RuntimeError(f"Cannot set option {field_} to True, because it was False in original solver options.\n") return @@ -451,4 +554,6 @@ class AcadosSimSolver: try: self.dlclose(self.shared_lib._handle) except: + print(f"WARNING: acados Python interface could not close shared_lib handle of AcadosSimSolver {self.model_name}.\n", + "Attempting to create a new one with the same name will likely result in the old one being used!") pass diff --git a/third_party/acados/acados_template/acados_sim_solver_common.pxd b/third_party/acados/acados_template/acados_sim_solver_common.pxd new file mode 100644 index 0000000000..cc6a58efd7 --- /dev/null +++ b/third_party/acados/acados_template/acados_sim_solver_common.pxd @@ -0,0 +1,64 @@ +# -*- coding: future_fstrings -*- +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + + +cdef extern from "acados/sim/sim_common.h": + ctypedef struct sim_config: + pass + + ctypedef struct sim_opts: + pass + + ctypedef struct sim_in: + pass + + ctypedef struct sim_out: + pass + + +cdef extern from "acados_c/sim_interface.h": + + ctypedef struct sim_plan: + pass + + ctypedef struct sim_solver: + pass + + # out + void sim_out_get(sim_config *config, void *dims, sim_out *out, const char *field, void *value) + int sim_dims_get_from_attr(sim_config *config, void *dims, const char *field, void *dims_data) + + # opts + void sim_opts_set(sim_config *config, void *opts_, const char *field, void *value) + + # get/set + void sim_in_set(sim_config *config, void *dims, sim_in *sim_in, const char *field, void *value) + void sim_solver_set(sim_solver *solver, const char *field, void *value) \ No newline at end of file diff --git a/third_party/acados/acados_template/acados_sim_solver_pyx.pyx b/third_party/acados/acados_template/acados_sim_solver_pyx.pyx new file mode 100644 index 0000000000..be400addc7 --- /dev/null +++ b/third_party/acados/acados_template/acados_sim_solver_pyx.pyx @@ -0,0 +1,256 @@ +# -*- coding: future_fstrings -*- +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# cython: language_level=3 +# cython: profile=False +# distutils: language=c + +cimport cython +from libc cimport string +# from libc cimport bool as bool_t + +cimport acados_sim_solver_common +cimport acados_sim_solver + +cimport numpy as cnp + +import os +from datetime import datetime +import numpy as np + + +cdef class AcadosSimSolverCython: + """ + Class to interact with the acados sim solver C object. + """ + + cdef acados_sim_solver.sim_solver_capsule *capsule + cdef void *sim_dims + cdef acados_sim_solver_common.sim_opts *sim_opts + cdef acados_sim_solver_common.sim_config *sim_config + cdef acados_sim_solver_common.sim_out *sim_out + cdef acados_sim_solver_common.sim_in *sim_in + cdef acados_sim_solver_common.sim_solver *sim_solver + + cdef bint solver_created + + cdef str model_name + + cdef str sim_solver_type + + cdef list gettable_vectors + cdef list gettable_matrices + cdef list gettable_scalars + + def __cinit__(self, model_name): + + self.solver_created = False + + self.model_name = model_name + + # create capsule + self.capsule = acados_sim_solver.acados_sim_solver_create_capsule() + + # create solver + assert acados_sim_solver.acados_sim_create(self.capsule) == 0 + self.solver_created = True + + # get pointers solver + self.__get_pointers_solver() + + self.gettable_vectors = ['x', 'u', 'z', 'S_adj'] + self.gettable_matrices = ['S_forw', 'Sx', 'Su', 'S_hess', 'S_algebraic'] + self.gettable_scalars = ['CPUtime', 'time_tot', 'ADtime', 'time_ad', 'LAtime', 'time_la'] + + def __get_pointers_solver(self): + """ + Private function to get the pointers for solver + """ + # get pointers solver + self.sim_opts = acados_sim_solver.acados_get_sim_opts(self.capsule) + self.sim_dims = acados_sim_solver.acados_get_sim_dims(self.capsule) + self.sim_config = acados_sim_solver.acados_get_sim_config(self.capsule) + self.sim_out = acados_sim_solver.acados_get_sim_out(self.capsule) + self.sim_in = acados_sim_solver.acados_get_sim_in(self.capsule) + self.sim_solver = acados_sim_solver.acados_get_sim_solver(self.capsule) + + + def simulate(self, x=None, u=None, z=None, p=None): + """ + Simulate the system forward for the given x, u, z, p and return x_next. + Wrapper around `solve()` taking care of setting/getting inputs/outputs. + """ + if x is not None: + self.set('x', x) + if u is not None: + self.set('u', u) + if z is not None: + self.set('z', z) + if p is not None: + self.set('p', p) + + status = self.solve() + + if status == 2: + print("Warning: acados_sim_solver reached maximum iterations.") + elif status != 0: + raise Exception(f'acados_sim_solver for model {self.model_name} returned status {status}.') + + x_next = self.get('x') + return x_next + + + def solve(self): + """ + Solve the sim with current input. + """ + return acados_sim_solver.acados_sim_solve(self.capsule) + + + def get(self, field_): + """ + Get the last solution of the solver. + + :param str field: string in ['x', 'u', 'z', 'S_forw', 'Sx', 'Su', 'S_adj', 'S_hess', 'S_algebraic', 'CPUtime', 'time_tot', 'ADtime', 'time_ad', 'LAtime', 'time_la'] + """ + field = field_.encode('utf-8') + + if field_ in self.gettable_vectors: + return self.__get_vector(field) + elif field_ in self.gettable_matrices: + return self.__get_matrix(field) + elif field_ in self.gettable_scalars: + return self.__get_scalar(field) + else: + raise Exception(f'AcadosSimSolver.get(): Unknown field {field_},' \ + f' available fields are {", ".join(self.gettable.keys())}') + + + def __get_scalar(self, field): + cdef double scalar + acados_sim_solver_common.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, &scalar) + return scalar + + + def __get_vector(self, field): + cdef int[2] dims + acados_sim_solver_common.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, &dims[0]) + # cdef cnp.ndarray[cnp.float64_t, ndim=1] out = np.ascontiguousarray(np.zeros((dims[0],), dtype=np.float64)) + cdef cnp.ndarray[cnp.float64_t, ndim=1] out = np.zeros((dims[0]),) + acados_sim_solver_common.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, out.data) + return out + + + def __get_matrix(self, field): + cdef int[2] dims + acados_sim_solver_common.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, &dims[0]) + cdef cnp.ndarray[cnp.float64_t, ndim=2] out = np.zeros((dims[0], dims[1]), order='F', dtype=np.float64) + acados_sim_solver_common.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, out.data) + return out + + + def set(self, field_: str, value_): + """ + Set numerical data inside the solver. + + :param field: string in ['p', 'seed_adj', 'T', 'x', 'u', 'xdot', 'z'] + :param value: the value with appropriate size. + """ + settable = ['seed_adj', 'T', 'x', 'u', 'xdot', 'z', 'p'] # S_forw + + # cast value_ to avoid conversion issues + if isinstance(value_, (float, int)): + value_ = np.array([value_]) + # if len(value_.shape) > 1: + # raise RuntimeError('AcadosSimSolverCython.set(): value_ should be 1 dimensional') + + cdef cnp.ndarray[cnp.float64_t, ndim=1] value = np.ascontiguousarray(value_, dtype=np.float64).flatten() + + field = field_.encode('utf-8') + cdef int[2] dims + + # treat parameters separately + if field_ == 'p': + assert acados_sim_solver.acados_sim_update_params(self.capsule, value.data, value.shape[0]) == 0 + return + else: + acados_sim_solver_common.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, &dims[0]) + + value_ = np.ravel(value_, order='F') + + value_shape = value_.shape + if len(value_shape) == 1: + value_shape = (value_shape[0], 0) + + if value_shape != tuple(dims): + raise Exception(f'AcadosSimSolverCython.set(): mismatching dimension' \ + f' for field "{field_}" with dimension {tuple(dims)} (you have {value_shape}).') + + # set + if field_ in ['xdot', 'z']: + acados_sim_solver_common.sim_solver_set(self.sim_solver, field, value.data) + elif field_ in settable: + acados_sim_solver_common.sim_in_set(self.sim_config, self.sim_dims, self.sim_in, field, value.data) + else: + raise Exception(f'AcadosSimSolverCython.set(): Unknown field {field_},' \ + f' available fields are {", ".join(settable)}') + + + def options_set(self, field_: str, value_: bool): + """ + Set solver options + + :param field: string in ['sens_forw', 'sens_adj', 'sens_hess'] + :param value: Boolean + """ + fields = ['sens_forw', 'sens_adj', 'sens_hess'] + if field_ not in fields: + raise Exception(f"field {field_} not supported. Supported values are {', '.join(fields)}.\n") + + field = field_.encode('utf-8') + + if not isinstance(value_, bool): + raise TypeError("options_set: expected boolean for value") + + cdef bint bool_value = value_ + acados_sim_solver_common.sim_opts_set(self.sim_config, self.sim_opts, field, &bool_value) + # TODO: only allow setting + # if getattr(self.acados_sim.solver_options, field_) or value_ == False: + # acados_sim_solver_common.sim_opts_set(self.sim_config, self.sim_opts, field, &bool_value) + # else: + # raise RuntimeError(f"Cannot set option {field_} to True, because it was False in original solver options.\n") + + return + + + def __del__(self): + if self.solver_created: + acados_sim_solver.acados_sim_free(self.capsule) + acados_sim_solver.acados_sim_solver_free_capsule(self.capsule) diff --git a/third_party/acados/acados_template/acados_solver_common.pxd b/third_party/acados/acados_template/acados_solver_common.pxd index fedd7190d9..c6d59d40a5 100644 --- a/third_party/acados/acados_template/acados_solver_common.pxd +++ b/third_party/acados/acados_template/acados_solver_common.pxd @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -87,7 +84,7 @@ cdef extern from "acados_c/ocp_nlp_interface.h": int stage, const char *field, int *dims_out) void ocp_nlp_cost_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, int stage, const char *field, int *dims_out) - void ocp_nlp_dynamics_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, + void ocp_nlp_qp_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, int stage, const char *field, int *dims_out) # opts diff --git a/third_party/acados/acados_template/builders.py b/third_party/acados/acados_template/builders.py index f595033ceb..6f21bfe8cd 100644 --- a/third_party/acados/acados_template/builders.py +++ b/third_party/acados/acados_template/builders.py @@ -34,7 +34,7 @@ import os import sys -from subprocess import call +from subprocess import DEVNULL, call, STDOUT class CMakeBuilder: @@ -78,7 +78,7 @@ class CMakeBuilder: def get_cmd3_install(self): return f'cmake --install "{self._build_dir}"' - def exec(self, code_export_directory): + def exec(self, code_export_directory, verbose=True): """ Execute the compilation using `CMake` with the given settings. :param code_export_directory: must be the absolute path to the directory where the code was exported to @@ -96,17 +96,32 @@ class CMakeBuilder: os.chdir(self._build_dir) cmd_str = self.get_cmd1_cmake() print(f'call("{cmd_str})"') - retcode = call(cmd_str, shell=True) + retcode = call( + cmd_str, + shell=True, + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) if retcode != 0: raise RuntimeError(f'CMake command "{cmd_str}" was terminated by signal {retcode}') cmd_str = self.get_cmd2_build() print(f'call("{cmd_str}")') - retcode = call(cmd_str, shell=True) + retcode = call( + cmd_str, + shell=True, + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) if retcode != 0: raise RuntimeError(f'Build command "{cmd_str}" was terminated by signal {retcode}') cmd_str = self.get_cmd3_install() print(f'call("{cmd_str}")') - retcode = call(cmd_str, shell=True) + retcode = call( + cmd_str, + shell=True, + stdout=None if verbose else DEVNULL, + stderr=None if verbose else STDOUT + ) if retcode != 0: raise RuntimeError(f'Install command "{cmd_str}" was terminated by signal {retcode}') except OSError as e: diff --git a/third_party/acados/acados_template/c_templates_tera/CMakeLists.in.txt b/third_party/acados/acados_template/c_templates_tera/CMakeLists.in.txt index 3d6483b5d2..99bc26f750 100644 --- a/third_party/acados/acados_template/c_templates_tera/CMakeLists.in.txt +++ b/third_party/acados/acados_template/c_templates_tera/CMakeLists.in.txt @@ -1,8 +1,5 @@ # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -121,12 +118,14 @@ {%- set openmp_flag = " " %} {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} {%- set link_libs = "-lqpOASES_e" %} + {%- elif qp_solver == "FULL_CONDENSING_DAQP" %} + {%- set link_libs = "-ldaqp" %} {%- else %} {%- set link_libs = "" %} {%- endif %} {%- endif %} -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.13) project({{ model.name }}) @@ -139,6 +138,14 @@ option(BUILD_SIM_EXAMPLE "Should the simulation example main_sim_{{ model.name } option(BUILD_ACADOS_SIM_SOLVER_LIB "Should the simulation solver library acados_sim_solver_{{ model.name }} be build?" OFF) {%- endif %} + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_SYSTEM_NAME MATCHES "Windows") + # MinGW, change to .lib such that mex recognizes it + set(CMAKE_SHARED_LIBRARY_SUFFIX ".lib") + set(CMAKE_SHARED_LIBRARY_PREFIX "") +endif() + + # object target names set(MODEL_OBJ model_{{ model.name }}) set(OCP_OBJ ocp_{{ model.name }}) @@ -146,9 +153,11 @@ set(SIM_OBJ sim_{{ model.name }}) # model set(MODEL_SRC + {%- if model.dyn_ext_fun_type == "casadi" %} {%- if solver_options.integrator_type == "ERK" %} {{ model.name }}_model/{{ model.name }}_expl_ode_fun.c {{ model.name }}_model/{{ model.name }}_expl_vde_forw.c + {{ model.name }}_model/{{ model.name }}_expl_vde_adj.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_expl_ode_hess.c {%- endif %} @@ -176,16 +185,15 @@ set(MODEL_SRC {%- endif %} {{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c {%- elif solver_options.integrator_type == "DISCRETE" %} - {%- if model.dyn_ext_fun_type == "casadi" %} {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun.c {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac.c {%- if hessian_approx == "EXACT" %} {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac_hess.c {%- endif %} - {%- else %} - {{ model.name }}_model/{{ model.dyn_source_discrete }} - {%- endif %} {%- endif -%} + {%- else %} + {{ model.name }}_model/{{ model.dyn_generic_source }} + {%- endif %} ) add_library(${MODEL_OBJ} OBJECT ${MODEL_SRC} ) @@ -219,6 +227,9 @@ if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_ACADOS_OCP_SOLVER_LIB} OR ${BUILD_EXAMP {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_0_hess.c +{%- elif cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + {{ model.name }}_cost/{{ model.name }}_conl_cost_0_fun.c + {{ model.name }}_cost/{{ model.name }}_conl_cost_0_fun_jac_hess.c {%- elif cost_type_0 == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_0 == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun.c @@ -232,6 +243,9 @@ if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_ACADOS_OCP_SOLVER_LIB} OR ${BUILD_EXAMP {{ model.name }}_cost/{{ model.name }}_cost_y_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_hess.c +{%- elif cost_type == "CONVEX_OVER_NONLINEAR" %} + {{ model.name }}_cost/{{ model.name }}_conl_cost_fun.c + {{ model.name }}_cost/{{ model.name }}_conl_cost_fun_jac_hess.c {%- elif cost_type == "EXTERNAL" %} {%- if cost.cost_ext_fun_type == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun.c @@ -245,6 +259,9 @@ if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_ACADOS_OCP_SOLVER_LIB} OR ${BUILD_EXAMP {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.c {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun_jac_ut_xt.c {{ model.name }}_cost/{{ model.name }}_cost_y_e_hess.c +{%- elif cost_type_e == "CONVEX_OVER_NONLINEAR" %} + {{ model.name }}_cost/{{ model.name }}_conl_cost_e_fun.c + {{ model.name }}_cost/{{ model.name }}_conl_cost_e_fun_jac_hess.c {%- elif cost_type_e == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_e == "casadi" %} {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun.c @@ -275,7 +292,7 @@ set(EX_SRC main_{{ model.name }}.c) set(EX_EXE main_{{ model.name }}) {%- if model_external_shared_lib_dir and model_external_shared_lib_name %} -set(EXTERNAL_DIR {{ model_external_shared_lib_dir }}) +set(EXTERNAL_DIR {{ model_external_shared_lib_dir | replace(from="\", to="/") }}) set(EXTERNAL_LIB {{ model_external_shared_lib_name }}) {%- else %} set(EXTERNAL_DIR) @@ -283,23 +300,26 @@ set(EXTERNAL_LIB) {%- endif %} # set some search paths for preprocessor and linker -set(ACADOS_INCLUDE_PATH {{ acados_include_path }} CACHE PATH "Define the path which contains the include directory for acados.") -set(ACADOS_LIB_PATH {{ acados_lib_path }} CACHE PATH "Define the path which contains the lib directory for acados.") +set(ACADOS_INCLUDE_PATH {{ acados_include_path | replace(from="\", to="/") }} CACHE PATH "Define the path which contains the include directory for acados.") +set(ACADOS_LIB_PATH {{ acados_lib_path | replace(from="\", to="/") }} CACHE PATH "Define the path which contains the lib directory for acados.") # c-compiler flags for debugging set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb") -set(CMAKE_C_FLAGS " +set(CMAKE_C_FLAGS "-fPIC -std=c99 {{ openmp_flag }} {%- if qp_solver == "FULL_CONDENSING_QPOASES" -%} - -DACADOS_WITH_QPOASES + -DACADOS_WITH_QPOASES +{%- endif -%} +{%- if qp_solver == "FULL_CONDENSING_DAQP" -%} + -DACADOS_WITH_DAQP {%- endif -%} {%- if qp_solver == "PARTIAL_CONDENSING_OSQP" -%} - -DACADOS_WITH_OSQP + -DACADOS_WITH_OSQP {%- endif -%} {%- if qp_solver == "PARTIAL_CONDENSING_QPDUNES" -%} - -DACADOS_WITH_QPDUNES + -DACADOS_WITH_QPDUNES {%- endif -%} - -fPIC -std=c99 {{ openmp_flag }}") +") #-fno-diagnostics-show-line-numbers -g include_directories( @@ -310,6 +330,9 @@ include_directories( {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} ${ACADOS_INCLUDE_PATH}/qpOASES_e/ {%- endif %} +{%- if qp_solver == "FULL_CONDENSING_DAQP" %} + ${ACADOS_INCLUDE_PATH}/daqp/include +{%- endif %} ) # linker flags diff --git a/third_party/acados/acados_template/c_templates_tera/CPPLINT.cfg b/third_party/acados/acados_template/c_templates_tera/CPPLINT.cfg deleted file mode 100644 index bbd1caf057..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/CPPLINT.cfg +++ /dev/null @@ -1 +0,0 @@ -exclude_files=[main, acados_solver, acados_solver_sfun, Makefile, model].*\.? diff --git a/third_party/acados/acados_template/c_templates_tera/Makefile.in b/third_party/acados/acados_template/c_templates_tera/Makefile.in index d45be0a9c7..fbefc08e38 100644 --- a/third_party/acados/acados_template/c_templates_tera/Makefile.in +++ b/third_party/acados/acados_template/c_templates_tera/Makefile.in @@ -1,8 +1,5 @@ # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -120,6 +117,8 @@ {%- set openmp_flag = " " %} {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} {%- set link_libs = "-lqpOASES_e" %} + {%- elif qp_solver == "FULL_CONDENSING_DAQP" %} + {%- set link_libs = "-ldaqp" %} {%- else %} {%- set link_libs = "" %} {%- endif %} @@ -129,9 +128,11 @@ # model MODEL_SRC= -{%- if solver_options.integrator_type == "ERK" %} + {%- if model.dyn_ext_fun_type == "casadi" %} +{%- if solver_options.integrator_type == "ERK" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_ode_fun.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_vde_forw.c +MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_vde_adj.c {%- if hessian_approx == "EXACT" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_ode_hess.c {%- endif %} @@ -139,9 +140,9 @@ MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_ode_hess.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_z.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_jac_x_xdot_u_z.c - {%- if hessian_approx == "EXACT" %} + {%- if hessian_approx == "EXACT" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_hess.c - {%- endif %} + {%- endif %} {%- elif solver_options.integrator_type == "LIFTED_IRK" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_u.c @@ -159,16 +160,15 @@ MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c {%- endif %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c {%- elif solver_options.integrator_type == "DISCRETE" %} - {%- if model.dyn_ext_fun_type == "casadi" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun.c MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac.c {%- if hessian_approx == "EXACT" %} MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac_hess.c {%- endif %} - {%- else %} -MODEL_SRC+= {{ model.name }}_model/{{ model.dyn_source_discrete }} - {%- endif %} {%- endif %} + {%- else %} +MODEL_SRC+= {{ model.name }}_model/{{ model.dyn_generic_source }} + {%- endif %} MODEL_OBJ := $(MODEL_SRC:.c=.o) # optimal control problem - mostly CasADi exports @@ -200,6 +200,9 @@ OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_z OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun_jac_ut_xt.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_hess.c +{%- elif cost_type_0 == "CONVEX_OVER_NONLINEAR" %} +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_0_fun.c +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_0_fun_jac_hess.c {%- elif cost_type_0 == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_0 == "casadi" %} OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun.c @@ -213,6 +216,9 @@ OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost_0 }} OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_fun.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_fun_jac_ut_xt.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_hess.c +{%- elif cost_type == "CONVEX_OVER_NONLINEAR" %} +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_fun.c +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_fun_jac_hess.c {%- elif cost_type == "EXTERNAL" %} {%- if cost.cost_ext_fun_type == "casadi" %} OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun.c @@ -226,6 +232,9 @@ OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost }} OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun_jac_ut_xt.c OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_hess.c +{%- elif cost_type_e == "CONVEX_OVER_NONLINEAR" %} +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_e_fun.c +OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_conl_cost_e_fun_jac_hess.c {%- elif cost_type_e == "EXTERNAL" %} {%- if cost.cost_ext_fun_type_e == "casadi" %} OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun.c @@ -235,6 +244,12 @@ OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac_hess.c OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost_e }} {%- endif %} {%- endif %} +{%- if solver_options.custom_update_filename %} + {%- if solver_options.custom_update_filename != "" %} +OCP_SRC+= {{ solver_options.custom_update_filename }} + {%- endif %} +{%- endif %} + OCP_SRC+= acados_solver_{{ model.name }}.c OCP_OBJ := $(OCP_SRC:.c=.o) @@ -275,6 +290,9 @@ LIB_PATH = {{ acados_lib_path }} {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} CPPFLAGS += -DACADOS_WITH_QPOASES {%- endif %} +{%- if qp_solver == "FULL_CONDENSING_DAQP" %} +CPPFLAGS += -DACADOS_WITH_DAQP +{%- endif %} {%- if qp_solver == "PARTIAL_CONDENSING_OSQP" %} CPPFLAGS += -DACADOS_WITH_OSQP {%- endif %} @@ -288,10 +306,13 @@ CPPFLAGS+= -I$(INCLUDE_PATH)/hpipm/include {%- if qp_solver == "FULL_CONDENSING_QPOASES" %} CPPFLAGS+= -I $(INCLUDE_PATH)/qpOASES_e/ {%- endif %} + {%- if qp_solver == "FULL_CONDENSING_DAQP" %} +CPPFLAGS+= -I $(INCLUDE_PATH)/daqp/include + {%- endif %} {# c-compiler flags #} # define the c-compiler flags for make's implicit rules -CFLAGS = -fPIC -std=c99 {{ openmp_flag }} #-fno-diagnostics-show-line-numbers -g +CFLAGS = -fPIC -std=c99 {{ openmp_flag }} {{ solver_options.ext_fun_compile_flags }}#-fno-diagnostics-show-line-numbers -g # # Debugging # CFLAGS += -g3 @@ -306,9 +327,9 @@ LDLIBS+= -lm LDLIBS+= {{ link_libs }} # libraries -LIBACADOS_SOLVER=libacados_solver_{{ model.name }}.so -LIBACADOS_OCP_SOLVER=libacados_ocp_solver_{{ model.name }}.so -LIBACADOS_SIM_SOLVER=lib$(SIM_SRC:.c=.so) +LIBACADOS_SOLVER=libacados_solver_{{ model.name }}{{ shared_lib_ext }} +LIBACADOS_OCP_SOLVER=libacados_ocp_solver_{{ model.name }}{{ shared_lib_ext }} +LIBACADOS_SIM_SOLVER=lib$(SIM_SRC:.c={{ shared_lib_ext }}) # virtual targets .PHONY : all clean @@ -354,38 +375,73 @@ ocp_cython_o: ocp_cython_c $(CC) $(ACADOS_FLAGS) -c -O2 \ -fPIC \ -o acados_ocp_solver_pyx.o \ - -I /usr/include/python3.8 \ -I $(INCLUDE_PATH)/blasfeo/include/ \ -I $(INCLUDE_PATH)/hpipm/include/ \ -I $(INCLUDE_PATH) \ - -I {{ cython_include_dirs }} \ + {%- for path in cython_include_dirs %} + -I {{ path }} \ + {%- endfor %} acados_ocp_solver_pyx.c \ ocp_cython: ocp_cython_o $(CC) $(ACADOS_FLAGS) -shared \ - -o acados_ocp_solver_pyx.so \ + -o acados_ocp_solver_pyx{{ shared_lib_ext }} \ -Wl,-rpath=$(LIB_PATH) \ acados_ocp_solver_pyx.o \ - $(abspath .)/libacados_ocp_solver_{{ model.name }}.so \ + $(abspath .)/libacados_ocp_solver_{{ model.name }}{{ shared_lib_ext }} \ + $(LDFLAGS) $(LDLIBS) + +# Sim Cython targets +sim_cython_c: sim_shared_lib + cython \ + -o acados_sim_solver_pyx.c \ + -I $(INCLUDE_PATH)/../interfaces/acados_template/acados_template \ + $(INCLUDE_PATH)/../interfaces/acados_template/acados_template/acados_sim_solver_pyx.pyx \ + -I {{ code_export_directory }} \ + +sim_cython_o: sim_cython_c + $(CC) $(ACADOS_FLAGS) -c -O2 \ + -fPIC \ + -o acados_sim_solver_pyx.o \ + -I $(INCLUDE_PATH)/blasfeo/include/ \ + -I $(INCLUDE_PATH)/hpipm/include/ \ + -I $(INCLUDE_PATH) \ + {%- for path in cython_include_dirs %} + -I {{ path }} \ + {%- endfor %} + acados_sim_solver_pyx.c \ + +sim_cython: sim_cython_o + $(CC) $(ACADOS_FLAGS) -shared \ + -o acados_sim_solver_pyx{{ shared_lib_ext }} \ + -Wl,-rpath=$(LIB_PATH) \ + acados_sim_solver_pyx.o \ + $(abspath .)/libacados_sim_solver_{{ model.name }}{{ shared_lib_ext }} \ $(LDFLAGS) $(LDLIBS) {%- if os and os == "pc" %} clean: del \Q *.o 2>nul - del \Q *.so 2>nul + del \Q *{{ shared_lib_ext }} 2>nul del \Q main_{{ model.name }} 2>nul clean_ocp_shared_lib: - del \Q libacados_ocp_solver_{{ model.name }}.so 2>nul + del \Q libacados_ocp_solver_{{ model.name }}{{ shared_lib_ext }} 2>nul del \Q acados_solver_{{ model.name }}.o 2>nul clean_ocp_cython: - del \Q libacados_ocp_solver_{{ model.name }}.so 2>nul + del \Q libacados_ocp_solver_{{ model.name }}{{ shared_lib_ext }} 2>nul del \Q acados_solver_{{ model.name }}.o 2>nul - del \Q acados_ocp_solver_pyx.so 2>nul + del \Q acados_ocp_solver_pyx{{ shared_lib_ext }} 2>nul del \Q acados_ocp_solver_pyx.o 2>nul +clean_sim_cython: + del \Q libacados_sim_solver_{{ model.name }}{{ shared_lib_ext }} 2>nul + del \Q acados_sim_solver_{{ model.name }}.o 2>nul + del \Q acados_sim_solver_pyx{{ shared_lib_ext }} 2>nul + del \Q acados_sim_solver_pyx.o 2>nul + {%- else %} clean: @@ -398,9 +454,15 @@ clean_ocp_shared_lib: $(RM) $(OCP_OBJ) clean_ocp_cython: - $(RM) libacados_ocp_solver_{{ model.name }}.so + $(RM) libacados_ocp_solver_{{ model.name }}{{ shared_lib_ext }} $(RM) acados_solver_{{ model.name }}.o - $(RM) acados_ocp_solver_pyx.so + $(RM) acados_ocp_solver_pyx{{ shared_lib_ext }} $(RM) acados_ocp_solver_pyx.o +clean_sim_cython: + $(RM) libacados_sim_solver_{{ model.name }}{{ shared_lib_ext }} + $(RM) acados_sim_solver_{{ model.name }}.o + $(RM) acados_sim_solver_pyx{{ shared_lib_ext }} + $(RM) acados_sim_solver_pyx.o + {%- endif %} diff --git a/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.c b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.c index f2e75058c1..0cd098273c 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.c +++ b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -88,18 +85,19 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) double Tsim = {{ solver_options.Tsim }}; {% if solver_options.integrator_type == "IRK" %} - capsule->sim_impl_dae_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - capsule->sim_impl_dae_fun_jac_x_xdot_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - capsule->sim_impl_dae_jac_x_xdot_u_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); + capsule->sim_impl_dae_fun = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_impl_dae_fun_jac_x_xdot_z = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_impl_dae_jac_x_xdot_u_z = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + {%- if model.dyn_ext_fun_type == "casadi" %} // external functions (implicit model) - capsule->sim_impl_dae_fun->casadi_fun = &{{ model.name }}_impl_dae_fun; + capsule->sim_impl_dae_fun->casadi_fun = &{{ model.name }}_impl_dae_fun; capsule->sim_impl_dae_fun->casadi_work = &{{ model.name }}_impl_dae_fun_work; capsule->sim_impl_dae_fun->casadi_sparsity_in = &{{ model.name }}_impl_dae_fun_sparsity_in; capsule->sim_impl_dae_fun->casadi_sparsity_out = &{{ model.name }}_impl_dae_fun_sparsity_out; capsule->sim_impl_dae_fun->casadi_n_in = &{{ model.name }}_impl_dae_fun_n_in; capsule->sim_impl_dae_fun->casadi_n_out = &{{ model.name }}_impl_dae_fun_n_out; - external_function_param_casadi_create(capsule->sim_impl_dae_fun, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_impl_dae_fun, np); capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_fun = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z; capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_work = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_work; @@ -107,33 +105,39 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_sparsity_out = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_sparsity_out; capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_n_in = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_in; capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_n_out = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_out; - external_function_param_casadi_create(capsule->sim_impl_dae_fun_jac_x_xdot_z, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_impl_dae_fun_jac_x_xdot_z, np); - // external_function_param_casadi impl_dae_jac_x_xdot_u_z; + // external_function_param_{{ model.dyn_ext_fun_type }} impl_dae_jac_x_xdot_u_z; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_fun = &{{ model.name }}_impl_dae_jac_x_xdot_u_z; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_work = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_work; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_sparsity_in = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_sparsity_in; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_sparsity_out = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_sparsity_out; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_n_in = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_n_in; capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_n_out = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_n_out; - external_function_param_casadi_create(capsule->sim_impl_dae_jac_x_xdot_u_z, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_impl_dae_jac_x_xdot_u_z, np); + {%- else %} + capsule->sim_impl_dae_fun->fun = &{{ model.dyn_impl_dae_fun }}; + capsule->sim_impl_dae_fun_jac_x_xdot_z->fun = &{{ model.dyn_impl_dae_fun_jac }}; + capsule->sim_impl_dae_jac_x_xdot_u_z->fun = &{{ model.dyn_impl_dae_jac }}; + {%- endif %} {%- if hessian_approx == "EXACT" %} - capsule->sim_impl_dae_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - // external_function_param_casadi impl_dae_jac_x_xdot_u_z; + capsule->sim_impl_dae_hess = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + // external_function_param_{{ model.dyn_ext_fun_type }} impl_dae_jac_x_xdot_u_z; capsule->sim_impl_dae_hess->casadi_fun = &{{ model.name }}_impl_dae_hess; capsule->sim_impl_dae_hess->casadi_work = &{{ model.name }}_impl_dae_hess_work; capsule->sim_impl_dae_hess->casadi_sparsity_in = &{{ model.name }}_impl_dae_hess_sparsity_in; capsule->sim_impl_dae_hess->casadi_sparsity_out = &{{ model.name }}_impl_dae_hess_sparsity_out; capsule->sim_impl_dae_hess->casadi_n_in = &{{ model.name }}_impl_dae_hess_n_in; capsule->sim_impl_dae_hess->casadi_n_out = &{{ model.name }}_impl_dae_hess_n_out; - external_function_param_casadi_create(capsule->sim_impl_dae_hess, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_impl_dae_hess, np); {%- endif %} {% elif solver_options.integrator_type == "ERK" %} // explicit ode - capsule->sim_forw_vde_casadi = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - capsule->sim_expl_ode_fun_casadi = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); + capsule->sim_forw_vde_casadi = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_vde_adj_casadi = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_expl_ode_fun_casadi = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); capsule->sim_forw_vde_casadi->casadi_fun = &{{ model.name }}_expl_vde_forw; capsule->sim_forw_vde_casadi->casadi_n_in = &{{ model.name }}_expl_vde_forw_n_in; @@ -141,7 +145,15 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_forw_vde_casadi->casadi_sparsity_in = &{{ model.name }}_expl_vde_forw_sparsity_in; capsule->sim_forw_vde_casadi->casadi_sparsity_out = &{{ model.name }}_expl_vde_forw_sparsity_out; capsule->sim_forw_vde_casadi->casadi_work = &{{ model.name }}_expl_vde_forw_work; - external_function_param_casadi_create(capsule->sim_forw_vde_casadi, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_forw_vde_casadi, np); + + capsule->sim_vde_adj_casadi->casadi_fun = &{{ model.name }}_expl_vde_adj; + capsule->sim_vde_adj_casadi->casadi_n_in = &{{ model.name }}_expl_vde_adj_n_in; + capsule->sim_vde_adj_casadi->casadi_n_out = &{{ model.name }}_expl_vde_adj_n_out; + capsule->sim_vde_adj_casadi->casadi_sparsity_in = &{{ model.name }}_expl_vde_adj_sparsity_in; + capsule->sim_vde_adj_casadi->casadi_sparsity_out = &{{ model.name }}_expl_vde_adj_sparsity_out; + capsule->sim_vde_adj_casadi->casadi_work = &{{ model.name }}_expl_vde_adj_work; + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_vde_adj_casadi, np); capsule->sim_expl_ode_fun_casadi->casadi_fun = &{{ model.name }}_expl_ode_fun; capsule->sim_expl_ode_fun_casadi->casadi_n_in = &{{ model.name }}_expl_ode_fun_n_in; @@ -149,30 +161,30 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_expl_ode_fun_casadi->casadi_sparsity_in = &{{ model.name }}_expl_ode_fun_sparsity_in; capsule->sim_expl_ode_fun_casadi->casadi_sparsity_out = &{{ model.name }}_expl_ode_fun_sparsity_out; capsule->sim_expl_ode_fun_casadi->casadi_work = &{{ model.name }}_expl_ode_fun_work; - external_function_param_casadi_create(capsule->sim_expl_ode_fun_casadi, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_expl_ode_fun_casadi, np); {%- if hessian_approx == "EXACT" %} - capsule->sim_expl_ode_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - // external_function_param_casadi impl_dae_jac_x_xdot_u_z; + capsule->sim_expl_ode_hess = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + // external_function_param_{{ model.dyn_ext_fun_type }} impl_dae_jac_x_xdot_u_z; capsule->sim_expl_ode_hess->casadi_fun = &{{ model.name }}_expl_ode_hess; capsule->sim_expl_ode_hess->casadi_work = &{{ model.name }}_expl_ode_hess_work; capsule->sim_expl_ode_hess->casadi_sparsity_in = &{{ model.name }}_expl_ode_hess_sparsity_in; capsule->sim_expl_ode_hess->casadi_sparsity_out = &{{ model.name }}_expl_ode_hess_sparsity_out; capsule->sim_expl_ode_hess->casadi_n_in = &{{ model.name }}_expl_ode_hess_n_in; capsule->sim_expl_ode_hess->casadi_n_out = &{{ model.name }}_expl_ode_hess_n_out; - external_function_param_casadi_create(capsule->sim_expl_ode_hess, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_expl_ode_hess, np); {%- endif %} {% elif solver_options.integrator_type == "GNSF" -%} {% if model.gnsf.purely_linear != 1 %} - capsule->sim_gnsf_phi_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - capsule->sim_gnsf_phi_fun_jac_y = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); - capsule->sim_gnsf_phi_jac_y_uhat = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); + capsule->sim_gnsf_phi_fun = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_gnsf_phi_fun_jac_y = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); + capsule->sim_gnsf_phi_jac_y_uhat = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); {% if model.gnsf.nontrivial_f_LO == 1 %} - capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); + capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); {%- endif %} {%- endif %} - capsule->sim_gnsf_get_matrices_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)); + capsule->sim_gnsf_get_matrices_fun = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})); {% if model.gnsf.purely_linear != 1 %} capsule->sim_gnsf_phi_fun->casadi_fun = &{{ model.name }}_gnsf_phi_fun; @@ -181,7 +193,7 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_gnsf_phi_fun->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_fun_sparsity_in; capsule->sim_gnsf_phi_fun->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_fun_sparsity_out; capsule->sim_gnsf_phi_fun->casadi_work = &{{ model.name }}_gnsf_phi_fun_work; - external_function_param_casadi_create(capsule->sim_gnsf_phi_fun, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_gnsf_phi_fun, np); capsule->sim_gnsf_phi_fun_jac_y->casadi_fun = &{{ model.name }}_gnsf_phi_fun_jac_y; capsule->sim_gnsf_phi_fun_jac_y->casadi_n_in = &{{ model.name }}_gnsf_phi_fun_jac_y_n_in; @@ -189,7 +201,7 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_gnsf_phi_fun_jac_y->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_fun_jac_y_sparsity_in; capsule->sim_gnsf_phi_fun_jac_y->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_fun_jac_y_sparsity_out; capsule->sim_gnsf_phi_fun_jac_y->casadi_work = &{{ model.name }}_gnsf_phi_fun_jac_y_work; - external_function_param_casadi_create(capsule->sim_gnsf_phi_fun_jac_y, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_gnsf_phi_fun_jac_y, np); capsule->sim_gnsf_phi_jac_y_uhat->casadi_fun = &{{ model.name }}_gnsf_phi_jac_y_uhat; capsule->sim_gnsf_phi_jac_y_uhat->casadi_n_in = &{{ model.name }}_gnsf_phi_jac_y_uhat_n_in; @@ -197,7 +209,7 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_gnsf_phi_jac_y_uhat->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_jac_y_uhat_sparsity_in; capsule->sim_gnsf_phi_jac_y_uhat->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_jac_y_uhat_sparsity_out; capsule->sim_gnsf_phi_jac_y_uhat->casadi_work = &{{ model.name }}_gnsf_phi_jac_y_uhat_work; - external_function_param_casadi_create(capsule->sim_gnsf_phi_jac_y_uhat, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_gnsf_phi_jac_y_uhat, np); {% if model.gnsf.nontrivial_f_LO == 1 %} capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_fun = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz; @@ -206,7 +218,7 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_sparsity_in = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_sparsity_in; capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_sparsity_out = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_sparsity_out; capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_work = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_work; - external_function_param_casadi_create(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z, np); {%- endif %} {%- endif %} @@ -216,7 +228,7 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->sim_gnsf_get_matrices_fun->casadi_sparsity_in = &{{ model.name }}_gnsf_get_matrices_fun_sparsity_in; capsule->sim_gnsf_get_matrices_fun->casadi_sparsity_out = &{{ model.name }}_gnsf_get_matrices_fun_sparsity_out; capsule->sim_gnsf_get_matrices_fun->casadi_work = &{{ model.name }}_gnsf_get_matrices_fun_work; - external_function_param_casadi_create(capsule->sim_gnsf_get_matrices_fun, np); + external_function_param_{{ model.dyn_ext_fun_type }}_create(capsule->sim_gnsf_get_matrices_fun, np); {% endif %} // sim plan & config @@ -252,6 +264,8 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) capsule->acados_sim_opts = {{ model.name }}_sim_opts; int tmp_int = {{ solver_options.sim_method_newton_iter }}; sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "newton_iter", &tmp_int); + double tmp_double = {{ solver_options.sim_method_newton_tol }}; + sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "newton_tol", &tmp_double); sim_collocation_type collocation_type = {{ solver_options.collocation_type }}; sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "collocation_type", &collocation_type); @@ -307,7 +321,9 @@ int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule) {%- elif solver_options.integrator_type == "ERK" %} {{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model, - "expl_vde_for", capsule->sim_forw_vde_casadi); + "expl_vde_forw", capsule->sim_forw_vde_casadi); + {{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model, + "expl_vde_adj", capsule->sim_vde_adj_casadi); {{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model, "expl_ode_fun", capsule->sim_expl_ode_fun_casadi); {%- if hessian_approx == "EXACT" %} @@ -408,28 +424,29 @@ int {{ model.name }}_acados_sim_free(sim_solver_capsule *capsule) // free external function {%- if solver_options.integrator_type == "IRK" %} - external_function_param_casadi_free(capsule->sim_impl_dae_fun); - external_function_param_casadi_free(capsule->sim_impl_dae_fun_jac_x_xdot_z); - external_function_param_casadi_free(capsule->sim_impl_dae_jac_x_xdot_u_z); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_impl_dae_fun); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_impl_dae_fun_jac_x_xdot_z); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_impl_dae_jac_x_xdot_u_z); {%- if hessian_approx == "EXACT" %} - external_function_param_casadi_free(capsule->sim_impl_dae_hess); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_impl_dae_hess); {%- endif %} {%- elif solver_options.integrator_type == "ERK" %} - external_function_param_casadi_free(capsule->sim_forw_vde_casadi); - external_function_param_casadi_free(capsule->sim_expl_ode_fun_casadi); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_forw_vde_casadi); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_vde_adj_casadi); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_expl_ode_fun_casadi); {%- if hessian_approx == "EXACT" %} - external_function_param_casadi_free(capsule->sim_expl_ode_hess); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_expl_ode_hess); {%- endif %} {%- elif solver_options.integrator_type == "GNSF" %} {% if model.gnsf.purely_linear != 1 %} - external_function_param_casadi_free(capsule->sim_gnsf_phi_fun); - external_function_param_casadi_free(capsule->sim_gnsf_phi_fun_jac_y); - external_function_param_casadi_free(capsule->sim_gnsf_phi_jac_y_uhat); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_gnsf_phi_fun); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_gnsf_phi_fun_jac_y); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_gnsf_phi_jac_y_uhat); {% if model.gnsf.nontrivial_f_LO == 1 %} - external_function_param_casadi_free(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z); {%- endif %} {%- endif %} - external_function_param_casadi_free(capsule->sim_gnsf_get_matrices_fun); + external_function_param_{{ model.dyn_ext_fun_type }}_free(capsule->sim_gnsf_get_matrices_fun); {% endif %} return 0; @@ -449,6 +466,7 @@ int {{ model.name }}_acados_sim_update_params(sim_solver_capsule *capsule, doubl {%- if solver_options.integrator_type == "ERK" %} capsule->sim_forw_vde_casadi[0].set_param(capsule->sim_forw_vde_casadi, p); + capsule->sim_vde_adj_casadi[0].set_param(capsule->sim_vde_adj_casadi, p); capsule->sim_expl_ode_fun_casadi[0].set_param(capsule->sim_expl_ode_fun_casadi, p); {%- if hessian_approx == "EXACT" %} capsule->sim_expl_ode_hess[0].set_param(capsule->sim_expl_ode_hess, p); diff --git a/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.h b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.h index 7306491baf..59aee62f49 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.h +++ b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -60,22 +57,23 @@ typedef struct sim_solver_capsule /* external functions */ // ERK - external_function_param_casadi * sim_forw_vde_casadi; - external_function_param_casadi * sim_expl_ode_fun_casadi; - external_function_param_casadi * sim_expl_ode_hess; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_forw_vde_casadi; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_vde_adj_casadi; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_expl_ode_fun_casadi; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_expl_ode_hess; // IRK - external_function_param_casadi * sim_impl_dae_fun; - external_function_param_casadi * sim_impl_dae_fun_jac_x_xdot_z; - external_function_param_casadi * sim_impl_dae_jac_x_xdot_u_z; - external_function_param_casadi * sim_impl_dae_hess; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_impl_dae_fun; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_impl_dae_fun_jac_x_xdot_z; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_impl_dae_jac_x_xdot_u_z; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_impl_dae_hess; // GNSF - external_function_param_casadi * sim_gnsf_phi_fun; - external_function_param_casadi * sim_gnsf_phi_fun_jac_y; - external_function_param_casadi * sim_gnsf_phi_jac_y_uhat; - external_function_param_casadi * sim_gnsf_f_lo_jac_x1_x1dot_u_z; - external_function_param_casadi * sim_gnsf_get_matrices_fun; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_gnsf_phi_fun; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_gnsf_phi_fun_jac_y; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_gnsf_phi_jac_y_uhat; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_gnsf_f_lo_jac_x1_x1dot_u_z; + external_function_param_{{ model.dyn_ext_fun_type }} * sim_gnsf_get_matrices_fun; } sim_solver_capsule; diff --git a/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.pxd b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.pxd new file mode 100644 index 0000000000..153f98d13a --- /dev/null +++ b/third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.pxd @@ -0,0 +1,51 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + +cimport acados_sim_solver_common + +cdef extern from "acados_sim_solver_{{ model.name }}.h": + ctypedef struct sim_solver_capsule "sim_solver_capsule": + pass + + sim_solver_capsule * acados_sim_solver_create_capsule "{{ model.name }}_acados_sim_solver_create_capsule"() + int acados_sim_solver_free_capsule "{{ model.name }}_acados_sim_solver_free_capsule"(sim_solver_capsule *capsule) + + int acados_sim_create "{{ model.name }}_acados_sim_create"(sim_solver_capsule * capsule) + int acados_sim_solve "{{ model.name }}_acados_sim_solve"(sim_solver_capsule * capsule) + int acados_sim_free "{{ model.name }}_acados_sim_free"(sim_solver_capsule * capsule) + int acados_sim_update_params "{{ model.name }}_acados_sim_update_params"(sim_solver_capsule * capsule, double *value, int np_) + # int acados_sim_update_params_sparse "{{ model.name }}_acados_sim_update_params_sparse"(sim_solver_capsule * capsule, int stage, int *idx, double *p, int n_update) + + acados_sim_solver_common.sim_in *acados_get_sim_in "{{ model.name }}_acados_get_sim_in"(sim_solver_capsule * capsule) + acados_sim_solver_common.sim_out *acados_get_sim_out "{{ model.name }}_acados_get_sim_out"(sim_solver_capsule * capsule) + acados_sim_solver_common.sim_solver *acados_get_sim_solver "{{ model.name }}_acados_get_sim_solver"(sim_solver_capsule * capsule) + acados_sim_solver_common.sim_config *acados_get_sim_config "{{ model.name }}_acados_get_sim_config"(sim_solver_capsule * capsule) + acados_sim_solver_common.sim_opts *acados_get_sim_opts "{{ model.name }}_acados_get_sim_opts"(sim_solver_capsule * capsule) + void *acados_get_sim_dims "{{ model.name }}_acados_get_sim_dims"(sim_solver_capsule * capsule) diff --git a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.c b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.c index 0af8127709..5e36a53d10 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.c +++ b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -42,33 +39,26 @@ // example specific #include "{{ model.name }}_model/{{ model.name }}_model.h" -{% if constraints.constr_type == "BGP" and dims.nphi %} -#include "{{ model.name }}_constraints/{{ model.name }}_phi_constraint.h" -{% endif %} -{% if constraints.constr_type_e == "BGP" and dims.nphi_e > 0 %} -#include "{{ model.name }}_constraints/{{ model.name }}_phi_e_constraint.h" -{% endif %} -{% if constraints.constr_type == "BGH" and dims.nh > 0 %} -#include "{{ model.name }}_constraints/{{ model.name }}_h_constraint.h" -{% endif %} -{% if constraints.constr_type_e == "BGH" and dims.nh_e > 0 %} -#include "{{ model.name }}_constraints/{{ model.name }}_h_e_constraint.h" -{% endif %} -{%- if cost.cost_type == "NONLINEAR_LS" %} -#include "{{ model.name }}_cost/{{ model.name }}_cost_y_fun.h" -{%- elif cost.cost_type == "EXTERNAL" %} -#include "{{ model.name }}_cost/{{ model.name }}_external_cost.h" +#include "{{ model.name }}_constraints/{{ model.name }}_constraints.h" + +{%- if cost.cost_type != "LINEAR_LS" or cost.cost_type_e != "LINEAR_LS" or cost.cost_type_0 != "LINEAR_LS" %} +#include "{{ model.name }}_cost/{{ model.name }}_cost.h" {%- endif %} -{%- if cost.cost_type_0 == "NONLINEAR_LS" %} -#include "{{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.h" -{%- elif cost.cost_type_0 == "EXTERNAL" %} -#include "{{ model.name }}_cost/{{ model.name }}_external_cost_0.h" + +{%- if not solver_options.custom_update_filename %} + {%- set custom_update_filename = "" %} +{% else %} + {%- set custom_update_filename = solver_options.custom_update_filename %} {%- endif %} -{%- if cost.cost_type_e == "NONLINEAR_LS" %} -#include "{{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.h" -{%- elif cost.cost_type_e == "EXTERNAL" %} -#include "{{ model.name }}_cost/{{ model.name }}_external_cost_e.h" +{%- if not solver_options.custom_update_header_filename %} + {%- set custom_update_header_filename = "" %} +{% else %} + {%- set custom_update_header_filename = solver_options.custom_update_header_filename %} {%- endif %} +{%- if custom_update_header_filename != "" %} +#include "{{ custom_update_header_filename }}" +{%- endif %} + #include "acados_solver_{{ model.name }}.h" @@ -205,7 +195,6 @@ void {{ model.name }}_acados_create_1_set_plan(ocp_nlp_plan_t* nlp_solver_plan, nlp_solver_plan->nlp_constraints[N] = BGH; {%- endif %} -{%- if solver_options.hessian_approx == "EXACT" %} {%- if solver_options.regularize_method == "NO_REGULARIZE" %} nlp_solver_plan->regularization = NO_REGULARIZE; {%- elif solver_options.regularize_method == "MIRROR" %} @@ -217,7 +206,6 @@ void {{ model.name }}_acados_create_1_set_plan(ocp_nlp_plan_t* nlp_solver_plan, {%- elif solver_options.regularize_method == "CONVEXIFY" %} nlp_solver_plan->regularization = CONVEXIFY; {%- endif %} -{%- endif %} } @@ -324,11 +312,11 @@ ocp_nlp_dims* {{ model.name }}_acados_create_2_create_and_set_dimensions({{ mode ocp_nlp_dims_set_constraints(nlp_config, nlp_dims, i, "nbxe", &nbxe[i]); } -{%- if cost.cost_type_0 == "NONLINEAR_LS" or cost.cost_type_0 == "LINEAR_LS" %} +{%- if cost.cost_type_0 == "NONLINEAR_LS" or cost.cost_type_0 == "LINEAR_LS" or cost.cost_type_0 == "CONVEX_OVER_NONLINEAR"%} ocp_nlp_dims_set_cost(nlp_config, nlp_dims, 0, "ny", &ny[0]); {%- endif %} -{%- if cost.cost_type == "NONLINEAR_LS" or cost.cost_type == "LINEAR_LS" %} +{%- if cost.cost_type == "NONLINEAR_LS" or cost.cost_type == "LINEAR_LS" or cost.cost_type == "CONVEX_OVER_NONLINEAR"%} for (int i = 1; i < N; i++) ocp_nlp_dims_set_cost(nlp_config, nlp_dims, i, "ny", &ny[i]); {%- endif %} @@ -353,7 +341,7 @@ ocp_nlp_dims* {{ model.name }}_acados_create_2_create_and_set_dimensions({{ mode ocp_nlp_dims_set_constraints(nlp_config, nlp_dims, N, "nphi", &nphi[N]); ocp_nlp_dims_set_constraints(nlp_config, nlp_dims, N, "nsphi", &nsphi[N]); {%- endif %} -{%- if cost.cost_type_e == "NONLINEAR_LS" or cost.cost_type_e == "LINEAR_LS" %} +{%- if cost.cost_type_e == "NONLINEAR_LS" or cost.cost_type_e == "LINEAR_LS" or cost.cost_type_e == "CONVEX_OVER_NONLINEAR"%} ocp_nlp_dims_set_cost(nlp_config, nlp_dims, N, "ny", &ny[N]); {%- endif %} free(intNp1mem); @@ -388,7 +376,6 @@ return nlp_dims; void {{ model.name }}_acados_create_3_create_and_set_functions({{ model.name }}_solver_capsule* capsule) { const int N = capsule->nlp_solver_plan->N; - ocp_nlp_config* nlp_config = capsule->nlp_config; /************************************************ * external functions @@ -468,35 +455,50 @@ void {{ model.name }}_acados_create_3_create_and_set_functions({{ model.name }}_ {% elif solver_options.integrator_type == "IRK" %} // implicit dae - capsule->impl_dae_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_fun = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { + {%- if model.dyn_ext_fun_type == "casadi" %} MAP_CASADI_FNC(impl_dae_fun[i], {{ model.name }}_impl_dae_fun); + {%- else %} + capsule->impl_dae_fun[i].fun = &{{ model.dyn_impl_dae_fun }}; + external_function_param_{{ model.dyn_ext_fun_type }}_create(&capsule->impl_dae_fun[i], {{ dims.np }}); + {%- endif %} } - capsule->impl_dae_fun_jac_x_xdot_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_fun_jac_x_xdot_z = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { + {%- if model.dyn_ext_fun_type == "casadi" %} MAP_CASADI_FNC(impl_dae_fun_jac_x_xdot_z[i], {{ model.name }}_impl_dae_fun_jac_x_xdot_z); + {%- else %} + capsule->impl_dae_fun_jac_x_xdot_z[i].fun = &{{ model.dyn_impl_dae_fun_jac }}; + external_function_param_{{ model.dyn_ext_fun_type }}_create(&capsule->impl_dae_fun_jac_x_xdot_z[i], {{ dims.np }}); + {%- endif %} } - capsule->impl_dae_jac_x_xdot_u_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_jac_x_xdot_u_z = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { + {%- if model.dyn_ext_fun_type == "casadi" %} MAP_CASADI_FNC(impl_dae_jac_x_xdot_u_z[i], {{ model.name }}_impl_dae_jac_x_xdot_u_z); + {%- else %} + capsule->impl_dae_jac_x_xdot_u_z[i].fun = &{{ model.dyn_impl_dae_jac }}; + external_function_param_{{ model.dyn_ext_fun_type }}_create(&capsule->impl_dae_jac_x_xdot_u_z[i], {{ dims.np }}); + {%- endif %} } {%- if solver_options.hessian_approx == "EXACT" %} - capsule->impl_dae_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_hess = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { MAP_CASADI_FNC(impl_dae_hess[i], {{ model.name }}_impl_dae_hess); } {%- endif %} {% elif solver_options.integrator_type == "LIFTED_IRK" %} // external functions (implicit model) - capsule->impl_dae_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_fun = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { MAP_CASADI_FNC(impl_dae_fun[i], {{ model.name }}_impl_dae_fun); } - capsule->impl_dae_fun_jac_x_xdot_u = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + capsule->impl_dae_fun_jac_x_xdot_u = (external_function_param_{{ model.dyn_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ model.dyn_ext_fun_type }})*N); for (int i = 0; i < N; i++) { MAP_CASADI_FNC(impl_dae_fun_jac_x_xdot_u[i], {{ model.name }}_impl_dae_fun_jac_x_xdot_u); } @@ -574,6 +576,11 @@ void {{ model.name }}_acados_create_3_create_and_set_functions({{ model.name }}_ MAP_CASADI_FNC(cost_y_0_fun_jac_ut_xt, {{ model.name }}_cost_y_0_fun_jac_ut_xt); MAP_CASADI_FNC(cost_y_0_hess, {{ model.name }}_cost_y_0_hess); +{%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + // convex-over-nonlinear cost + MAP_CASADI_FNC(conl_cost_0_fun, {{ model.name }}_conl_cost_0_fun); + MAP_CASADI_FNC(conl_cost_0_fun_jac_hess, {{ model.name }}_conl_cost_0_fun_jac_hess); + {%- elif cost.cost_type_0 == "EXTERNAL" %} // external cost {%- if cost.cost_ext_fun_type_0 == "casadi" %} @@ -619,6 +626,20 @@ void {{ model.name }}_acados_create_3_create_and_set_functions({{ model.name }}_ { MAP_CASADI_FNC(cost_y_hess[i], {{ model.name }}_cost_y_hess); } + +{%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + // convex-over-nonlinear cost + capsule->conl_cost_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + for (int i = 0; i < N-1; i++) + { + MAP_CASADI_FNC(conl_cost_fun[i], {{ model.name }}_conl_cost_fun); + } + capsule->conl_cost_fun_jac_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi)*N); + for (int i = 0; i < N-1; i++) + { + MAP_CASADI_FNC(conl_cost_fun_jac_hess[i], {{ model.name }}_conl_cost_fun_jac_hess); + } + {%- elif cost.cost_type == "EXTERNAL" %} // external cost capsule->ext_cost_fun = (external_function_param_{{ cost.cost_ext_fun_type }} *) malloc(sizeof(external_function_param_{{ cost.cost_ext_fun_type }})*N); @@ -660,6 +681,12 @@ void {{ model.name }}_acados_create_3_create_and_set_functions({{ model.name }}_ MAP_CASADI_FNC(cost_y_e_fun, {{ model.name }}_cost_y_e_fun); MAP_CASADI_FNC(cost_y_e_fun_jac_ut_xt, {{ model.name }}_cost_y_e_fun_jac_ut_xt); MAP_CASADI_FNC(cost_y_e_hess, {{ model.name }}_cost_y_e_hess); + +{%- elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + // convex-over-nonlinear cost + MAP_CASADI_FNC(conl_cost_e_fun, {{ model.name }}_conl_cost_e_fun); + MAP_CASADI_FNC(conl_cost_e_fun_jac_hess, {{ model.name }}_conl_cost_e_fun_jac_hess); + {%- elif cost.cost_type_e == "EXTERNAL" %} // external cost - function {%- if cost.cost_ext_fun_type_e == "casadi" %} @@ -808,20 +835,9 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule } /**** Cost ****/ -{%- if cost.cost_type_0 == "NONLINEAR_LS" or cost.cost_type_0 == "LINEAR_LS" %} - {%- if dims.ny_0 > 0 %} - double* W_0 = calloc(NY0*NY0, sizeof(double)); - // change only the non-zero elements: - {%- for j in range(end=dims.ny_0) %} - {%- for k in range(end=dims.ny_0) %} - {%- if cost.W_0[j][k] != 0 %} - W_0[{{ j }}+(NY0) * {{ k }}] = {{ cost.W_0[j][k] }}; - {%- endif %} - {%- endfor %} - {%- endfor %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "W", W_0); - free(W_0); +{%- if dims.ny_0 == 0 %} +{%- elif cost.cost_type_0 == "NONLINEAR_LS" or cost.cost_type_0 == "LINEAR_LS" or cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} double* yref_0 = calloc(NY0, sizeof(double)); // change only the non-zero elements: {%- for j in range(end=dims.ny_0) %} @@ -831,21 +847,11 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {%- endfor %} ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "yref", yref_0); free(yref_0); - {%- endif %} {%- endif %} -{%- if cost.cost_type == "NONLINEAR_LS" or cost.cost_type == "LINEAR_LS" %} - {%- if dims.ny > 0 %} - double* W = calloc(NY*NY, sizeof(double)); - // change only the non-zero elements: - {%- for j in range(end=dims.ny) %} - {%- for k in range(end=dims.ny) %} - {%- if cost.W[j][k] != 0 %} - W[{{ j }}+(NY) * {{ k }}] = {{ cost.W[j][k] }}; - {%- endif %} - {%- endfor %} - {%- endfor %} +{%- if dims.ny == 0 %} +{%- elif cost.cost_type == "NONLINEAR_LS" or cost.cost_type == "LINEAR_LS" or cost.cost_type == "CONVEX_OVER_NONLINEAR" %} double* yref = calloc(NY, sizeof(double)); // change only the non-zero elements: {%- for j in range(end=dims.ny) %} @@ -856,15 +862,76 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule for (int i = 1; i < N; i++) { - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "W", W); ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "yref", yref); } - free(W); free(yref); - {%- endif %} {%- endif %} -{%- if cost.cost_type_0 == "LINEAR_LS" %} + +{%- if dims.ny_e == 0 %} +{%- elif cost.cost_type_e == "NONLINEAR_LS" or cost.cost_type_e == "LINEAR_LS" or cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + double* yref_e = calloc(NYN, sizeof(double)); + // change only the non-zero elements: + {%- for j in range(end=dims.ny_e) %} + {%- if cost.yref_e[j] != 0 %} + yref_e[{{ j }}] = {{ cost.yref_e[j] }}; + {%- endif %} + {%- endfor %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "yref", yref_e); + free(yref_e); +{%- endif %} + +{%- if dims.ny_0 == 0 %} +{%- elif cost.cost_type_0 == "NONLINEAR_LS" or cost.cost_type_0 == "LINEAR_LS" %} + double* W_0 = calloc(NY0*NY0, sizeof(double)); + // change only the non-zero elements: + {%- for j in range(end=dims.ny_0) %} + {%- for k in range(end=dims.ny_0) %} + {%- if cost.W_0[j][k] != 0 %} + W_0[{{ j }}+(NY0) * {{ k }}] = {{ cost.W_0[j][k] }}; + {%- endif %} + {%- endfor %} + {%- endfor %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "W", W_0); + free(W_0); +{%- endif %} + +{%- if dims.ny == 0 %} +{%- elif cost.cost_type == "NONLINEAR_LS" or cost.cost_type == "LINEAR_LS" %} + double* W = calloc(NY*NY, sizeof(double)); + // change only the non-zero elements: + {%- for j in range(end=dims.ny) %} + {%- for k in range(end=dims.ny) %} + {%- if cost.W[j][k] != 0 %} + W[{{ j }}+(NY) * {{ k }}] = {{ cost.W[j][k] }}; + {%- endif %} + {%- endfor %} + {%- endfor %} + + for (int i = 1; i < N; i++) + { + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "W", W); + } + free(W); +{%- endif %} + +{%- if dims.ny_e == 0 %} +{%- elif cost.cost_type_e == "NONLINEAR_LS" or cost.cost_type_e == "LINEAR_LS" %} + double* W_e = calloc(NYN*NYN, sizeof(double)); + // change only the non-zero elements: + {%- for j in range(end=dims.ny_e) %} + {%- for k in range(end=dims.ny_e) %} + {%- if cost.W_e[j][k] != 0 %} + W_e[{{ j }}+(NYN) * {{ k }}] = {{ cost.W_e[j][k] }}; + {%- endif %} + {%- endfor %} + {%- endfor %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "W", W_e); + free(W_e); +{%- endif %} + +{%- if dims.ny_0 == 0 %} +{%- elif cost.cost_type_0 == "LINEAR_LS" %} double* Vx_0 = calloc(NY0*NX, sizeof(double)); // change only the non-zero elements: {%- for j in range(end=dims.ny_0) %} @@ -877,7 +944,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "Vx", Vx_0); free(Vx_0); - {%- if dims.ny_0 > 0 and dims.nu > 0 %} + {%- if dims.nu > 0 %} double* Vu_0 = calloc(NY0*NU, sizeof(double)); // change only the non-zero elements: {%- for j in range(end=dims.ny_0) %} @@ -891,7 +958,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule free(Vu_0); {%- endif %} - {%- if dims.ny_0 > 0 and dims.nz > 0 %} + {%- if dims.nz > 0 %} double* Vz_0 = calloc(NY0*NZ, sizeof(double)); // change only the non-zero elements: {% for j in range(end=dims.ny_0) %} @@ -904,10 +971,10 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "Vz", Vz_0); free(Vz_0); {%- endif %} -{%- endif %}{# LINEAR LS #} +{%- endif %} - -{%- if cost.cost_type == "LINEAR_LS" %} +{%- if dims.ny == 0 %} +{%- elif cost.cost_type == "LINEAR_LS" %} double* Vx = calloc(NY*NX, sizeof(double)); // change only the non-zero elements: {%- for j in range(end=dims.ny) %} @@ -923,7 +990,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule } free(Vx); - {% if dims.ny > 0 and dims.nu > 0 %} + {% if dims.nu > 0 %} double* Vu = calloc(NY*NU, sizeof(double)); // change only the non-zero elements: {% for j in range(end=dims.ny) %} @@ -941,7 +1008,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule free(Vu); {%- endif %} - {%- if dims.ny > 0 and dims.nz > 0 %} + {%- if dims.nz > 0 %} double* Vz = calloc(NY*NZ, sizeof(double)); // change only the non-zero elements: {% for j in range(end=dims.ny) %} @@ -960,11 +1027,28 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {%- endif %} {%- endif %}{# LINEAR LS #} +{%- if dims.ny_e == 0 %} +{%- elif cost.cost_type_e == "LINEAR_LS" %} + double* Vx_e = calloc(NYN*NX, sizeof(double)); + // change only the non-zero elements: + {% for j in range(end=dims.ny_e) %} + {%- for k in range(end=dims.nx) %} + {%- if cost.Vx_e[j][k] != 0 %} + Vx_e[{{ j }}+(NYN) * {{ k }}] = {{ cost.Vx_e[j][k] }}; + {%- endif %} + {%- endfor %} + {%- endfor %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "Vx", Vx_e); + free(Vx_e); +{%- endif %} {%- if cost.cost_type_0 == "NONLINEAR_LS" %} ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "nls_y_fun", &capsule->cost_y_0_fun); ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "nls_y_fun_jac", &capsule->cost_y_0_fun_jac_ut_xt); ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "nls_y_hess", &capsule->cost_y_0_hess); +{%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "conl_cost_fun", &capsule->conl_cost_0_fun); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "conl_cost_fun_jac_hess", &capsule->conl_cost_0_fun_jac_hess); {%- elif cost.cost_type_0 == "EXTERNAL" %} ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "ext_cost_fun", &capsule->ext_cost_0_fun); ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, 0, "ext_cost_fun_jac", &capsule->ext_cost_0_fun_jac); @@ -978,6 +1062,12 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "nls_y_fun_jac", &capsule->cost_y_fun_jac_ut_xt[i-1]); ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "nls_y_hess", &capsule->cost_y_hess[i-1]); } +{%- elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} + for (int i = 1; i < N; i++) + { + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "conl_cost_fun", &capsule->conl_cost_fun[i-1]); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, i, "conl_cost_fun_jac_hess", &capsule->conl_cost_fun_jac_hess[i-1]); + } {%- elif cost.cost_type == "EXTERNAL" %} for (int i = 1; i < N; i++) { @@ -987,7 +1077,25 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule } {%- endif %} +{%- if cost.cost_type_e == "NONLINEAR_LS" %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_fun", &capsule->cost_y_e_fun); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_fun_jac", &capsule->cost_y_e_fun_jac_ut_xt); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_hess", &capsule->cost_y_e_hess); + +{%- elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "conl_cost_fun", &capsule->conl_cost_e_fun); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "conl_cost_fun_jac_hess", &capsule->conl_cost_e_fun_jac_hess); + +{%- elif cost.cost_type_e == "EXTERNAL" %} + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun", &capsule->ext_cost_e_fun); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun_jac", &capsule->ext_cost_e_fun_jac); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun_jac_hess", &capsule->ext_cost_e_fun_jac_hess); +{%- endif %} + + {%- if dims.ns > 0 %} + // slacks double* zlumem = calloc(4*NS, sizeof(double)); double* Zl = zlumem+NS*0; double* Zu = zlumem+NS*1; @@ -1028,59 +1136,8 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule free(zlumem); {%- endif %} - // terminal cost -{%- if cost.cost_type_e == "LINEAR_LS" or cost.cost_type_e == "NONLINEAR_LS" %} - {%- if dims.ny_e > 0 %} - double* yref_e = calloc(NYN, sizeof(double)); - // change only the non-zero elements: - {%- for j in range(end=dims.ny_e) %} - {%- if cost.yref_e[j] != 0 %} - yref_e[{{ j }}] = {{ cost.yref_e[j] }}; - {%- endif %} - {%- endfor %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "yref", yref_e); - free(yref_e); - - double* W_e = calloc(NYN*NYN, sizeof(double)); - // change only the non-zero elements: - {%- for j in range(end=dims.ny_e) %} - {%- for k in range(end=dims.ny_e) %} - {%- if cost.W_e[j][k] != 0 %} - W_e[{{ j }}+(NYN) * {{ k }}] = {{ cost.W_e[j][k] }}; - {%- endif %} - {%- endfor %} - {%- endfor %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "W", W_e); - free(W_e); - - {%- if cost.cost_type_e == "LINEAR_LS" %} - double* Vx_e = calloc(NYN*NX, sizeof(double)); - // change only the non-zero elements: - {% for j in range(end=dims.ny_e) %} - {%- for k in range(end=dims.nx) %} - {%- if cost.Vx_e[j][k] != 0 %} - Vx_e[{{ j }}+(NYN) * {{ k }}] = {{ cost.Vx_e[j][k] }}; - {%- endif %} - {%- endfor %} - {%- endfor %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "Vx", Vx_e); - free(Vx_e); - {%- endif %} - - {%- if cost.cost_type_e == "NONLINEAR_LS" %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_fun", &capsule->cost_y_e_fun); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_fun_jac", &capsule->cost_y_e_fun_jac_ut_xt); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "nls_y_hess", &capsule->cost_y_e_hess); - {%- endif %} - {%- endif %}{# ny_e > 0 #} - -{%- elif cost.cost_type_e == "EXTERNAL" %} - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun", &capsule->ext_cost_e_fun); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun_jac", &capsule->ext_cost_e_fun_jac); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "ext_cost_fun_jac_hess", &capsule->ext_cost_e_fun_jac_hess); -{%- endif %} - {% if dims.ns_e > 0 %} + // slacks terminal double* zluemem = calloc(4*NSN, sizeof(double)); double* Zl_e = zluemem+NSN*0; double* Zu_e = zluemem+NSN*1; @@ -1185,7 +1242,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {%- endfor %} for (int i = 1; i < N; i++) - { + { ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, i, "idxsbx", idxsbx); ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, i, "lsbx", lsbx); ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, i, "usbx", usbx); @@ -1363,7 +1420,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {%- endif %} {% if dims.ng > 0 %} - // set up general constraints for stage 0 to N-1 + // set up general constraints for stage 0 to N-1 double* D = calloc(NG*NU, sizeof(double)); double* C = calloc(NG*NX, sizeof(double)); double* lug = calloc(2*NG, sizeof(double)); @@ -1427,7 +1484,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule uh[{{ i }}] = {{ constraints.uh[i] }}; {%- endif %} {%- endfor %} - + for (int i = 0; i < N; i++) { // nonlinear constraints for stages 0 to N-1 @@ -1599,16 +1656,16 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {% endif %} {% if dims.ng_e > 0 %} - // set up general constraints for last stage + // set up general constraints for last stage double* C_e = calloc(NGN*NX, sizeof(double)); double* lug_e = calloc(2*NGN, sizeof(double)); double* lg_e = lug_e; double* ug_e = lug_e + NGN; - {% for j in range(end=dims.ng) %} + {% for j in range(end=dims.ng_e) %} {%- for k in range(end=dims.nx) %} {%- if constraints.C_e[j][k] != 0 %} - C_e[{{ j }}+NG * {{ k }}] = {{ constraints.C_e[j][k] }}; + C_e[{{ j }}+NGN * {{ k }}] = {{ constraints.C_e[j][k] }}; {%- endif %} {%- endfor %} {%- endfor %} @@ -1658,7 +1715,7 @@ void {{ model.name }}_acados_create_5_set_nlp_in({{ model.name }}_solver_capsule {%- endif %} {% if dims.nphi_e > 0 and constraints.constr_type_e == "BGP" %} - // set up convex-over-nonlinear constraints for last stage + // set up convex-over-nonlinear constraints for last stage double* luphi_e = calloc(2*NPHIN, sizeof(double)); double* lphi_e = luphi_e; double* uphi_e = luphi_e + NPHIN; @@ -1687,7 +1744,6 @@ void {{ model.name }}_acados_create_6_set_opts({{ model.name }}_solver_capsule* { const int N = capsule->nlp_solver_plan->N; ocp_nlp_config* nlp_config = capsule->nlp_config; - ocp_nlp_dims* nlp_dims = capsule->nlp_dims; void *nlp_opts = capsule->nlp_opts; /************************************************ @@ -1695,12 +1751,9 @@ void {{ model.name }}_acados_create_6_set_opts({{ model.name }}_solver_capsule* ************************************************/ {% if solver_options.hessian_approx == "EXACT" %} - bool nlp_solver_exact_hessian = true; - // TODO: this if should not be needed! however, calling the setter with false leads to weird behavior. Investigate! - if (nlp_solver_exact_hessian) - { - ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "exact_hess", &nlp_solver_exact_hessian); - } + int nlp_solver_exact_hessian = 1; + ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "exact_hess", &nlp_solver_exact_hessian); + int exact_hess_dyn = {{ solver_options.exact_hess_dyn }}; ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "exact_hess_dyn", &exact_hess_dyn); @@ -1861,6 +1914,8 @@ void {{ model.name }}_acados_create_6_set_opts({{ model.name }}_solver_capsule* ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "qp_cond_N", &qp_solver_cond_N); {%- endif %} + int nlp_solver_ext_qp_res = {{ solver_options.nlp_solver_ext_qp_res }}; + ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "ext_qp_res", &nlp_solver_ext_qp_res); {%- if solver_options.qp_solver is containing("HPIPM") %} // set HPIPM mode: should be done before setting other QP solver options @@ -1920,6 +1975,15 @@ void {{ model.name }}_acados_create_6_set_opts({{ model.name }}_solver_capsule* int print_level = {{ solver_options.print_level }}; ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "print_level", &print_level); +{%- if solver_options.qp_solver is containing('PARTIAL_CONDENSING') %} + int qp_solver_cond_ric_alg = {{ solver_options.qp_solver_cond_ric_alg }}; + ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "qp_cond_ric_alg", &qp_solver_cond_ric_alg); +{% endif %} + +{%- if solver_options.qp_solver == 'PARTIAL_CONDENSING_HPIPM' %} + int qp_solver_ric_alg = {{ solver_options.qp_solver_ric_alg }}; + ocp_nlp_solver_opts_set(nlp_config, nlp_opts, "qp_ric_alg", &qp_solver_ric_alg); +{% endif %} int ext_cost_num_hess = {{ solver_options.ext_cost_num_hess }}; {%- if cost.cost_type == "EXTERNAL" %} @@ -2042,6 +2106,12 @@ int {{ model.name }}_acados_create_with_discretization({{ model.name }}_solver_c // 9) do precomputations int status = {{ model.name }}_acados_create_9_precompute(capsule); + + {%- if custom_update_filename != "" %} + // Initialize custom update function + custom_update_init_function(capsule); + {%- endif %} + return status; } @@ -2076,7 +2146,7 @@ int {{ model.name }}_acados_update_qp_solver_cond_N({{ model.name }}_solver_caps } -int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule) +int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule, int reset_qp_solver_mem) { // set initialization to all zeros @@ -2088,8 +2158,6 @@ int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule) ocp_nlp_in* nlp_in = capsule->nlp_in; ocp_nlp_solver* nlp_solver = capsule->nlp_solver; - int nx, nu, nv, ns, nz, ni, dim; - double* buffer = calloc(NX+NU+NZ+2*NS+2*NSN+NBX+NBU+NG+NH+NPHI+NBX0+NBXN+NHN+NPHIN+NGN, sizeof(double)); for(int i=0; i reset memory int qp_status; ocp_nlp_get(capsule->nlp_config, capsule->nlp_solver, "qp_status", &qp_status); - if (qp_status == 3) + if (reset_qp_solver_mem || (qp_status == 3)) { // printf("\nin reset qp_status %d -> resetting QP memory\n", qp_status); ocp_nlp_solver_reset_qp_memory(nlp_solver, nlp_in, nlp_out); @@ -2144,7 +2212,6 @@ int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule* capsu exit(1); } -{%- if dims.np > 0 %} const int N = capsule->nlp_solver_plan->N; if (stage < N && stage >= 0) { @@ -2201,6 +2268,9 @@ int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule* capsu capsule->cost_y_0_fun.set_param(&capsule->cost_y_0_fun, p); capsule->cost_y_0_fun_jac_ut_xt.set_param(&capsule->cost_y_0_fun_jac_ut_xt, p); capsule->cost_y_0_hess.set_param(&capsule->cost_y_0_hess, p); + {%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_0_fun.set_param(&capsule->conl_cost_0_fun, p); + capsule->conl_cost_0_fun_jac_hess.set_param(&capsule->conl_cost_0_fun_jac_hess, p); {%- elif cost.cost_type_0 == "EXTERNAL" %} capsule->ext_cost_0_fun.set_param(&capsule->ext_cost_0_fun, p); capsule->ext_cost_0_fun_jac.set_param(&capsule->ext_cost_0_fun_jac, p); @@ -2213,6 +2283,9 @@ int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule* capsu capsule->cost_y_fun[stage-1].set_param(capsule->cost_y_fun+stage-1, p); capsule->cost_y_fun_jac_ut_xt[stage-1].set_param(capsule->cost_y_fun_jac_ut_xt+stage-1, p); capsule->cost_y_hess[stage-1].set_param(capsule->cost_y_hess+stage-1, p); + {%- elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_fun[stage-1].set_param(capsule->conl_cost_fun+stage-1, p); + capsule->conl_cost_fun_jac_hess[stage-1].set_param(capsule->conl_cost_fun_jac_hess+stage-1, p); {%- elif cost.cost_type == "EXTERNAL" %} capsule->ext_cost_fun[stage-1].set_param(capsule->ext_cost_fun+stage-1, p); capsule->ext_cost_fun_jac[stage-1].set_param(capsule->ext_cost_fun_jac+stage-1, p); @@ -2229,6 +2302,9 @@ int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule* capsu capsule->cost_y_e_fun.set_param(&capsule->cost_y_e_fun, p); capsule->cost_y_e_fun_jac_ut_xt.set_param(&capsule->cost_y_e_fun_jac_ut_xt, p); capsule->cost_y_e_hess.set_param(&capsule->cost_y_e_hess, p); + {%- elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_e_fun.set_param(&capsule->conl_cost_e_fun, p); + capsule->conl_cost_e_fun_jac_hess.set_param(&capsule->conl_cost_e_fun_jac_hess, p); {%- elif cost.cost_type_e == "EXTERNAL" %} capsule->ext_cost_e_fun.set_param(&capsule->ext_cost_e_fun, p); capsule->ext_cost_e_fun_jac.set_param(&capsule->ext_cost_e_fun_jac, p); @@ -2245,16 +2321,149 @@ int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule* capsu {%- endif %} {% endif %} } -{% endif %}{# if dims.np #} return solver_status; } +int {{ model.name }}_acados_update_params_sparse({{ model.name }}_solver_capsule * capsule, int stage, int *idx, double *p, int n_update) +{ + int solver_status = 0; + + int casadi_np = {{ dims.np }}; + if (casadi_np < n_update) { + printf("{{ model.name }}_acados_update_params_sparse: trying to set %d parameters for external functions." + " External function has %d parameters. Exiting.\n", n_update, casadi_np); + exit(1); + } + // for (int i = 0; i < n_update; i++) + // { + // if (idx[i] > casadi_np) { + // printf("{{ model.name }}_acados_update_params_sparse: attempt to set parameters with index %d, while" + // " external functions only has %d parameters. Exiting.\n", idx[i], casadi_np); + // exit(1); + // } + // printf("param %d value %e\n", idx[i], p[i]); + // } + +{%- if dims.np > 0 %} + const int N = capsule->nlp_solver_plan->N; + if (stage < N && stage >= 0) + { + {%- if solver_options.integrator_type == "IRK" %} + capsule->impl_dae_fun[stage].set_param_sparse(capsule->impl_dae_fun+stage, n_update, idx, p); + capsule->impl_dae_fun_jac_x_xdot_z[stage].set_param_sparse(capsule->impl_dae_fun_jac_x_xdot_z+stage, n_update, idx, p); + capsule->impl_dae_jac_x_xdot_u_z[stage].set_param_sparse(capsule->impl_dae_jac_x_xdot_u_z+stage, n_update, idx, p); + + {%- if solver_options.hessian_approx == "EXACT" %} + capsule->impl_dae_hess[stage].set_param_sparse(capsule->impl_dae_hess+stage, n_update, idx, p); + {%- endif %} + {% elif solver_options.integrator_type == "LIFTED_IRK" %} + capsule->impl_dae_fun[stage].set_param_sparse(capsule->impl_dae_fun+stage, n_update, idx, p); + capsule->impl_dae_fun_jac_x_xdot_u[stage].set_param_sparse(capsule->impl_dae_fun_jac_x_xdot_u+stage, n_update, idx, p); + {% elif solver_options.integrator_type == "ERK" %} + capsule->forw_vde_casadi[stage].set_param_sparse(capsule->forw_vde_casadi+stage, n_update, idx, p); + capsule->expl_ode_fun[stage].set_param_sparse(capsule->expl_ode_fun+stage, n_update, idx, p); + + {%- if solver_options.hessian_approx == "EXACT" %} + capsule->hess_vde_casadi[stage].set_param_sparse(capsule->hess_vde_casadi+stage, n_update, idx, p); + {%- endif %} + {% elif solver_options.integrator_type == "GNSF" %} + {% if model.gnsf.purely_linear != 1 %} + capsule->gnsf_phi_fun[stage].set_param_sparse(capsule->gnsf_phi_fun+stage, n_update, idx, p); + capsule->gnsf_phi_fun_jac_y[stage].set_param_sparse(capsule->gnsf_phi_fun_jac_y+stage, n_update, idx, p); + capsule->gnsf_phi_jac_y_uhat[stage].set_param_sparse(capsule->gnsf_phi_jac_y_uhat+stage, n_update, idx, p); + {% if model.gnsf.nontrivial_f_LO == 1 %} + capsule->gnsf_f_lo_jac_x1_x1dot_u_z[stage].set_param_sparse(capsule->gnsf_f_lo_jac_x1_x1dot_u_z+stage, n_update, idx, p); + {%- endif %} + {%- endif %} + {% elif solver_options.integrator_type == "DISCRETE" %} + capsule->discr_dyn_phi_fun[stage].set_param_sparse(capsule->discr_dyn_phi_fun+stage, n_update, idx, p); + capsule->discr_dyn_phi_fun_jac_ut_xt[stage].set_param_sparse(capsule->discr_dyn_phi_fun_jac_ut_xt+stage, n_update, idx, p); + {%- if solver_options.hessian_approx == "EXACT" %} + capsule->discr_dyn_phi_fun_jac_ut_xt_hess[stage].set_param_sparse(capsule->discr_dyn_phi_fun_jac_ut_xt_hess+stage, n_update, idx, p); + {% endif %} + {%- endif %}{# integrator_type #} + + // constraints + {% if constraints.constr_type == "BGP" %} + capsule->phi_constraint[stage].set_param_sparse(capsule->phi_constraint+stage, n_update, idx, p); + {% elif constraints.constr_type == "BGH" and dims.nh > 0 %} + capsule->nl_constr_h_fun_jac[stage].set_param_sparse(capsule->nl_constr_h_fun_jac+stage, n_update, idx, p); + capsule->nl_constr_h_fun[stage].set_param_sparse(capsule->nl_constr_h_fun+stage, n_update, idx, p); + {%- if solver_options.hessian_approx == "EXACT" %} + capsule->nl_constr_h_fun_jac_hess[stage].set_param_sparse(capsule->nl_constr_h_fun_jac_hess+stage, n_update, idx, p); + {%- endif %} + {%- endif %} + + // cost + if (stage == 0) + { + {%- if cost.cost_type_0 == "NONLINEAR_LS" %} + capsule->cost_y_0_fun.set_param_sparse(&capsule->cost_y_0_fun, n_update, idx, p); + capsule->cost_y_0_fun_jac_ut_xt.set_param_sparse(&capsule->cost_y_0_fun_jac_ut_xt, n_update, idx, p); + capsule->cost_y_0_hess.set_param_sparse(&capsule->cost_y_0_hess, n_update, idx, p); + {%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_0_fun.set_param_sparse(&capsule->conl_cost_0_fun, n_update, idx, p); + capsule->conl_cost_0_fun_jac_hess.set_param_sparse(&capsule->conl_cost_0_fun_jac_hess, n_update, idx, p); + {%- elif cost.cost_type_0 == "EXTERNAL" %} + capsule->ext_cost_0_fun.set_param_sparse(&capsule->ext_cost_0_fun, n_update, idx, p); + capsule->ext_cost_0_fun_jac.set_param_sparse(&capsule->ext_cost_0_fun_jac, n_update, idx, p); + capsule->ext_cost_0_fun_jac_hess.set_param_sparse(&capsule->ext_cost_0_fun_jac_hess, n_update, idx, p); + {% endif %} + } + else // 0 < stage < N + { + {%- if cost.cost_type == "NONLINEAR_LS" %} + capsule->cost_y_fun[stage-1].set_param_sparse(capsule->cost_y_fun+stage-1, n_update, idx, p); + capsule->cost_y_fun_jac_ut_xt[stage-1].set_param_sparse(capsule->cost_y_fun_jac_ut_xt+stage-1, n_update, idx, p); + capsule->cost_y_hess[stage-1].set_param_sparse(capsule->cost_y_hess+stage-1, n_update, idx, p); + {%- elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_fun[stage-1].set_param_sparse(capsule->conl_cost_fun+stage-1, n_update, idx, p); + capsule->conl_cost_fun_jac_hess[stage-1].set_param_sparse(capsule->conl_cost_fun_jac_hess+stage-1, n_update, idx, p); + {%- elif cost.cost_type == "EXTERNAL" %} + capsule->ext_cost_fun[stage-1].set_param_sparse(capsule->ext_cost_fun+stage-1, n_update, idx, p); + capsule->ext_cost_fun_jac[stage-1].set_param_sparse(capsule->ext_cost_fun_jac+stage-1, n_update, idx, p); + capsule->ext_cost_fun_jac_hess[stage-1].set_param_sparse(capsule->ext_cost_fun_jac_hess+stage-1, n_update, idx, p); + {%- endif %} + } + } + + else // stage == N + { + // terminal shooting node has no dynamics + // cost + {%- if cost.cost_type_e == "NONLINEAR_LS" %} + capsule->cost_y_e_fun.set_param_sparse(&capsule->cost_y_e_fun, n_update, idx, p); + capsule->cost_y_e_fun_jac_ut_xt.set_param_sparse(&capsule->cost_y_e_fun_jac_ut_xt, n_update, idx, p); + capsule->cost_y_e_hess.set_param_sparse(&capsule->cost_y_e_hess, n_update, idx, p); + {%- elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + capsule->conl_cost_e_fun.set_param_sparse(&capsule->conl_cost_e_fun, n_update, idx, p); + capsule->conl_cost_e_fun_jac_hess.set_param_sparse(&capsule->conl_cost_e_fun_jac_hess, n_update, idx, p); + {%- elif cost.cost_type_e == "EXTERNAL" %} + capsule->ext_cost_e_fun.set_param_sparse(&capsule->ext_cost_e_fun, n_update, idx, p); + capsule->ext_cost_e_fun_jac.set_param_sparse(&capsule->ext_cost_e_fun_jac, n_update, idx, p); + capsule->ext_cost_e_fun_jac_hess.set_param_sparse(&capsule->ext_cost_e_fun_jac_hess, n_update, idx, p); + {% endif %} + // constraints + {% if constraints.constr_type_e == "BGP" %} + capsule->phi_e_constraint.set_param_sparse(&capsule->phi_e_constraint, n_update, idx, p); + {% elif constraints.constr_type_e == "BGH" and dims.nh_e > 0 %} + capsule->nl_constr_h_e_fun_jac.set_param_sparse(&capsule->nl_constr_h_e_fun_jac, n_update, idx, p); + capsule->nl_constr_h_e_fun.set_param_sparse(&capsule->nl_constr_h_e_fun, n_update, idx, p); + {%- if solver_options.hessian_approx == "EXACT" %} + capsule->nl_constr_h_e_fun_jac_hess.set_param_sparse(&capsule->nl_constr_h_e_fun_jac_hess, n_update, idx, p); + {%- endif %} + {% endif %} + } +{% endif %}{# if dims.np #} + + return solver_status; +} int {{ model.name }}_acados_solve({{ model.name }}_solver_capsule* capsule) { - // solve NLP + // solve NLP int solver_status = ocp_nlp_solve(capsule->nlp_solver, capsule->nlp_in, capsule->nlp_out); return solver_status; @@ -2265,6 +2474,9 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) { // before destroying, keep some info const int N = capsule->nlp_solver_plan->N; + {%- if custom_update_filename != "" %} + custom_update_terminate_function(capsule); + {%- endif %} // free memory ocp_nlp_solver_opts_destroy(capsule->nlp_opts); ocp_nlp_in_destroy(capsule->nlp_in); @@ -2280,11 +2492,11 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) {%- if solver_options.integrator_type == "IRK" %} for (int i = 0; i < N; i++) { - external_function_param_casadi_free(&capsule->impl_dae_fun[i]); - external_function_param_casadi_free(&capsule->impl_dae_fun_jac_x_xdot_z[i]); - external_function_param_casadi_free(&capsule->impl_dae_jac_x_xdot_u_z[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_fun[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_fun_jac_x_xdot_z[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_jac_x_xdot_u_z[i]); {%- if solver_options.hessian_approx == "EXACT" %} - external_function_param_casadi_free(&capsule->impl_dae_hess[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_hess[i]); {%- endif %} } free(capsule->impl_dae_fun); @@ -2297,8 +2509,8 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) {%- elif solver_options.integrator_type == "LIFTED_IRK" %} for (int i = 0; i < N; i++) { - external_function_param_casadi_free(&capsule->impl_dae_fun[i]); - external_function_param_casadi_free(&capsule->impl_dae_fun_jac_x_xdot_u[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_fun[i]); + external_function_param_{{ model.dyn_ext_fun_type }}_free(&capsule->impl_dae_fun_jac_x_xdot_u[i]); } free(capsule->impl_dae_fun); free(capsule->impl_dae_fun_jac_x_xdot_u); @@ -2354,7 +2566,7 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) {%- if solver_options.hessian_approx == "EXACT" %} free(capsule->discr_dyn_phi_fun_jac_ut_xt_hess); {%- endif %} - + {%- endif %} // cost @@ -2362,6 +2574,9 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) external_function_param_casadi_free(&capsule->cost_y_0_fun); external_function_param_casadi_free(&capsule->cost_y_0_fun_jac_ut_xt); external_function_param_casadi_free(&capsule->cost_y_0_hess); +{%- elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + external_function_param_casadi_free(&capsule->conl_cost_0_fun); + external_function_param_casadi_free(&capsule->conl_cost_0_fun_jac_hess); {%- elif cost.cost_type_0 == "EXTERNAL" %} external_function_param_{{ cost.cost_ext_fun_type_0 }}_free(&capsule->ext_cost_0_fun); external_function_param_{{ cost.cost_ext_fun_type_0 }}_free(&capsule->ext_cost_0_fun_jac); @@ -2377,6 +2592,14 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) free(capsule->cost_y_fun); free(capsule->cost_y_fun_jac_ut_xt); free(capsule->cost_y_hess); +{%- elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} + for (int i = 0; i < N - 1; i++) + { + external_function_param_casadi_free(&capsule->conl_cost_fun[i]); + external_function_param_casadi_free(&capsule->conl_cost_fun_jac_hess[i]); + } + free(capsule->conl_cost_fun); + free(capsule->conl_cost_fun_jac_hess); {%- elif cost.cost_type == "EXTERNAL" %} for (int i = 0; i < N - 1; i++) { @@ -2392,6 +2615,9 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) external_function_param_casadi_free(&capsule->cost_y_e_fun); external_function_param_casadi_free(&capsule->cost_y_e_fun_jac_ut_xt); external_function_param_casadi_free(&capsule->cost_y_e_hess); +{%- elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + external_function_param_casadi_free(&capsule->conl_cost_e_fun); + external_function_param_casadi_free(&capsule->conl_cost_e_fun_jac_hess); {%- elif cost.cost_type_e == "EXTERNAL" %} external_function_param_{{ cost.cost_ext_fun_type_e }}_free(&capsule->ext_cost_e_fun); external_function_param_{{ cost.cost_ext_fun_type_e }}_free(&capsule->ext_cost_e_fun_jac); @@ -2438,15 +2664,6 @@ int {{ model.name }}_acados_free({{ model.name }}_solver_capsule* capsule) return 0; } -ocp_nlp_in *{{ model.name }}_acados_get_nlp_in({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_in; } -ocp_nlp_out *{{ model.name }}_acados_get_nlp_out({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_out; } -ocp_nlp_out *{{ model.name }}_acados_get_sens_out({{ model.name }}_solver_capsule* capsule) { return capsule->sens_out; } -ocp_nlp_solver *{{ model.name }}_acados_get_nlp_solver({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_solver; } -ocp_nlp_config *{{ model.name }}_acados_get_nlp_config({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_config; } -void *{{ model.name }}_acados_get_nlp_opts({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_opts; } -ocp_nlp_dims *{{ model.name }}_acados_get_nlp_dims({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_dims; } -ocp_nlp_plan_t *{{ model.name }}_acados_get_nlp_plan({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_solver_plan; } - void {{ model.name }}_acados_print_stats({{ model.name }}_solver_capsule* capsule) { @@ -2461,8 +2678,13 @@ void {{ model.name }}_acados_print_stats({{ model.name }}_solver_capsule* capsul int nrow = sqp_iter+1 < stat_m ? sqp_iter+1 : stat_m; + printf("iter\tres_stat\tres_eq\t\tres_ineq\tres_comp\tqp_stat\tqp_iter\talpha"); + if (stat_n > 8) + printf("\t\tqp_res_stat\tqp_res_eq\tqp_res_ineq\tqp_res_comp"); + printf("\n"); + {%- if solver_options.nlp_solver_type == "SQP" %} - printf("iter\tres_stat\tres_eq\t\tres_ineq\tres_comp\tqp_stat\tqp_iter\talpha\n"); + for (int i = 0; i < nrow; i++) { for (int j = 0; j < stat_n + 1; j++) @@ -2493,3 +2715,27 @@ void {{ model.name }}_acados_print_stats({{ model.name }}_solver_capsule* capsul {%- endif %} } +int {{ model.name }}_acados_custom_update({{ model.name }}_solver_capsule* capsule, double* data, int data_len) +{ +{%- if custom_update_filename == "" %} + (void)capsule; + (void)data; + (void)data_len; + printf("\ndummy function that can be called in between solver calls to update parameters or numerical data efficiently in C.\n"); + printf("nothing set yet..\n"); + return 1; +{% else %} + custom_update_function(capsule, data, data_len); +{%- endif %} +} + + + +ocp_nlp_in *{{ model.name }}_acados_get_nlp_in({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_in; } +ocp_nlp_out *{{ model.name }}_acados_get_nlp_out({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_out; } +ocp_nlp_out *{{ model.name }}_acados_get_sens_out({{ model.name }}_solver_capsule* capsule) { return capsule->sens_out; } +ocp_nlp_solver *{{ model.name }}_acados_get_nlp_solver({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_solver; } +ocp_nlp_config *{{ model.name }}_acados_get_nlp_config({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_config; } +void *{{ model.name }}_acados_get_nlp_opts({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_opts; } +ocp_nlp_dims *{{ model.name }}_acados_get_nlp_dims({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_dims; } +ocp_nlp_plan_t *{{ model.name }}_acados_get_nlp_plan({{ model.name }}_solver_capsule* capsule) { return capsule->nlp_solver_plan; } diff --git a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.h b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.h index 1c82ef3ba0..5cf38aa8c8 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.h +++ b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -74,6 +71,12 @@ extern "C" { #endif +{%- if not solver_options.custom_update_filename %} + {%- set custom_update_filename = "" %} +{% else %} + {%- set custom_update_filename = solver_options.custom_update_filename %} +{%- endif %} + // ** capsule for solver data ** typedef struct {{ model.name }}_solver_capsule { @@ -99,15 +102,15 @@ typedef struct {{ model.name }}_solver_capsule external_function_param_casadi *hess_vde_casadi; {%- endif %} {% elif solver_options.integrator_type == "IRK" %} - external_function_param_casadi *impl_dae_fun; - external_function_param_casadi *impl_dae_fun_jac_x_xdot_z; - external_function_param_casadi *impl_dae_jac_x_xdot_u_z; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_fun; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_fun_jac_x_xdot_z; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_jac_x_xdot_u_z; {% if solver_options.hessian_approx == "EXACT" %} - external_function_param_casadi *impl_dae_hess; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_hess; {%- endif %} {% elif solver_options.integrator_type == "LIFTED_IRK" %} - external_function_param_casadi *impl_dae_fun; - external_function_param_casadi *impl_dae_fun_jac_x_xdot_u; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_fun; + external_function_param_{{ model.dyn_ext_fun_type }} *impl_dae_fun_jac_x_xdot_u; {% elif solver_options.integrator_type == "GNSF" %} external_function_param_casadi *gnsf_phi_fun; external_function_param_casadi *gnsf_phi_fun_jac_y; @@ -128,6 +131,9 @@ typedef struct {{ model.name }}_solver_capsule external_function_param_casadi *cost_y_fun; external_function_param_casadi *cost_y_fun_jac_ut_xt; external_function_param_casadi *cost_y_hess; +{% elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} + external_function_param_casadi *conl_cost_fun; + external_function_param_casadi *conl_cost_fun_jac_hess; {%- elif cost.cost_type == "EXTERNAL" %} external_function_param_{{ cost.cost_ext_fun_type }} *ext_cost_fun; external_function_param_{{ cost.cost_ext_fun_type }} *ext_cost_fun_jac; @@ -138,6 +144,9 @@ typedef struct {{ model.name }}_solver_capsule external_function_param_casadi cost_y_0_fun; external_function_param_casadi cost_y_0_fun_jac_ut_xt; external_function_param_casadi cost_y_0_hess; +{% elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + external_function_param_casadi conl_cost_0_fun; + external_function_param_casadi conl_cost_0_fun_jac_hess; {% elif cost.cost_type_0 == "EXTERNAL" %} external_function_param_{{ cost.cost_ext_fun_type_0 }} ext_cost_0_fun; external_function_param_{{ cost.cost_ext_fun_type_0 }} ext_cost_0_fun_jac; @@ -148,6 +157,9 @@ typedef struct {{ model.name }}_solver_capsule external_function_param_casadi cost_y_e_fun; external_function_param_casadi cost_y_e_fun_jac_ut_xt; external_function_param_casadi cost_y_e_hess; +{% elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} + external_function_param_casadi conl_cost_e_fun; + external_function_param_casadi conl_cost_e_fun_jac_hess; {% elif cost.cost_type_e == "EXTERNAL" %} external_function_param_{{ cost.cost_ext_fun_type_e }} ext_cost_e_fun; external_function_param_{{ cost.cost_ext_fun_type_e }} ext_cost_e_fun_jac; @@ -160,8 +172,10 @@ typedef struct {{ model.name }}_solver_capsule {% elif constraints.constr_type == "BGH" and dims.nh > 0 %} external_function_param_casadi *nl_constr_h_fun_jac; external_function_param_casadi *nl_constr_h_fun; +{%- if solver_options.hessian_approx == "EXACT" %} external_function_param_casadi *nl_constr_h_fun_jac_hess; {%- endif %} +{%- endif %} {% if constraints.constr_type_e == "BGP" %} @@ -169,8 +183,14 @@ typedef struct {{ model.name }}_solver_capsule {% elif constraints.constr_type_e == "BGH" and dims.nh_e > 0 %} external_function_param_casadi nl_constr_h_e_fun_jac; external_function_param_casadi nl_constr_h_e_fun; +{%- if solver_options.hessian_approx == "EXACT" %} external_function_param_casadi nl_constr_h_e_fun_jac_hess; {%- endif %} +{%- endif %} + +{%- if custom_update_filename != "" %} + void * custom_update_memory; +{%- endif %} } {{ model.name }}_solver_capsule; @@ -179,7 +199,7 @@ ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_free_capsule({{ model.name }}_s ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_create({{ model.name }}_solver_capsule * capsule); -ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule); +ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule, int reset_qp_solver_mem); /** * Generic version of {{ model.name }}_acados_create which allows to use a different number of shooting intervals than @@ -197,10 +217,14 @@ ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_time_steps({{ model.name */ ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_qp_solver_cond_N({{ model.name }}_solver_capsule * capsule, int qp_solver_cond_N); ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule * capsule, int stage, double *value, int np); +ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_params_sparse({{ model.name }}_solver_capsule * capsule, int stage, int *idx, double *p, int n_update); + ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_solve({{ model.name }}_solver_capsule * capsule); ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_free({{ model.name }}_solver_capsule * capsule); ACADOS_SYMBOL_EXPORT void {{ model.name }}_acados_print_stats({{ model.name }}_solver_capsule * capsule); - +ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_custom_update({{ model.name }}_solver_capsule* capsule, double* data, int data_len); + + ACADOS_SYMBOL_EXPORT ocp_nlp_in *{{ model.name }}_acados_get_nlp_in({{ model.name }}_solver_capsule * capsule); ACADOS_SYMBOL_EXPORT ocp_nlp_out *{{ model.name }}_acados_get_nlp_out({{ model.name }}_solver_capsule * capsule); ACADOS_SYMBOL_EXPORT ocp_nlp_out *{{ model.name }}_acados_get_sens_out({{ model.name }}_solver_capsule * capsule); diff --git a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.pxd b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.pxd index 09f8755cbe..233e3f79da 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_solver.in.pxd +++ b/third_party/acados/acados_template/c_templates_tera/acados_solver.in.pxd @@ -1,8 +1,5 @@ # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -47,11 +44,14 @@ cdef extern from "acados_solver_{{ model.name }}.h": int acados_update_qp_solver_cond_N "{{ model.name }}_acados_update_qp_solver_cond_N"(nlp_solver_capsule * capsule, int qp_solver_cond_N) int acados_update_params "{{ model.name }}_acados_update_params"(nlp_solver_capsule * capsule, int stage, double *value, int np_) + int acados_update_params_sparse "{{ model.name }}_acados_update_params_sparse"(nlp_solver_capsule * capsule, int stage, int *idx, double *p, int n_update) int acados_solve "{{ model.name }}_acados_solve"(nlp_solver_capsule * capsule) - int acados_reset "{{ model.name }}_acados_reset"(nlp_solver_capsule * capsule) + int acados_reset "{{ model.name }}_acados_reset"(nlp_solver_capsule * capsule, int reset_qp_solver_mem) int acados_free "{{ model.name }}_acados_free"(nlp_solver_capsule * capsule) void acados_print_stats "{{ model.name }}_acados_print_stats"(nlp_solver_capsule * capsule) + int acados_custom_update "{{ model.name }}_acados_custom_update"(nlp_solver_capsule* capsule, double * data, int data_len) + acados_solver_common.ocp_nlp_in *acados_get_nlp_in "{{ model.name }}_acados_get_nlp_in"(nlp_solver_capsule * capsule) acados_solver_common.ocp_nlp_out *acados_get_nlp_out "{{ model.name }}_acados_get_nlp_out"(nlp_solver_capsule * capsule) acados_solver_common.ocp_nlp_out *acados_get_sens_out "{{ model.name }}_acados_get_sens_out"(nlp_solver_capsule * capsule) diff --git a/third_party/acados/acados_template/c_templates_tera/h_e_constraint.in.h b/third_party/acados/acados_template/c_templates_tera/constraints.in.h similarity index 54% rename from third_party/acados/acados_template/c_templates_tera/h_e_constraint.in.h rename to third_party/acados/acados_template/c_templates_tera/constraints.in.h index a5dd711641..d71ce5cc22 100644 --- a/third_party/acados/acados_template/c_templates_tera/h_e_constraint.in.h +++ b/third_party/acados/acados_template/c_templates_tera/constraints.in.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -31,14 +28,56 @@ * POSSIBILITY OF SUCH DAMAGE.; */ - -#ifndef {{ model.name }}_H_E_CONSTRAINT -#define {{ model.name }}_H_E_CONSTRAINT +#ifndef {{ model.name }}_CONSTRAINTS +#define {{ model.name }}_CONSTRAINTS #ifdef __cplusplus extern "C" { #endif +{% if dims.nphi > 0 %} +int {{ model.name }}_phi_constraint(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_phi_constraint_work(int *, int *, int *, int *); +const int *{{ model.name }}_phi_constraint_sparsity_in(int); +const int *{{ model.name }}_phi_constraint_sparsity_out(int); +int {{ model.name }}_phi_constraint_n_in(void); +int {{ model.name }}_phi_constraint_n_out(void); +{% endif %} + +{% if dims.nphi_e > 0 %} +int {{ model.name }}_phi_e_constraint(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_phi_e_constraint_work(int *, int *, int *, int *); +const int *{{ model.name }}_phi_e_constraint_sparsity_in(int); +const int *{{ model.name }}_phi_e_constraint_sparsity_out(int); +int {{ model.name }}_phi_e_constraint_n_in(void); +int {{ model.name }}_phi_e_constraint_n_out(void); +{% endif %} + +{% if dims.nh > 0 %} +int {{ model.name }}_constr_h_fun_jac_uxt_zt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_work(int *, int *, int *, int *); +const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_sparsity_in(int); +const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_sparsity_out(int); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_n_in(void); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_n_out(void); + +int {{ model.name }}_constr_h_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_constr_h_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_constr_h_fun_sparsity_in(int); +const int *{{ model.name }}_constr_h_fun_sparsity_out(int); +int {{ model.name }}_constr_h_fun_n_in(void); +int {{ model.name }}_constr_h_fun_n_out(void); + +{% if solver_options.hessian_approx == "EXACT" -%} +int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_hess_sparsity_in(int); +const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_hess_sparsity_out(int); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_n_in(void); +int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_n_out(void); +{% endif %} +{% endif %} + {% if dims.nh_e > 0 %} int {{ model.name }}_constr_h_e_fun_jac_uxt_zt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); int {{ model.name }}_constr_h_e_fun_jac_uxt_zt_work(int *, int *, int *, int *); @@ -68,4 +107,4 @@ int {{ model.name }}_constr_h_e_fun_jac_uxt_zt_hess_n_out(void); } /* extern "C" */ #endif -#endif // {{ model.name }}_H_E_CONSTRAINT +#endif // {{ model.name }}_CONSTRAINTS diff --git a/third_party/acados/acados_template/c_templates_tera/cost.in.h b/third_party/acados/acados_template/c_templates_tera/cost.in.h new file mode 100644 index 0000000000..45eb09c12e --- /dev/null +++ b/third_party/acados/acados_template/c_templates_tera/cost.in.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) The acados authors. + * + * This file is part of acados. + * + * The 2-Clause BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.; + */ + + +#ifndef {{ model.name }}_COST +#define {{ model.name }}_COST + +#ifdef __cplusplus +extern "C" { +#endif + + +// Cost at initial shooting node +{% if cost.cost_type_0 == "NONLINEAR_LS" %} +int {{ model.name }}_cost_y_0_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_0_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_0_fun_sparsity_in(int); +const int *{{ model.name }}_cost_y_0_fun_sparsity_out(int); +int {{ model.name }}_cost_y_0_fun_n_in(void); +int {{ model.name }}_cost_y_0_fun_n_out(void); + +int {{ model.name }}_cost_y_0_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_0_fun_jac_ut_xt_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_0_fun_jac_ut_xt_sparsity_in(int); +const int *{{ model.name }}_cost_y_0_fun_jac_ut_xt_sparsity_out(int); +int {{ model.name }}_cost_y_0_fun_jac_ut_xt_n_in(void); +int {{ model.name }}_cost_y_0_fun_jac_ut_xt_n_out(void); + +int {{ model.name }}_cost_y_0_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_0_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_0_hess_sparsity_in(int); +const int *{{ model.name }}_cost_y_0_hess_sparsity_out(int); +int {{ model.name }}_cost_y_0_hess_n_in(void); +int {{ model.name }}_cost_y_0_hess_n_out(void); +{% elif cost.cost_type_0 == "CONVEX_OVER_NONLINEAR" %} + +int {{ model.name }}_conl_cost_0_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_0_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_0_fun_sparsity_in(int); +const int *{{ model.name }}_conl_cost_0_fun_sparsity_out(int); +int {{ model.name }}_conl_cost_0_fun_n_in(void); +int {{ model.name }}_conl_cost_0_fun_n_out(void); + +int {{ model.name }}_conl_cost_0_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_0_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_0_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_conl_cost_0_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_conl_cost_0_fun_jac_hess_n_in(void); +int {{ model.name }}_conl_cost_0_fun_jac_hess_n_out(void); + +{% elif cost.cost_type_0 == "EXTERNAL" %} + {%- if cost.cost_ext_fun_type_0 == "casadi" %} +int {{ model.name }}_cost_ext_cost_0_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_0_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_0_fun_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_0_fun_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_0_fun_n_in(void); +int {{ model.name }}_cost_ext_cost_0_fun_n_out(void); + +int {{ model.name }}_cost_ext_cost_0_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_0_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_0_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_n_in(void); +int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_n_out(void); + +int {{ model.name }}_cost_ext_cost_0_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_0_fun_jac_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_0_fun_jac_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_0_fun_jac_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_0_fun_jac_n_in(void); +int {{ model.name }}_cost_ext_cost_0_fun_jac_n_out(void); + {%- else %} +int {{ cost.cost_function_ext_cost_0 }}(void **, void **, void *); + {%- endif %} +{% endif %} + + +// Cost at path shooting node +{% if cost.cost_type == "NONLINEAR_LS" %} +int {{ model.name }}_cost_y_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_fun_sparsity_in(int); +const int *{{ model.name }}_cost_y_fun_sparsity_out(int); +int {{ model.name }}_cost_y_fun_n_in(void); +int {{ model.name }}_cost_y_fun_n_out(void); + +int {{ model.name }}_cost_y_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_fun_jac_ut_xt_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_fun_jac_ut_xt_sparsity_in(int); +const int *{{ model.name }}_cost_y_fun_jac_ut_xt_sparsity_out(int); +int {{ model.name }}_cost_y_fun_jac_ut_xt_n_in(void); +int {{ model.name }}_cost_y_fun_jac_ut_xt_n_out(void); + +int {{ model.name }}_cost_y_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_hess_sparsity_in(int); +const int *{{ model.name }}_cost_y_hess_sparsity_out(int); +int {{ model.name }}_cost_y_hess_n_in(void); +int {{ model.name }}_cost_y_hess_n_out(void); + +{% elif cost.cost_type == "CONVEX_OVER_NONLINEAR" %} +int {{ model.name }}_conl_cost_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_fun_sparsity_in(int); +const int *{{ model.name }}_conl_cost_fun_sparsity_out(int); +int {{ model.name }}_conl_cost_fun_n_in(void); +int {{ model.name }}_conl_cost_fun_n_out(void); + +int {{ model.name }}_conl_cost_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_conl_cost_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_conl_cost_fun_jac_hess_n_in(void); +int {{ model.name }}_conl_cost_fun_jac_hess_n_out(void); +{% elif cost.cost_type == "EXTERNAL" %} + {%- if cost.cost_ext_fun_type == "casadi" %} +int {{ model.name }}_cost_ext_cost_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_fun_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_fun_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_fun_n_in(void); +int {{ model.name }}_cost_ext_cost_fun_n_out(void); + +int {{ model.name }}_cost_ext_cost_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_fun_jac_hess_n_in(void); +int {{ model.name }}_cost_ext_cost_fun_jac_hess_n_out(void); + +int {{ model.name }}_cost_ext_cost_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_fun_jac_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_fun_jac_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_fun_jac_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_fun_jac_n_in(void); +int {{ model.name }}_cost_ext_cost_fun_jac_n_out(void); + {%- else %} +int {{ cost.cost_function_ext_cost }}(void **, void **, void *); + {%- endif %} +{% endif %} + +// Cost at terminal shooting node +{% if cost.cost_type_e == "NONLINEAR_LS" %} +int {{ model.name }}_cost_y_e_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_e_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_e_fun_sparsity_in(int); +const int *{{ model.name }}_cost_y_e_fun_sparsity_out(int); +int {{ model.name }}_cost_y_e_fun_n_in(void); +int {{ model.name }}_cost_y_e_fun_n_out(void); + +int {{ model.name }}_cost_y_e_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_e_fun_jac_ut_xt_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_e_fun_jac_ut_xt_sparsity_in(int); +const int *{{ model.name }}_cost_y_e_fun_jac_ut_xt_sparsity_out(int); +int {{ model.name }}_cost_y_e_fun_jac_ut_xt_n_in(void); +int {{ model.name }}_cost_y_e_fun_jac_ut_xt_n_out(void); + +int {{ model.name }}_cost_y_e_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_y_e_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_y_e_hess_sparsity_in(int); +const int *{{ model.name }}_cost_y_e_hess_sparsity_out(int); +int {{ model.name }}_cost_y_e_hess_n_in(void); +int {{ model.name }}_cost_y_e_hess_n_out(void); +{% elif cost.cost_type_e == "CONVEX_OVER_NONLINEAR" %} +int {{ model.name }}_conl_cost_e_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_e_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_e_fun_sparsity_in(int); +const int *{{ model.name }}_conl_cost_e_fun_sparsity_out(int); +int {{ model.name }}_conl_cost_e_fun_n_in(void); +int {{ model.name }}_conl_cost_e_fun_n_out(void); + +int {{ model.name }}_conl_cost_e_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_conl_cost_e_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_conl_cost_e_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_conl_cost_e_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_conl_cost_e_fun_jac_hess_n_in(void); +int {{ model.name }}_conl_cost_e_fun_jac_hess_n_out(void); +{% elif cost.cost_type_e == "EXTERNAL" %} + {%- if cost.cost_ext_fun_type_e == "casadi" %} +int {{ model.name }}_cost_ext_cost_e_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_e_fun_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_e_fun_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_e_fun_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_e_fun_n_in(void); +int {{ model.name }}_cost_ext_cost_e_fun_n_out(void); + +int {{ model.name }}_cost_ext_cost_e_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_e_fun_jac_hess_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_e_fun_jac_hess_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_n_in(void); +int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_n_out(void); + +int {{ model.name }}_cost_ext_cost_e_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); +int {{ model.name }}_cost_ext_cost_e_fun_jac_work(int *, int *, int *, int *); +const int *{{ model.name }}_cost_ext_cost_e_fun_jac_sparsity_in(int); +const int *{{ model.name }}_cost_ext_cost_e_fun_jac_sparsity_out(int); +int {{ model.name }}_cost_ext_cost_e_fun_jac_n_in(void); +int {{ model.name }}_cost_ext_cost_e_fun_jac_n_out(void); + {%- else %} +int {{ cost.cost_function_ext_cost_e }}(void **, void **, void *); + {%- endif %} +{% endif %} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // {{ model.name }}_COST diff --git a/third_party/acados/acados_template/c_templates_tera/cost_y_0_fun.in.h b/third_party/acados/acados_template/c_templates_tera/cost_y_0_fun.in.h deleted file mode 100644 index 347446e3f4..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/cost_y_0_fun.in.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_Y_0_COST -#define {{ model.name }}_Y_0_COST - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_type_0 == "NONLINEAR_LS" %} -int {{ model.name }}_cost_y_0_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_0_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_0_fun_sparsity_in(int); -const int *{{ model.name }}_cost_y_0_fun_sparsity_out(int); -int {{ model.name }}_cost_y_0_fun_n_in(void); -int {{ model.name }}_cost_y_0_fun_n_out(void); - -int {{ model.name }}_cost_y_0_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_0_fun_jac_ut_xt_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_0_fun_jac_ut_xt_sparsity_in(int); -const int *{{ model.name }}_cost_y_0_fun_jac_ut_xt_sparsity_out(int); -int {{ model.name }}_cost_y_0_fun_jac_ut_xt_n_in(void); -int {{ model.name }}_cost_y_0_fun_jac_ut_xt_n_out(void); - -int {{ model.name }}_cost_y_0_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_0_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_0_hess_sparsity_in(int); -const int *{{ model.name }}_cost_y_0_hess_sparsity_out(int); -int {{ model.name }}_cost_y_0_hess_n_in(void); -int {{ model.name }}_cost_y_0_hess_n_out(void); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_Y_0_COST diff --git a/third_party/acados/acados_template/c_templates_tera/cost_y_e_fun.in.h b/third_party/acados/acados_template/c_templates_tera/cost_y_e_fun.in.h deleted file mode 100644 index acc99009fe..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/cost_y_e_fun.in.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_Y_E_COST -#define {{ model.name }}_Y_E_COST - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_type_e == "NONLINEAR_LS" %} -int {{ model.name }}_cost_y_e_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_e_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_e_fun_sparsity_in(int); -const int *{{ model.name }}_cost_y_e_fun_sparsity_out(int); -int {{ model.name }}_cost_y_e_fun_n_in(void); -int {{ model.name }}_cost_y_e_fun_n_out(void); - -int {{ model.name }}_cost_y_e_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_e_fun_jac_ut_xt_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_e_fun_jac_ut_xt_sparsity_in(int); -const int *{{ model.name }}_cost_y_e_fun_jac_ut_xt_sparsity_out(int); -int {{ model.name }}_cost_y_e_fun_jac_ut_xt_n_in(void); -int {{ model.name }}_cost_y_e_fun_jac_ut_xt_n_out(void); - -int {{ model.name }}_cost_y_e_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_e_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_e_hess_sparsity_in(int); -const int *{{ model.name }}_cost_y_e_hess_sparsity_out(int); -int {{ model.name }}_cost_y_e_hess_n_in(void); -int {{ model.name }}_cost_y_e_hess_n_out(void); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_Y_E_COST diff --git a/third_party/acados/acados_template/c_templates_tera/cost_y_fun.in.h b/third_party/acados/acados_template/c_templates_tera/cost_y_fun.in.h deleted file mode 100644 index 1e03780cc1..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/cost_y_fun.in.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_Y_COST -#define {{ model.name }}_Y_COST - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_type == "NONLINEAR_LS" %} -int {{ model.name }}_cost_y_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_fun_sparsity_in(int); -const int *{{ model.name }}_cost_y_fun_sparsity_out(int); -int {{ model.name }}_cost_y_fun_n_in(void); -int {{ model.name }}_cost_y_fun_n_out(void); - -int {{ model.name }}_cost_y_fun_jac_ut_xt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_fun_jac_ut_xt_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_fun_jac_ut_xt_sparsity_in(int); -const int *{{ model.name }}_cost_y_fun_jac_ut_xt_sparsity_out(int); -int {{ model.name }}_cost_y_fun_jac_ut_xt_n_in(void); -int {{ model.name }}_cost_y_fun_jac_ut_xt_n_out(void); - -int {{ model.name }}_cost_y_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_y_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_y_hess_sparsity_in(int); -const int *{{ model.name }}_cost_y_hess_sparsity_out(int); -int {{ model.name }}_cost_y_hess_n_in(void); -int {{ model.name }}_cost_y_hess_n_out(void); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_Y_COST diff --git a/third_party/acados/acados_template/c_templates_tera/external_cost.in.h b/third_party/acados/acados_template/c_templates_tera/external_cost.in.h deleted file mode 100644 index d200dba45e..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/external_cost.in.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_EXT_COST -#define {{ model.name }}_EXT_COST - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_ext_fun_type == "casadi" %} -{% if cost.cost_type == "EXTERNAL" %} -int {{ model.name }}_cost_ext_cost_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_fun_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_fun_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_fun_n_in(void); -int {{ model.name }}_cost_ext_cost_fun_n_out(void); - -int {{ model.name }}_cost_ext_cost_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_fun_jac_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_fun_jac_hess_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_fun_jac_hess_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_fun_jac_hess_n_in(void); -int {{ model.name }}_cost_ext_cost_fun_jac_hess_n_out(void); - -int {{ model.name }}_cost_ext_cost_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_fun_jac_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_fun_jac_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_fun_jac_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_fun_jac_n_in(void); -int {{ model.name }}_cost_ext_cost_fun_jac_n_out(void); -{% endif %} - -{% else %} -int {{ cost.cost_function_ext_cost }}(void **, void **, void *); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_EXT_COST diff --git a/third_party/acados/acados_template/c_templates_tera/external_cost_0.in.h b/third_party/acados/acados_template/c_templates_tera/external_cost_0.in.h deleted file mode 100644 index 8152447e5f..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/external_cost_0.in.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_EXT_COST_0 -#define {{ model.name }}_EXT_COST_0 - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_ext_fun_type_0 == "casadi" %} - -{% if cost.cost_type_0 == "EXTERNAL" %} -int {{ model.name }}_cost_ext_cost_0_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_0_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_0_fun_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_0_fun_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_0_fun_n_in(void); -int {{ model.name }}_cost_ext_cost_0_fun_n_out(void); - -int {{ model.name }}_cost_ext_cost_0_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_0_fun_jac_hess_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_0_fun_jac_hess_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_n_in(void); -int {{ model.name }}_cost_ext_cost_0_fun_jac_hess_n_out(void); - -int {{ model.name }}_cost_ext_cost_0_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_0_fun_jac_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_0_fun_jac_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_0_fun_jac_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_0_fun_jac_n_in(void); -int {{ model.name }}_cost_ext_cost_0_fun_jac_n_out(void); -{% endif %} - -{% else %} -int {{ cost.cost_function_ext_cost_0 }}(void **, void **, void *); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_EXT_COST_0 diff --git a/third_party/acados/acados_template/c_templates_tera/external_cost_e.in.h b/third_party/acados/acados_template/c_templates_tera/external_cost_e.in.h deleted file mode 100644 index 56485db4c7..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/external_cost_e.in.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - - -#ifndef {{ model.name }}_EXT_COST_E -#define {{ model.name }}_EXT_COST_E - -#ifdef __cplusplus -extern "C" { -#endif - -{% if cost.cost_ext_fun_type_e == "casadi" %} -{% if cost.cost_type_e == "EXTERNAL" %} -int {{ model.name }}_cost_ext_cost_e_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_e_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_e_fun_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_e_fun_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_e_fun_n_in(void); -int {{ model.name }}_cost_ext_cost_e_fun_n_out(void); - -int {{ model.name }}_cost_ext_cost_e_fun_jac_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_e_fun_jac_hess_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_e_fun_jac_hess_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_n_in(void); -int {{ model.name }}_cost_ext_cost_e_fun_jac_hess_n_out(void); - -int {{ model.name }}_cost_ext_cost_e_fun_jac(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_cost_ext_cost_e_fun_jac_work(int *, int *, int *, int *); -const int *{{ model.name }}_cost_ext_cost_e_fun_jac_sparsity_in(int); -const int *{{ model.name }}_cost_ext_cost_e_fun_jac_sparsity_out(int); -int {{ model.name }}_cost_ext_cost_e_fun_jac_n_in(void); -int {{ model.name }}_cost_ext_cost_e_fun_jac_n_out(void); -{% endif %} - -{% else %} -int {{ cost.cost_function_ext_cost_e }}(void **, void **, void *); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_EXT_COST_E diff --git a/third_party/acados/acados_template/c_templates_tera/h_constraint.in.h b/third_party/acados/acados_template/c_templates_tera/h_constraint.in.h deleted file mode 100644 index e49176c6ef..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/h_constraint.in.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl - * - * This file is part of acados. - * - * The 2-Clause BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE.; - */ - -#ifndef {{ model.name }}_H_CONSTRAINT -#define {{ model.name }}_H_CONSTRAINT - -#ifdef __cplusplus -extern "C" { -#endif - -{% if dims.nh > 0 %} -int {{ model.name }}_constr_h_fun_jac_uxt_zt(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_work(int *, int *, int *, int *); -const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_sparsity_in(int); -const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_sparsity_out(int); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_n_in(void); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_n_out(void); - -int {{ model.name }}_constr_h_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_constr_h_fun_work(int *, int *, int *, int *); -const int *{{ model.name }}_constr_h_fun_sparsity_in(int); -const int *{{ model.name }}_constr_h_fun_sparsity_out(int); -int {{ model.name }}_constr_h_fun_n_in(void); -int {{ model.name }}_constr_h_fun_n_out(void); - -{% if solver_options.hessian_approx == "EXACT" -%} -int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_work(int *, int *, int *, int *); -const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_hess_sparsity_in(int); -const int *{{ model.name }}_constr_h_fun_jac_uxt_zt_hess_sparsity_out(int); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_n_in(void); -int {{ model.name }}_constr_h_fun_jac_uxt_zt_hess_n_out(void); -{% endif %} -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_H_CONSTRAINT diff --git a/third_party/acados/acados_template/c_templates_tera/main.in.c b/third_party/acados/acados_template/c_templates_tera/main.in.c index 99c4f13be1..92a8b33eac 100644 --- a/third_party/acados/acados_template/c_templates_tera/main.in.c +++ b/third_party/acados/acados_template/c_templates_tera/main.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -31,6 +28,11 @@ * POSSIBILITY OF SUCH DAMAGE.; */ +{%- if not solver_options.custom_update_filename %} + {%- set custom_update_filename = "" %} +{% else %} + {%- set custom_update_filename = solver_options.custom_update_filename %} +{%- endif %} // standard #include @@ -42,6 +44,9 @@ #include "acados_c/external_function_interface.h" #include "acados_solver_{{ model.name }}.h" +// blasfeo +#include "blasfeo/include/blasfeo_d_aux_ext_dep.h" + #define NX {{ model.name | upper }}_NX #define NZ {{ model.name | upper }}_NZ #define NU {{ model.name | upper }}_NU @@ -191,6 +196,11 @@ int main() printf("{{ model.name }}_acados_solve() failed with status %d.\n", status); } + +{%- if custom_update_filename != "" %} + {{ model.name }}_acados_custom_update(acados_ocp_capsule, xtraj, NX*(N+1)); +{%- endif %} + // get solution ocp_nlp_out_get(nlp_config, nlp_dims, nlp_out, 0, "kkt_norm_inf", &kkt_norm_inf); ocp_nlp_get(nlp_config, nlp_solver, "sqp_iter", &sqp_iter); diff --git a/third_party/acados/acados_template/c_templates_tera/main_sim.in.c b/third_party/acados/acados_template/c_templates_tera/main_sim.in.c index 743e81d593..8960aa0035 100644 --- a/third_party/acados/acados_template/c_templates_tera/main_sim.in.c +++ b/third_party/acados/acados_template/c_templates_tera/main_sim.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/acados_template/c_templates_tera/acados_mex_create.in.c b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_create.in.c similarity index 98% rename from third_party/acados/acados_template/c_templates_tera/acados_mex_create.in.c rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_create.in.c index e67a51567a..24ae94ac2c 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_mex_create.in.c +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_create.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/acados_template/c_templates_tera/acados_mex_free.in.c b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_free.in.c similarity index 88% rename from third_party/acados/acados_template/c_templates_tera/acados_mex_free.in.c rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_free.in.c index 560adb0b98..bd457969b2 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_mex_free.in.c +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_free.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/acados_template/c_templates_tera/acados_mex_set.in.c b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_set.in.c similarity index 76% rename from third_party/acados/acados_template/c_templates_tera/acados_mex_set.in.c rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_set.in.c index f8e1e5e445..78a308df49 100644 --- a/third_party/acados/acados_template/c_templates_tera/acados_mex_set.in.c +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/acados_mex_set.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -59,9 +56,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) /* RHS */ int min_nrhs = 6; - char *ext_fun_type = mxArrayToString( prhs[0] ); - char *ext_fun_type_e = mxArrayToString( prhs[1] ); - // C ocp const mxArray *C_ocp = prhs[2]; // capsule @@ -378,45 +372,63 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) // } // } // initializations - else if (!strcmp(field, "init_x")) + else if (!strcmp(field, "init_x") || !strcmp(field, "x")) { - if (nrhs!=min_nrhs) - MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field) - - acados_size = (N+1) * nx; - MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); - for (int ii=0; ii<=N; ii++) + if (nrhs == min_nrhs) { - ocp_nlp_out_set(config, dims, out, ii, "x", value+ii*nx); + acados_size = (N+1) * nx; + MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); + for (int ii=0; ii<=N; ii++) + { + ocp_nlp_out_set(config, dims, out, ii, "x", value+ii*nx); + } + } + else // (nrhs == min_nrhs + 1) + { + acados_size = nx; + MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); + ocp_nlp_out_set(config, dims, out, s0, "x", value); } } - else if (!strcmp(field, "init_u")) + else if (!strcmp(field, "init_u") || !strcmp(field, "u")) { - if (nrhs!=min_nrhs) - MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field) - - acados_size = N*nu; - MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); - for (int ii=0; iisim_solver_plan[0]; sim_solver_t type = sim_plan.sim_solver; if (type == IRK) { int nz = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "z"); - if (nrhs!=min_nrhs) - MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field) - - acados_size = N*nz; - MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); - for (int ii=0; iisim_solver_plan[0]; sim_solver_t type = sim_plan.sim_solver; if (type == IRK) { int nx = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "x"); - if (nrhs!=min_nrhs) - MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field) - - acados_size = N*nx; - MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); - for (int ii=0; iisim_solver_plan[0]; sim_solver_t type = sim_plan.sim_solver; @@ -454,14 +472,20 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int nout = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "init_gnsf_phi"); - if (nrhs!=min_nrhs) - MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field) - - acados_size = N*nout; - MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size); - for (int ii=0; ii 0 and simulink_opts.inputs.uh -%} {#- uh #} {%- set n_inputs = n_inputs + 1 -%} {%- endif -%} + {%- if dims.nh_e > 0 and simulink_opts.inputs.lh_e -%} {#- lh_e #} + {%- set n_inputs = n_inputs + 1 -%} + {%- endif -%} + {%- if dims.nh_e > 0 and simulink_opts.inputs.uh_e -%} {#- uh_e #} + {%- set n_inputs = n_inputs + 1 -%} + {%- endif -%} {%- for key, val in simulink_opts.inputs -%} {%- if val != 0 and val != 1 -%} @@ -177,7 +182,7 @@ static void mdlInitializeSizes (SimStruct *S) {%- if dims.np > 0 and simulink_opts.inputs.parameter_traj -%} {#- parameter_traj #} {%- set i_input = i_input + 1 %} // parameters - ssSetInputPortVectorDimension(S, {{ i_input }}, ({{ dims.N }}+1) * {{ dims.np }}); + ssSetInputPortVectorDimension(S, {{ i_input }}, (N+1) * {{ dims.np }}); {%- endif %} {%- if dims.ny > 0 and simulink_opts.inputs.y_ref_0 %} @@ -235,23 +240,34 @@ static void mdlInitializeSizes (SimStruct *S) {%- if dims.ng > 0 and simulink_opts.inputs.lg -%} {#- lg #} {%- set i_input = i_input + 1 %} // lg - ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.ng }}); + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.N*dims.ng }}); {%- endif -%} {%- if dims.ng > 0 and simulink_opts.inputs.ug -%} {#- ug #} {%- set i_input = i_input + 1 %} // ug - ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.ng }}); + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.N*dims.ng }}); {%- endif -%} {%- if dims.nh > 0 and simulink_opts.inputs.lh -%} {#- lh #} {%- set i_input = i_input + 1 %} // lh - ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh }}); + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.N*dims.nh }}); {%- endif -%} {%- if dims.nh > 0 and simulink_opts.inputs.uh -%} {#- uh #} {%- set i_input = i_input + 1 %} // uh - ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh }}); + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.N*dims.nh }}); + {%- endif -%} + + {%- if dims.nh_e > 0 and simulink_opts.inputs.lh_e -%} {#- lh_e #} + {%- set i_input = i_input + 1 %} + // lh_e + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh_e }}); + {%- endif -%} + {%- if dims.nh_e > 0 and simulink_opts.inputs.uh_e -%} {#- uh_e #} + {%- set i_input = i_input + 1 %} + // uh_e + ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nh_e }}); {%- endif -%} {%- if dims.ny_0 > 0 and simulink_opts.inputs.cost_W_0 %} {#- cost_W_0 #} @@ -312,11 +328,21 @@ static void mdlInitializeSizes (SimStruct *S) ssSetOutputPortVectorDimension(S, {{ i_output }}, 1 ); {%- endif %} + {%- if simulink_opts.outputs.cost_value == 1 %} + {%- set i_output = i_output + 1 %} + ssSetOutputPortVectorDimension(S, {{ i_output }}, 1 ); + {%- endif %} + {%- if simulink_opts.outputs.KKT_residual == 1 %} {%- set i_output = i_output + 1 %} ssSetOutputPortVectorDimension(S, {{ i_output }}, 1 ); {%- endif %} + {%- if simulink_opts.outputs.KKT_residuals == 1 %} + {%- set i_output = i_output + 1 %} + ssSetOutputPortVectorDimension(S, {{ i_output }}, 4 ); + {%- endif %} + {%- if dims.N > 0 and simulink_opts.outputs.x1 == 1 %} {%- set i_output = i_output + 1 %} ssSetOutputPortVectorDimension(S, {{ i_output }}, {{ dims.nx }} ); // state at shooting node 1 @@ -404,7 +430,9 @@ static void mdlOutputs(SimStruct *S, int_T tid) InputRealPtrsType in_sign; - {%- set buffer_sizes = [dims.nbx_0, dims.np, dims.nbx, dims.nbu, dims.ng, dims.nh, dims.nx] -%} + int N = {{ model.name | upper }}_N; + + {%- set buffer_sizes = [dims.nbx_0, dims.np, dims.nbx, dims.nbx_e, dims.nbu, dims.ng, dims.nh, dims.ng_e, dims.nh_e] -%} {%- if dims.ny_0 > 0 and simulink_opts.inputs.y_ref_0 %} {# y_ref_0 #} {%- set buffer_sizes = buffer_sizes | concat(with=(dims.ny_0)) %} @@ -457,7 +485,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); // update value of parameters - for (int ii = 0; ii <= {{ dims.N }}; ii++) + for (int ii = 0; ii <= N; ii++) { for (int jj = 0; jj < {{ dims.np }}; jj++) buffer[jj] = (double)(*in_sign[ii*{{dims.np}}+jj]); @@ -481,7 +509,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 1; ii < {{ dims.N }}; ii++) + for (int ii = 1; ii < N; ii++) { for (int jj = 0; jj < {{ dims.ny }}; jj++) buffer[jj] = (double)(*in_sign[(ii-1)*{{ dims.ny }}+jj]); @@ -497,14 +525,14 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (int i = 0; i < {{ dims.ny_e }}; i++) buffer[i] = (double)(*in_sign[i]); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, {{ dims.N }}, "yref", (void *) buffer); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "yref", (void *) buffer); {%- endif %} {%- if dims.nbx > 0 and dims.N > 1 and simulink_opts.inputs.lbx -%} {#- lbx #} // lbx {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 1; ii < {{ dims.N }}; ii++) + for (int ii = 1; ii < N; ii++) { for (int jj = 0; jj < {{ dims.nbx }}; jj++) buffer[jj] = (double)(*in_sign[(ii-1)*{{ dims.nbx }}+jj]); @@ -515,7 +543,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) // ubx {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 1; ii < {{ dims.N }}; ii++) + for (int ii = 1; ii < N; ii++) { for (int jj = 0; jj < {{ dims.nbx }}; jj++) buffer[jj] = (double)(*in_sign[(ii-1)*{{ dims.nbx }}+jj]); @@ -531,7 +559,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (int i = 0; i < {{ dims.nbx_e }}; i++) buffer[i] = (double)(*in_sign[i]); - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, {{ dims.N }}, "lbx", buffer); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "lbx", buffer); {%- endif %} {%- if dims.nbx_e > 0 and dims.N > 0 and simulink_opts.inputs.ubx_e -%} {#- ubx_e #} // ubx_e @@ -540,7 +568,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (int i = 0; i < {{ dims.nbx_e }}; i++) buffer[i] = (double)(*in_sign[i]); - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, {{ dims.N }}, "ubx", buffer); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "ubx", buffer); {%- endif %} @@ -548,7 +576,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) // lbu {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 0; ii < {{ dims.N }}; ii++) + for (int ii = 0; ii < N; ii++) { for (int jj = 0; jj < {{ dims.nbu }}; jj++) buffer[jj] = (double)(*in_sign[ii*{{ dims.nbu }}+jj]); @@ -559,7 +587,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) // ubu {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 0; ii < {{ dims.N }}; ii++) + for (int ii = 0; ii < N; ii++) { for (int jj = 0; jj < {{ dims.nbu }}; jj++) buffer[jj] = (double)(*in_sign[ii*{{ dims.nbu }}+jj]); @@ -572,44 +600,67 @@ static void mdlOutputs(SimStruct *S, int_T tid) {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int i = 0; i < {{ dims.ng }}; i++) - buffer[i] = (double)(*in_sign[i]); - - for (int ii = 0; ii < {{ dims.N }}; ii++) - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lg", buffer); + for (int ii = 0; ii < N; ii++) + { + for (int jj = 0; jj < {{ dims.ng }}; jj++) + buffer[jj] = (double)(*in_sign[ii*{{ dims.ng }}+jj]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lg", (void *) buffer); + } {%- endif -%} {%- if dims.ng > 0 and simulink_opts.inputs.ug -%} {#- ug #} // ug {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int i = 0; i < {{ dims.ng }}; i++) - buffer[i] = (double)(*in_sign[i]); - - for (int ii = 0; ii < {{ dims.N }}; ii++) - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "ug", buffer); + for (int ii = 0; ii < N; ii++) + { + for (int jj = 0; jj < {{ dims.ng }}; jj++) + buffer[jj] = (double)(*in_sign[ii*{{ dims.ng }}+jj]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "ug", (void *) buffer); + } {%- endif -%} + {%- if dims.nh > 0 and simulink_opts.inputs.lh -%} {#- lh #} // lh {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int i = 0; i < {{ dims.nh }}; i++) - buffer[i] = (double)(*in_sign[i]); - - for (int ii = 0; ii < {{ dims.N }}; ii++) - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lh", buffer); + for (int ii = 0; ii < N; ii++) + { + for (int jj = 0; jj < {{ dims.nh }}; jj++) + buffer[jj] = (double)(*in_sign[ii*{{ dims.nh }}+jj]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "lh", (void *) buffer); + } {%- endif -%} {%- if dims.nh > 0 and simulink_opts.inputs.uh -%} {#- uh #} // uh {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int i = 0; i < {{ dims.nh }}; i++) - buffer[i] = (double)(*in_sign[i]); + for (int ii = 0; ii < N; ii++) + { + for (int jj = 0; jj < {{ dims.nh }}; jj++) + buffer[jj] = (double)(*in_sign[ii*{{ dims.nh }}+jj]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "uh", (void *) buffer); + } + {%- endif -%} - for (int ii = 0; ii < {{ dims.N }}; ii++) - ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii, "uh", buffer); + + {%- if dims.nh_e > 0 and simulink_opts.inputs.lh_e -%} {#- lh_e #} + // lh_e + {%- set i_input = i_input + 1 %} + in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); + for (int i = 0; i < {{ dims.nh_e }}; i++) + buffer[i] = (double)(*in_sign[i]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "lh", buffer); + {%- endif -%} + {%- if dims.nh_e > 0 and simulink_opts.inputs.uh_e -%} {#- uh_e #} + // uh_e + {%- set i_input = i_input + 1 %} + in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); + for (int i = 0; i < {{ dims.nh_e }}; i++) + buffer[i] = (double)(*in_sign[i]); + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "uh", buffer); {%- endif -%} {%- if dims.ny_0 > 0 and simulink_opts.inputs.cost_W_0 %} {#- cost_W_0 #} @@ -629,7 +680,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (int i = 0; i < {{ dims.ny * dims.ny }}; i++) buffer[i] = (double)(*in_sign[i]); - for (int ii = 1; ii < {{ dims.N }}; ii++) + for (int ii = 1; ii < N; ii++) ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, ii, "W", buffer); {%- endif %} @@ -640,7 +691,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (int i = 0; i < {{ dims.ny_e * dims.ny_e }}; i++) buffer[i] = (double)(*in_sign[i]); - ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, {{ dims.N }}, "W", buffer); + ocp_nlp_cost_model_set(nlp_config, nlp_dims, nlp_in, N, "W", buffer); {%- endif %} {%- if simulink_opts.inputs.reset_solver %} {#- reset_solver #} @@ -650,7 +701,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) double reset = (double)(*in_sign[0]); if (reset) { - {{ model.name }}_acados_reset(capsule); + {{ model.name }}_acados_reset(capsule, 1); } {%- endif %} @@ -670,7 +721,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) // u_init {%- set i_input = i_input + 1 %} in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }}); - for (int ii = 0; ii < {{ dims.N }}; ii++) + for (int ii = 0; ii < N; ii++) { for (int jj = 0; jj < {{ dims.nu }}; jj++) buffer[jj] = (double)(*in_sign[(ii)*{{ dims.nu }}+jj]); @@ -686,7 +737,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) /* set outputs */ // assign pointers to output signals - real_t *out_u0, *out_utraj, *out_xtraj, *out_status, *out_sqp_iter, *out_KKT_res, *out_x1, *out_cpu_time, *out_cpu_time_sim, *out_cpu_time_qp, *out_cpu_time_lin; + real_t *out_u0, *out_utraj, *out_xtraj, *out_status, *out_sqp_iter, *out_KKT_res, *out_KKT_residuals, *out_x1, *out_cpu_time, *out_cpu_time_sim, *out_cpu_time_qp, *out_cpu_time_lin, *out_cost_value; int tmp_int; {%- set i_output = -1 -%}{# note here i_output is 0-based #} @@ -699,7 +750,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) {%- if simulink_opts.outputs.utraj == 1 %} {%- set i_output = i_output + 1 %} out_utraj = ssGetOutputPortRealSignal(S, {{ i_output }}); - for (int ii = 0; ii < {{ dims.N }}; ii++) + for (int ii = 0; ii < N; ii++) ocp_nlp_out_get(nlp_config, nlp_dims, nlp_out, ii, "u", (void *) (out_utraj + ii * {{ dims.nu }})); {%- endif %} @@ -719,12 +770,32 @@ static void mdlOutputs(SimStruct *S, int_T tid) *out_status = (real_t) acados_status; {%- endif %} + {%- if simulink_opts.outputs.cost_value == 1 %} + {%- set i_output = i_output + 1 %} + out_cost_value = ssGetOutputPortRealSignal(S, {{ i_output }}); + ocp_nlp_eval_cost(capsule->nlp_solver, nlp_in, nlp_out); + ocp_nlp_get(nlp_config, capsule->nlp_solver, "cost_value", (void *) out_cost_value); + {%- endif %} + {%- if simulink_opts.outputs.KKT_residual == 1 %} {%- set i_output = i_output + 1 %} out_KKT_res = ssGetOutputPortRealSignal(S, {{ i_output }}); *out_KKT_res = (real_t) nlp_out->inf_norm_res; {%- endif %} + {%- if simulink_opts.outputs.KKT_residuals == 1 %} + {%- set i_output = i_output + 1 %} + out_KKT_residuals = ssGetOutputPortRealSignal(S, {{ i_output }}); + + {%- if solver_options.nlp_solver_type == "SQP_RTI" %} + ocp_nlp_eval_residuals(capsule->nlp_solver, nlp_in, nlp_out); + {%- endif %} + ocp_nlp_get(nlp_config, capsule->nlp_solver, "res_stat", (void *) &out_KKT_residuals[0]); + ocp_nlp_get(nlp_config, capsule->nlp_solver, "res_eq", (void *) &out_KKT_residuals[1]); + ocp_nlp_get(nlp_config, capsule->nlp_solver, "res_ineq", (void *) &out_KKT_residuals[2]); + ocp_nlp_get(nlp_config, capsule->nlp_solver, "res_comp", (void *) &out_KKT_residuals[3]); + {%- endif %} + {%- if dims.N > 0 and simulink_opts.outputs.x1 == 1 %} {%- set i_output = i_output + 1 %} out_x1 = ssGetOutputPortRealSignal(S, {{ i_output }}); diff --git a/third_party/acados/acados_template/c_templates_tera/main_mex.in.c b/third_party/acados/acados_template/c_templates_tera/matlab_templates/main_mex.in.c similarity index 95% rename from third_party/acados/acados_template/c_templates_tera/main_mex.in.c rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/main_mex.in.c index 8da5db29a0..851a3cc04f 100644 --- a/third_party/acados/acados_template/c_templates_tera/main_mex.in.c +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/main_mex.in.c @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/acados_template/c_templates_tera/make_main_mex.in.m b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_main_mex.in.m similarity index 93% rename from third_party/acados/acados_template/c_templates_tera/make_main_mex.in.m rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/make_main_mex.in.m index 9188686a0d..d217948456 100644 --- a/third_party/acados/acados_template/c_templates_tera/make_main_mex.in.m +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_main_mex.in.m @@ -1,8 +1,5 @@ % -% Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -% Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -% Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -% Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +% Copyright (c) The acados authors. % % This file is part of acados. % @@ -29,6 +26,7 @@ % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE.; + % function make_main_mex_{{ model.name }}() diff --git a/third_party/acados/acados_template/c_templates_tera/make_mex.in.m b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_mex.in.m similarity index 81% rename from third_party/acados/acados_template/c_templates_tera/make_mex.in.m rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/make_mex.in.m index cde30f6f41..5e35827137 100644 --- a/third_party/acados/acados_template/c_templates_tera/make_mex.in.m +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_mex.in.m @@ -1,8 +1,5 @@ % -% Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -% Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -% Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -% Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +% Copyright (c) The acados authors. % % This file is part of acados. % @@ -29,6 +26,7 @@ % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE.; + % function make_mex_{{ model.name }}() @@ -48,6 +46,23 @@ function make_mex_{{ model.name }}() blasfeo_include = ['-I', fullfile(acados_folder, 'external', 'blasfeo', 'include')]; hpipm_include = ['-I', fullfile(acados_folder, 'external', 'hpipm', 'include')]; + % load linking information of compiled acados + link_libs_core_filename = fullfile(acados_folder, 'lib', 'link_libs.json'); + addpath(fullfile(acados_folder, 'external', 'jsonlab')); + link_libs = loadjson(link_libs_core_filename); + + % add necessary link instructs + acados_lib_extra = {}; + lib_names = fieldnames(link_libs); + for idx = 1 : numel(lib_names) + lib_name = lib_names{idx}; + link_arg = link_libs.(lib_name); + if ~isempty(link_arg) + acados_lib_extra = [acados_lib_extra, link_arg]; + end + end + + mex_include = ['-I', fullfile(acados_folder, 'interfaces', 'acados_matlab_octave')]; mex_names = { ... @@ -94,7 +109,8 @@ function make_mex_{{ model.name }}() if is_octave() % mkoctfile -p CFLAGS mex(acados_include, template_lib_include, external_include, blasfeo_include, hpipm_include,... - acados_lib_path, template_lib_path, mex_include, '-lacados', '-lhpipm', '-lblasfeo', mex_files{ii}) + template_lib_path, mex_include, acados_lib_path, '-lacados', '-lhpipm', '-lblasfeo',... + acados_lib_extra{:}, mex_files{ii}) else if ismac() FLAGS = 'CFLAGS=$CFLAGS -std=c99'; @@ -102,7 +118,8 @@ function make_mex_{{ model.name }}() FLAGS = 'CFLAGS=$CFLAGS -std=c99 -fopenmp'; end mex(FLAGS, acados_include, template_lib_include, external_include, blasfeo_include, hpipm_include,... - acados_lib_path, template_lib_path, mex_include, '-lacados', '-lhpipm', '-lblasfeo', mex_files{ii}) + template_lib_path, mex_include, acados_lib_path, '-lacados', '-lhpipm', '-lblasfeo',... + acados_lib_extra{:}, mex_files{ii}) end end diff --git a/third_party/acados/acados_template/c_templates_tera/make_sfun.in.m b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun.in.m similarity index 74% rename from third_party/acados/acados_template/c_templates_tera/make_sfun.in.m rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun.in.m index 77603a78fa..5d74c523f8 100644 --- a/third_party/acados/acados_template/c_templates_tera/make_sfun.in.m +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun.in.m @@ -1,8 +1,5 @@ % -% Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -% Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -% Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -% Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +% Copyright (c) The acados authors. % % This file is part of acados. % @@ -29,6 +26,7 @@ % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE.; + % SOURCES = { ... @@ -133,6 +131,9 @@ COMPDEFINES = [ COMPDEFINES, ' -DACADOS_WITH_OSQP ' ]; {%- elif solver_options.qp_solver is containing("QPDUNES") %} CFLAGS = [ CFLAGS, ' -DACADOS_WITH_QPDUNES ' ]; COMPDEFINES = [ COMPDEFINES, ' -DACADOS_WITH_QPDUNES ' ]; +{%- elif solver_options.qp_solver is containing("DAQP") %} +CFLAGS = [ CFLAGS, ' -DACADOS_WITH_DAQP' ]; +COMPDEFINES = [ COMPDEFINES, ' -DACADOS_WITH_DAQP' ]; {%- elif solver_options.qp_solver is containing("HPMPC") %} CFLAGS = [ CFLAGS, ' -DACADOS_WITH_HPMPC ' ]; COMPDEFINES = [ COMPDEFINES, ' -DACADOS_WITH_HPMPC ' ]; @@ -153,129 +154,176 @@ LIBS{end+1} = '{{ acados_link_libs.osqp }}'; {% if solver_options.qp_solver is containing("QPOASES") %} LIBS{end+1} = '-lqpOASES_e'; {% endif %} + {% if solver_options.qp_solver is containing("DAQP") %} +LIBS{end+1} = '-ldaqp'; + {% endif %} {%- endif %} -mex('-v', '-O', CFLAGS, LDFLAGS, COMPFLAGS, COMPDEFINES, INCS{:}, ... - LIB_PATH, LIBS{:}, SOURCES{:}, ... - '-output', 'acados_solver_sfunction_{{ model.name }}' ); + +try + % mex('-v', '-O', CFLAGS, LDFLAGS, COMPFLAGS, COMPDEFINES, INCS{:}, ... + mex('-O', CFLAGS, LDFLAGS, COMPFLAGS, COMPDEFINES, INCS{:}, ... + LIB_PATH, LIBS{:}, SOURCES{:}, ... + '-output', 'acados_solver_sfunction_{{ model.name }}' ); +catch exception + disp('make_sfun failed with the following exception:') + disp(exception); + disp('Try adding -v to the mex command above to get more information.') + keyboard +end fprintf( [ '\n\nSuccessfully created sfunction:\nacados_solver_sfunction_{{ model.name }}', '.', ... eval('mexext')] ); -%% print note on usage of s-function +%% print note on usage of s-function, and create I/O port names vectors fprintf('\n\nNote: Usage of Sfunction is as follows:\n') input_note = 'Inputs are:\n'; i_in = 1; +global sfun_input_names +sfun_input_names = {}; {%- if dims.nbx_0 > 0 and simulink_opts.inputs.lbx_0 -%} {#- lbx_0 #} input_note = strcat(input_note, num2str(i_in), ') lbx_0 - lower bound on x for stage 0,',... ' size [{{ dims.nbx_0 }}]\n '); +sfun_input_names = [sfun_input_names; 'lbx_0 [{{ dims.nbx_0 }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbx_0 > 0 and simulink_opts.inputs.ubx_0 -%} {#- ubx_0 #} input_note = strcat(input_note, num2str(i_in), ') ubx_0 - upper bound on x for stage 0,',... ' size [{{ dims.nbx_0 }}]\n '); +sfun_input_names = [sfun_input_names; 'ubx_0 [{{ dims.nbx_0 }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.np > 0 and simulink_opts.inputs.parameter_traj -%} {#- parameter_traj #} -input_note = strcat(input_note, num2str(i_in), ') parameters - concatenated for all shooting nodes 0 to N+1,',... +input_note = strcat(input_note, num2str(i_in), ') parameters - concatenated for all shooting nodes 0 to N,',... ' size [{{ (dims.N+1)*dims.np }}]\n '); +sfun_input_names = [sfun_input_names; 'parameter_traj [{{ (dims.N+1)*dims.np }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny_0 > 0 and simulink_opts.inputs.y_ref_0 %} input_note = strcat(input_note, num2str(i_in), ') y_ref_0, size [{{ dims.ny_0 }}]\n '); +sfun_input_names = [sfun_input_names; 'y_ref_0 [{{ dims.ny_0 }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny > 0 and dims.N > 1 and simulink_opts.inputs.y_ref %} input_note = strcat(input_note, num2str(i_in), ') y_ref - concatenated for shooting nodes 1 to N-1,',... ' size [{{ (dims.N-1) * dims.ny }}]\n '); +sfun_input_names = [sfun_input_names; 'y_ref [{{ (dims.N-1) * dims.ny }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny_e > 0 and dims.N > 0 and simulink_opts.inputs.y_ref_e %} input_note = strcat(input_note, num2str(i_in), ') y_ref_e, size [{{ dims.ny_e }}]\n '); +sfun_input_names = [sfun_input_names; 'y_ref_e [{{ dims.ny_e }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbx > 0 and dims.N > 1 and simulink_opts.inputs.lbx -%} {#- lbx #} input_note = strcat(input_note, num2str(i_in), ') lbx for shooting nodes 1 to N-1, size [{{ (dims.N-1) * dims.nbx }}]\n '); +sfun_input_names = [sfun_input_names; 'lbx [{{ (dims.N-1) * dims.nbx }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbx > 0 and dims.N > 1 and simulink_opts.inputs.ubx -%} {#- ubx #} input_note = strcat(input_note, num2str(i_in), ') ubx for shooting nodes 1 to N-1, size [{{ (dims.N-1) * dims.nbx }}]\n '); +sfun_input_names = [sfun_input_names; 'ubx [{{ (dims.N-1) * dims.nbx }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbx_e > 0 and dims.N > 0 and simulink_opts.inputs.lbx_e -%} {#- lbx_e #} input_note = strcat(input_note, num2str(i_in), ') lbx_e (lbx at shooting node N), size [{{ dims.nbx_e }}]\n '); +sfun_input_names = [sfun_input_names; 'lbx_e [{{ dims.nbx_e }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbx_e > 0 and dims.N > 0 and simulink_opts.inputs.ubx_e -%} {#- ubx_e #} input_note = strcat(input_note, num2str(i_in), ') ubx_e (ubx at shooting node N), size [{{ dims.nbx_e }}]\n '); +sfun_input_names = [sfun_input_names; 'ubx_e [{{ dims.nbx_e }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nbu > 0 and dims.N > 0 and simulink_opts.inputs.lbu -%} {#- lbu #} input_note = strcat(input_note, num2str(i_in), ') lbu for shooting nodes 0 to N-1, size [{{ dims.N*dims.nbu }}]\n '); +sfun_input_names = [sfun_input_names; 'lbu [{{ dims.N*dims.nbu }}]']; i_in = i_in + 1; {%- endif -%} {%- if dims.nbu > 0 and dims.N > 0 and simulink_opts.inputs.ubu -%} {#- ubu #} input_note = strcat(input_note, num2str(i_in), ') ubu for shooting nodes 0 to N-1, size [{{ dims.N*dims.nbu }}]\n '); +sfun_input_names = [sfun_input_names; 'ubu [{{ dims.N*dims.nbu }}]']; i_in = i_in + 1; {%- endif -%} {%- if dims.ng > 0 and simulink_opts.inputs.lg -%} {#- lg #} -input_note = strcat(input_note, num2str(i_in), ') lg, size [{{ dims.ng }}]\n '); +input_note = strcat(input_note, num2str(i_in), ') lg for shooting nodes 0 to N-1, size [{{ dims.N*dims.ng }}]\n '); +sfun_input_names = [sfun_input_names; 'lg [{{ dims.N*dims.ng }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ng > 0 and simulink_opts.inputs.ug -%} {#- ug #} -input_note = strcat(input_note, num2str(i_in), ') ug, size [{{ dims.ng }}]\n '); +input_note = strcat(input_note, num2str(i_in), ') ug for shooting nodes 0 to N-1, size [{{ dims.N*dims.ng }}]\n '); +sfun_input_names = [sfun_input_names; 'ug [{{ dims.N*dims.ng }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nh > 0 and simulink_opts.inputs.lh -%} {#- lh #} -input_note = strcat(input_note, num2str(i_in), ') lh, size [{{ dims.nh }}]\n '); +input_note = strcat(input_note, num2str(i_in), ') lh for shooting nodes 0 to N-1, size [{{ dims.N*dims.nh }}]\n '); +sfun_input_names = [sfun_input_names; 'lh [{{ dims.N*dims.nh }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.nh > 0 and simulink_opts.inputs.uh -%} {#- uh #} -input_note = strcat(input_note, num2str(i_in), ') uh, size [{{ dims.nh }}]\n '); +input_note = strcat(input_note, num2str(i_in), ') uh for shooting nodes 0 to N-1, size [{{ dims.N*dims.nh }}]\n '); +sfun_input_names = [sfun_input_names; 'uh [{{ dims.N*dims.nh }}]']; +i_in = i_in + 1; +{%- endif %} + +{%- if dims.nh_e > 0 and simulink_opts.inputs.lh_e -%} {#- lh_e #} +input_note = strcat(input_note, num2str(i_in), ') lh_e, size [{{ dims.nh_e }}]\n '); +sfun_input_names = [sfun_input_names; 'lh_e [{{ dims.nh_e }}]']; +i_in = i_in + 1; +{%- endif %} +{%- if dims.nh_e > 0 and simulink_opts.inputs.uh_e -%} {#- uh_e #} +input_note = strcat(input_note, num2str(i_in), ') uh_e, size [{{ dims.nh_e }}]\n '); +sfun_input_names = [sfun_input_names; 'uh_e [{{ dims.nh_e }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny_0 > 0 and simulink_opts.inputs.cost_W_0 %} {#- cost_W_0 #} input_note = strcat(input_note, num2str(i_in), ') cost_W_0 in column-major format, size [{{ dims.ny_0 * dims.ny_0 }}]\n '); +sfun_input_names = [sfun_input_names; 'cost_W_0 [{{ dims.ny_0 * dims.ny_0 }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny > 0 and simulink_opts.inputs.cost_W %} {#- cost_W #} input_note = strcat(input_note, num2str(i_in), ') cost_W in column-major format, that is set for all intermediate shooting nodes: 1 to N-1, size [{{ dims.ny * dims.ny }}]\n '); +sfun_input_names = [sfun_input_names; 'cost_W [{{ dims.ny * dims.ny }}]']; i_in = i_in + 1; {%- endif %} {%- if dims.ny_e > 0 and simulink_opts.inputs.cost_W_e %} {#- cost_W_e #} input_note = strcat(input_note, num2str(i_in), ') cost_W_e in column-major format, size [{{ dims.ny_e * dims.ny_e }}]\n '); +sfun_input_names = [sfun_input_names; 'cost_W_e [{{ dims.ny_e * dims.ny_e }}]']; i_in = i_in + 1; {%- endif %} {%- if simulink_opts.inputs.reset_solver %} {#- reset_solver #} input_note = strcat(input_note, num2str(i_in), ') reset_solver determines if iterate is set to all zeros before other initializations (x_init, u_init) are set and before solver is called, size [1]\n '); +sfun_input_names = [sfun_input_names; 'reset_solver [1]']; i_in = i_in + 1; {%- endif %} {%- if simulink_opts.inputs.x_init %} {#- x_init #} input_note = strcat(input_note, num2str(i_in), ') initialization of x for all shooting nodes, size [{{ dims.nx * (dims.N+1) }}]\n '); +sfun_input_names = [sfun_input_names; 'x_init [{{ dims.nx * (dims.N+1) }}]']; i_in = i_in + 1; {%- endif %} {%- if simulink_opts.inputs.u_init %} {#- u_init #} input_note = strcat(input_note, num2str(i_in), ') initialization of u for shooting nodes 0 to N-1, size [{{ dims.nu * (dims.N) }}]\n '); +sfun_input_names = [sfun_input_names; 'u_init [{{ dims.nu * (dims.N) }}]']; i_in = i_in + 1; {%- endif %} @@ -286,59 +334,99 @@ disp(' ') output_note = 'Outputs are:\n'; i_out = 0; +global sfun_output_names +sfun_output_names = {}; + {%- if dims.nu > 0 and simulink_opts.outputs.u0 == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') u0, control input at node 0, size [{{ dims.nu }}]\n '); +sfun_output_names = [sfun_output_names; 'u0 [{{ dims.nu }}]']; {%- endif %} {%- if simulink_opts.outputs.utraj == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') utraj, control input concatenated for nodes 0 to N-1, size [{{ dims.nu * dims.N }}]\n '); +sfun_output_names = [sfun_output_names; 'utraj [{{ dims.nu * dims.N }}]']; {%- endif %} {%- if simulink_opts.outputs.xtraj == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') xtraj, state concatenated for nodes 0 to N, size [{{ dims.nx * (dims.N + 1) }}]\n '); +sfun_output_names = [sfun_output_names; 'xtraj [{{ dims.nx * (dims.N + 1) }}]']; {%- endif %} {%- if simulink_opts.outputs.solver_status == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') acados solver status (0 = SUCCESS)\n '); +sfun_output_names = [sfun_output_names; 'solver_status']; {%- endif %} +{%- if simulink_opts.outputs.cost_value == 1 %} +i_out = i_out + 1; +output_note = strcat(output_note, num2str(i_out), ') cost function value\n '); +sfun_output_names = [sfun_output_names; 'cost_value']; +{%- endif %} + + {%- if simulink_opts.outputs.KKT_residual == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') KKT residual\n '); +sfun_output_names = [sfun_output_names; 'KKT_residual']; +{%- endif %} + +{%- if simulink_opts.outputs.KKT_residuals == 1 %} +i_out = i_out + 1; +output_note = strcat(output_note, num2str(i_out), ') KKT residuals, size [4] (stat, eq, ineq, comp)\n '); +sfun_output_names = [sfun_output_names; 'KKT_residuals [4]']; {%- endif %} {%- if dims.N > 0 and simulink_opts.outputs.x1 == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') x1, state at node 1\n '); +sfun_output_names = [sfun_output_names; 'x1']; {%- endif %} {%- if simulink_opts.outputs.CPU_time == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') CPU time\n '); +sfun_output_names = [sfun_output_names; 'CPU_time']; {%- endif %} {%- if simulink_opts.outputs.CPU_time_sim == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') CPU time integrator\n '); +sfun_output_names = [sfun_output_names; 'CPU_time_sim']; {%- endif %} {%- if simulink_opts.outputs.CPU_time_qp == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') CPU time QP solution\n '); +sfun_output_names = [sfun_output_names; 'CPU_time_qp']; {%- endif %} {%- if simulink_opts.outputs.CPU_time_lin == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') CPU time linearization (including integrator)\n '); +sfun_output_names = [sfun_output_names; 'CPU_time_lin']; {%- endif %} {%- if simulink_opts.outputs.sqp_iter == 1 %} i_out = i_out + 1; output_note = strcat(output_note, num2str(i_out), ') SQP iterations\n '); +sfun_output_names = [sfun_output_names; 'sqp_iter']; {%- endif %} fprintf(output_note) + +% The mask drawing command is: +% --- +% global sfun_input_names sfun_output_names +% for i = 1:length(sfun_input_names) +% port_label('input', i, sfun_input_names{i}) +% end +% for i = 1:length(sfun_output_names) +% port_label('output', i, sfun_output_names{i}) +% end +% --- +% It can be used by copying it in sfunction/Mask/Edit mask/Icon drawing commands +% (you can access it wirth ctrl+M on the s-function) \ No newline at end of file diff --git a/third_party/acados/acados_template/c_templates_tera/make_sfun_sim.in.m b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun_sim.in.m similarity index 70% rename from third_party/acados/acados_template/c_templates_tera/make_sfun_sim.in.m rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun_sim.in.m index a0c503e41a..e4c32a8c19 100644 --- a/third_party/acados/acados_template/c_templates_tera/make_sfun_sim.in.m +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/make_sfun_sim.in.m @@ -1,8 +1,5 @@ % -% Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -% Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -% Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -% Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +% Copyright (c) The acados authors. % % This file is part of acados. % @@ -29,17 +26,19 @@ % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE.; + % SOURCES = [ 'acados_sim_solver_sfunction_{{ model.name }}.c ', ... 'acados_sim_solver_{{ model.name }}.c ', ... {%- if solver_options.integrator_type == 'ERK' %} - '{{ model.name }}_model/{{ model.name }}_expl_ode_fun.c ', ... + '{{ model.name }}_model/{{ model.name }}_expl_ode_fun.c ',... '{{ model.name }}_model/{{ model.name }}_expl_vde_forw.c ',... + '{{ model.name }}_model/{{ model.name }}_expl_vde_adj.c ',... {%- if solver_options.hessian_approx == 'EXACT' %} '{{ model.name }}_model/{{ model.name }}_expl_ode_hess.c ',... {%- endif %} - {%- elif solver_options.integrator_type == "IRK" %} + {%- elif solver_options.integrator_type == "IRK" %} '{{ model.name }}_model/{{ model.name }}_impl_dae_fun.c ', ... '{{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_z.c ', ... '{{ model.name }}_model/{{ model.name }}_impl_dae_jac_x_xdot_u_z.c ', ... @@ -47,15 +46,15 @@ SOURCES = [ 'acados_sim_solver_sfunction_{{ model.name }}.c ', ... '{{ model.name }}_model/{{ model.name }}_impl_dae_hess.c ',... {%- endif %} {%- elif solver_options.integrator_type == "GNSF" %} - {% if model.gnsf.purely_linear != 1 %} - '{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun.c ' - '{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun_jac_y.c ' - '{{ model.name }}_model/{{ model.name }}_gnsf_phi_jac_y_uhat.c ' - {% if model.gnsf.nontrivial_f_LO == 1 %} - '{{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c ' + {%- if model.gnsf.purely_linear != 1 %} + '{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun.c ',... + '{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun_jac_y.c ',... + '{{ model.name }}_model/{{ model.name }}_gnsf_phi_jac_y_uhat.c ',... + {%- if model.gnsf.nontrivial_f_LO == 1 %} + '{{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c ',... {%- endif %} {%- endif %} - '{{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c ' + '{{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c ',... {%- endif %} ]; @@ -71,25 +70,42 @@ LIB_PATH = '{{ acados_lib_path }}'; LIBS = '-lacados -lblasfeo -lhpipm'; -eval( [ 'mex -v -output acados_sim_solver_sfunction_{{ model.name }} ', ... - CFLAGS, INCS, ' ', SOURCES, ' -L', LIB_PATH, ' ', LIBS ]); +try + % eval( [ 'mex -v -output acados_sim_solver_sfunction_{{ model.name }} ', ... + eval( [ 'mex -output acados_sim_solver_sfunction_{{ model.name }} ', ... + CFLAGS, INCS, ' ', SOURCES, ' -L', LIB_PATH, ' ', LIBS ]); + +catch exception + disp('make_sfun failed with the following exception:') + disp(exception); + disp('Try adding -v to the mex command above to get more information.') + keyboard +end + fprintf( [ '\n\nSuccessfully created sfunction:\nacados_sim_solver_sfunction_{{ model.name }}', '.', ... eval('mexext')] ); +global sfun_sim_input_names +sfun_sim_input_names = {}; + %% print note on usage of s-function fprintf('\n\nNote: Usage of Sfunction is as follows:\n') input_note = 'Inputs are:\n1) x0, initial state, size [{{ dims.nx }}]\n '; i_in = 2; +sfun_sim_input_names = [sfun_sim_input_names; 'x0 [{{ dims.nx }}]']; + {%- if dims.nu > 0 %} input_note = strcat(input_note, num2str(i_in), ') u, size [{{ dims.nu }}]\n '); i_in = i_in + 1; +sfun_sim_input_names = [sfun_sim_input_names; 'u [{{ dims.nu }}]']; {%- endif %} {%- if dims.np > 0 %} input_note = strcat(input_note, num2str(i_in), ') parameters, size [{{ dims.np }}]\n '); i_in = i_in + 1; +sfun_sim_input_names = [sfun_sim_input_names; 'p [{{ dims.np }}]']; {%- endif %} @@ -97,7 +113,25 @@ fprintf(input_note) disp(' ') +global sfun_sim_output_names +sfun_sim_output_names = {}; + output_note = strcat('Outputs are:\n', ... '1) x1 - simulated state, size [{{ dims.nx }}]\n'); +sfun_sim_output_names = [sfun_sim_output_names; 'x1 [{{ dims.nx }}]']; fprintf(output_note) + + +% The mask drawing command is: +% --- +% global sfun_sim_input_names sfun_sim_output_names +% for i = 1:length(sfun_sim_input_names) +% port_label('input', i, sfun_sim_input_names{i}) +% end +% for i = 1:length(sfun_sim_output_names) +% port_label('output', i, sfun_sim_output_names{i}) +% end +% --- +% It can be used by copying it in sfunction/Mask/Edit mask/Icon drawing commands +% (you can access it wirth ctrl+M on the s-function) \ No newline at end of file diff --git a/third_party/acados/acados_template/c_templates_tera/mex_solver.in.m b/third_party/acados/acados_template/c_templates_tera/matlab_templates/mex_solver.in.m similarity index 61% rename from third_party/acados/acados_template/c_templates_tera/mex_solver.in.m rename to third_party/acados/acados_template/c_templates_tera/matlab_templates/mex_solver.in.m index 278e0a605c..3743212830 100644 --- a/third_party/acados/acados_template/c_templates_tera/mex_solver.in.m +++ b/third_party/acados/acados_template/c_templates_tera/matlab_templates/mex_solver.in.m @@ -1,8 +1,5 @@ % -% Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -% Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -% Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -% Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +% Copyright (c) The acados authors. % % This file is part of acados. % @@ -29,6 +26,7 @@ % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE.; + % classdef {{ model.name }}_mex_solver < handle @@ -38,6 +36,9 @@ classdef {{ model.name }}_mex_solver < handle C_ocp_ext_fun cost_ext_fun_type cost_ext_fun_type_e + N + name + code_gen_dir end % properties @@ -52,13 +53,21 @@ classdef {{ model.name }}_mex_solver < handle addpath('.') obj.cost_ext_fun_type = '{{ cost.cost_ext_fun_type }}'; obj.cost_ext_fun_type_e = '{{ cost.cost_ext_fun_type_e }}'; + obj.N = {{ dims.N }}; + obj.name = '{{ model.name }}'; + obj.code_gen_dir = pwd(); end % destructor function delete(obj) + disp("delete template..."); + return_dir = pwd(); + cd(obj.code_gen_dir); if ~isempty(obj.C_ocp) acados_mex_free_{{ model.name }}(obj.C_ocp); end + cd(return_dir); + disp("done."); end % solve @@ -112,6 +121,101 @@ classdef {{ model.name }}_mex_solver < handle end + function [] = store_iterate(varargin) + %%% Stores the current iterate of the ocp solver in a json file. + %%% param1: filename: if not set, use model_name + timestamp + '.json' + %%% param2: overwrite: if false and filename exists add timestamp to filename + + obj = varargin{1}; + filename = ''; + overwrite = false; + + if nargin>=2 + filename = varargin{2}; + if ~isa(filename, 'char') + error('filename must be a char vector, use '' '''); + end + end + + if nargin==3 + overwrite = varargin{3}; + end + + if nargin > 3 + disp('acados_ocp.get: wrong number of input arguments (1 or 2 allowed)'); + end + + if strcmp(filename,'') + filename = [obj.name '_iterate.json']; + end + if ~overwrite + % append timestamp + if exist(filename, 'file') + filename = filename(1:end-5); + filename = [filename '_' datestr(now,'yyyy-mm-dd-HH:MM:SS') '.json']; + end + end + filename = fullfile(pwd, filename); + + % get iterate: + solution = struct(); + for i=0:obj.N + solution.(['x_' num2str(i)]) = obj.get('x', i); + solution.(['lam_' num2str(i)]) = obj.get('lam', i); + solution.(['t_' num2str(i)]) = obj.get('t', i); + solution.(['sl_' num2str(i)]) = obj.get('sl', i); + solution.(['su_' num2str(i)]) = obj.get('su', i); + end + for i=0:obj.N-1 + solution.(['z_' num2str(i)]) = obj.get('z', i); + solution.(['u_' num2str(i)]) = obj.get('u', i); + solution.(['pi_' num2str(i)]) = obj.get('pi', i); + end + + acados_folder = getenv('ACADOS_INSTALL_DIR'); + addpath(fullfile(acados_folder, 'external', 'jsonlab')); + savejson('', solution, filename); + + json_string = savejson('', solution, 'ForceRootName', 0); + + fid = fopen(filename, 'w'); + if fid == -1, error('store_iterate: Cannot create JSON file'); end + fwrite(fid, json_string, 'char'); + fclose(fid); + + disp(['stored current iterate in ' filename]); + end + + + function [] = load_iterate(obj, filename) + %%% Loads the iterate stored in json file with filename into the ocp solver. + acados_folder = getenv('ACADOS_INSTALL_DIR'); + addpath(fullfile(acados_folder, 'external', 'jsonlab')); + filename = fullfile(pwd, filename); + + if ~exist(filename, 'file') + error(['load_iterate: failed, file does not exist: ' filename]) + end + + solution = loadjson(filename); + keys = fieldnames(solution); + + for k = 1:numel(keys) + key = keys{k}; + key_parts = strsplit(key, '_'); + field = key_parts{1}; + stage = key_parts{2}; + + val = solution.(key); + + % check if array is empty (can happen for z) + if numel(val) > 0 + obj.set(field, val, str2num(stage)) + end + end + end + + % print function print(varargin) if nargin < 2 diff --git a/third_party/acados/acados_template/c_templates_tera/model.in.h b/third_party/acados/acados_template/c_templates_tera/model.in.h index 918e2bc29e..e5059df9ff 100644 --- a/third_party/acados/acados_template/c_templates_tera/model.in.h +++ b/third_party/acados/acados_template/c_templates_tera/model.in.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -47,7 +44,8 @@ extern "C" { {%- endif %} {% if solver_options.integrator_type == "IRK" or solver_options.integrator_type == "LIFTED_IRK" %} -// implicit ODE + {% if model.dyn_ext_fun_type == "casadi" %} +// implicit ODE: function int {{ model.name }}_impl_dae_fun(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); int {{ model.name }}_impl_dae_fun_work(int *, int *, int *, int *); const int *{{ model.name }}_impl_dae_fun_sparsity_in(int); @@ -55,7 +53,7 @@ const int *{{ model.name }}_impl_dae_fun_sparsity_out(int); int {{ model.name }}_impl_dae_fun_n_in(void); int {{ model.name }}_impl_dae_fun_n_out(void); -// implicit ODE +// implicit ODE: function + jacobians int {{ model.name }}_impl_dae_fun_jac_x_xdot_z(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); int {{ model.name }}_impl_dae_fun_jac_x_xdot_z_work(int *, int *, int *, int *); const int *{{ model.name }}_impl_dae_fun_jac_x_xdot_z_sparsity_in(int); @@ -63,7 +61,7 @@ const int *{{ model.name }}_impl_dae_fun_jac_x_xdot_z_sparsity_out(int); int {{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_in(void); int {{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_out(void); -// implicit ODE +// implicit ODE: jacobians only int {{ model.name }}_impl_dae_jac_x_xdot_u_z(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); int {{ model.name }}_impl_dae_jac_x_xdot_u_z_work(int *, int *, int *, int *); const int *{{ model.name }}_impl_dae_jac_x_xdot_u_z_sparsity_in(int); @@ -79,14 +77,23 @@ const int *{{ model.name }}_impl_dae_fun_jac_x_xdot_u_sparsity_out(int); int {{ model.name }}_impl_dae_fun_jac_x_xdot_u_n_in(void); int {{ model.name }}_impl_dae_fun_jac_x_xdot_u_n_out(void); -{%- if hessian_approx == "EXACT" %} + {%- if hessian_approx == "EXACT" %} +// implicit ODE - hessian int {{ model.name }}_impl_dae_hess(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); int {{ model.name }}_impl_dae_hess_work(int *, int *, int *, int *); const int *{{ model.name }}_impl_dae_hess_sparsity_in(int); const int *{{ model.name }}_impl_dae_hess_sparsity_out(int); int {{ model.name }}_impl_dae_hess_n_in(void); int {{ model.name }}_impl_dae_hess_n_out(void); -{%- endif %} + {% endif %} + {% else %}{# ext_fun_type #} + {%- if hessian_approx == "EXACT" %} +int {{ model.dyn_impl_dae_hess }}(void **, void **, void *); + {% endif %} +int {{ model.dyn_impl_dae_fun_jac }}(void **, void **, void *); +int {{ model.dyn_impl_dae_jac }}(void **, void **, void *); +int {{ model.dyn_impl_dae_fun }}(void **, void **, void *); + {% endif %}{# ext_fun_type #} {% elif solver_options.integrator_type == "GNSF" %} /* GNSF Functions */ diff --git a/third_party/acados/acados_template/c_templates_tera/phi_e_constraint.in.h b/third_party/acados/acados_template/c_templates_tera/phi_e_constraint.in.h deleted file mode 100644 index dc8e293ad7..0000000000 --- a/third_party/acados/acados_template/c_templates_tera/phi_e_constraint.in.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef {{ model.name }}_PHI_E_CONSTRAINT -#define {{ model.name }}_PHI_E_CONSTRAINT - -#ifdef __cplusplus -extern "C" { -#endif - -{% if dims.nphi_e > 0 %} -int {{ model.name }}_phi_e_constraint(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_phi_e_constraint_work(int *, int *, int *, int *); -const int *{{ model.name }}_phi_e_constraint_sparsity_in(int); -const int *{{ model.name }}_phi_e_constraint_sparsity_out(int); -int {{ model.name }}_phi_e_constraint_n_in(void); -int {{ model.name }}_phi_e_constraint_n_out(void); -{% endif %} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif // {{ model.name }}_PHI_E_CONSTRAINT diff --git a/third_party/acados/acados_template/casadi_function_generation.py b/third_party/acados/acados_template/casadi_function_generation.py new file mode 100644 index 0000000000..6373a2809d --- /dev/null +++ b/third_party/acados/acados_template/casadi_function_generation.py @@ -0,0 +1,708 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + +import os +import casadi as ca +from .utils import is_empty, casadi_length + + +def get_casadi_symbol(x): + if isinstance(x, ca.MX): + return ca.MX.sym + elif isinstance(x, ca.SX): + return ca.SX.sym + else: + raise TypeError("Expected casadi SX or MX.") + +################ +# Dynamics +################ + + +def generate_c_code_discrete_dynamics( model, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + # load model + x = model.x + u = model.u + p = model.p + phi = model.disc_dyn_expr + model_name = model.name + nx = casadi_length(x) + + symbol = get_casadi_symbol(x) + # assume nx1 = nx !!! + lam = symbol('lam', nx, 1) + + # generate jacobians + ux = ca.vertcat(u,x) + jac_ux = ca.jacobian(phi, ux) + # generate adjoint + adj_ux = ca.jtimes(phi, ux, lam, True) + # generate hessian + hess_ux = ca.jacobian(adj_ux, ux) + + # change directory + cwd = os.getcwd() + model_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model_name}_model')) + if not os.path.exists(model_dir): + os.makedirs(model_dir) + os.chdir(model_dir) + + # set up & generate ca.Functions + fun_name = model_name + '_dyn_disc_phi_fun' + phi_fun = ca.Function(fun_name, [x, u, p], [phi]) + phi_fun.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_dyn_disc_phi_fun_jac' + phi_fun_jac_ut_xt = ca.Function(fun_name, [x, u, p], [phi, jac_ux.T]) + phi_fun_jac_ut_xt.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_dyn_disc_phi_fun_jac_hess' + phi_fun_jac_ut_xt_hess = ca.Function(fun_name, [x, u, lam, p], [phi, jac_ux.T, hess_ux]) + phi_fun_jac_ut_xt_hess.generate(fun_name, casadi_codegen_opts) + + os.chdir(cwd) + return + + + +def generate_c_code_explicit_ode( model, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + generate_hess = opts["generate_hess"] + + # load model + x = model.x + u = model.u + p = model.p + f_expl = model.f_expl_expr + model_name = model.name + + ## get model dimensions + nx = x.size()[0] + nu = u.size()[0] + + symbol = get_casadi_symbol(x) + + ## set up functions to be exported + Sx = symbol('Sx', nx, nx) + Sp = symbol('Sp', nx, nu) + lambdaX = symbol('lambdaX', nx, 1) + + fun_name = model_name + '_expl_ode_fun' + + ## Set up functions + expl_ode_fun = ca.Function(fun_name, [x, u, p], [f_expl]) + + vdeX = ca.jtimes(f_expl,x,Sx) + vdeP = ca.jacobian(f_expl,u) + ca.jtimes(f_expl,x,Sp) + + fun_name = model_name + '_expl_vde_forw' + + expl_vde_forw = ca.Function(fun_name, [x, Sx, Sp, u, p], [f_expl, vdeX, vdeP]) + + adj = ca.jtimes(f_expl, ca.vertcat(x, u), lambdaX, True) + + fun_name = model_name + '_expl_vde_adj' + expl_vde_adj = ca.Function(fun_name, [x, lambdaX, u, p], [adj]) + + if generate_hess: + S_forw = ca.vertcat(ca.horzcat(Sx, Sp), ca.horzcat(ca.DM.zeros(nu,nx), ca.DM.eye(nu))) + hess = ca.mtimes(ca.transpose(S_forw),ca.jtimes(adj, ca.vertcat(x,u), S_forw)) + hess2 = [] + for j in range(nx+nu): + for i in range(j,nx+nu): + hess2 = ca.vertcat(hess2, hess[i,j]) + + fun_name = model_name + '_expl_ode_hess' + expl_ode_hess = ca.Function(fun_name, [x, Sx, Sp, lambdaX, u, p], [adj, hess2]) + + # change directory + cwd = os.getcwd() + model_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model_name}_model')) + if not os.path.exists(model_dir): + os.makedirs(model_dir) + os.chdir(model_dir) + + # generate C code + fun_name = model_name + '_expl_ode_fun' + expl_ode_fun.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_expl_vde_forw' + expl_vde_forw.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_expl_vde_adj' + expl_vde_adj.generate(fun_name, casadi_codegen_opts) + + if generate_hess: + fun_name = model_name + '_expl_ode_hess' + expl_ode_hess.generate(fun_name, casadi_codegen_opts) + os.chdir(cwd) + + return + + +def generate_c_code_implicit_ode( model, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + # load model + x = model.x + xdot = model.xdot + u = model.u + z = model.z + p = model.p + f_impl = model.f_impl_expr + model_name = model.name + + # get model dimensions + nx = casadi_length(x) + nz = casadi_length(z) + + # generate jacobians + jac_x = ca.jacobian(f_impl, x) + jac_xdot = ca.jacobian(f_impl, xdot) + jac_u = ca.jacobian(f_impl, u) + jac_z = ca.jacobian(f_impl, z) + + # Set up functions + p = model.p + fun_name = model_name + '_impl_dae_fun' + impl_dae_fun = ca.Function(fun_name, [x, xdot, u, z, p], [f_impl]) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_z' + impl_dae_fun_jac_x_xdot_z = ca.Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_z]) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u_z' + impl_dae_fun_jac_x_xdot_u_z = ca.Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_u, jac_z]) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u' + impl_dae_fun_jac_x_xdot_u = ca.Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_u]) + + fun_name = model_name + '_impl_dae_jac_x_xdot_u_z' + impl_dae_jac_x_xdot_u_z = ca.Function(fun_name, [x, xdot, u, z, p], [jac_x, jac_xdot, jac_u, jac_z]) + + if opts["generate_hess"]: + x_xdot_z_u = ca.vertcat(x, xdot, z, u) + symbol = get_casadi_symbol(x) + multiplier = symbol('multiplier', nx + nz) + ADJ = ca.jtimes(f_impl, x_xdot_z_u, multiplier, True) + HESS = ca.jacobian(ADJ, x_xdot_z_u) + fun_name = model_name + '_impl_dae_hess' + impl_dae_hess = ca.Function(fun_name, [x, xdot, u, z, multiplier, p], [HESS]) + + # change directory + cwd = os.getcwd() + model_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model_name}_model')) + if not os.path.exists(model_dir): + os.makedirs(model_dir) + os.chdir(model_dir) + + # generate C code + fun_name = model_name + '_impl_dae_fun' + impl_dae_fun.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_z' + impl_dae_fun_jac_x_xdot_z.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_impl_dae_jac_x_xdot_u_z' + impl_dae_jac_x_xdot_u_z.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u_z' + impl_dae_fun_jac_x_xdot_u_z.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u' + impl_dae_fun_jac_x_xdot_u.generate(fun_name, casadi_codegen_opts) + + if opts["generate_hess"]: + fun_name = model_name + '_impl_dae_hess' + impl_dae_hess.generate(fun_name, casadi_codegen_opts) + + os.chdir(cwd) + return + + +def generate_c_code_gnsf( model, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + model_name = model.name + + # set up directory + cwd = os.getcwd() + model_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model_name}_model')) + if not os.path.exists(model_dir): + os.makedirs(model_dir) + os.chdir(model_dir) + + # obtain gnsf dimensions + get_matrices_fun = model.get_matrices_fun + phi_fun = model.phi_fun + + size_gnsf_A = get_matrices_fun.size_out(0) + gnsf_nx1 = size_gnsf_A[1] + gnsf_nz1 = size_gnsf_A[0] - size_gnsf_A[1] + gnsf_nuhat = max(phi_fun.size_in(1)) + gnsf_ny = max(phi_fun.size_in(0)) + gnsf_nout = max(phi_fun.size_out(0)) + + # set up expressions + # if the model uses ca.MX because of cost/constraints + # the DAE can be exported as ca.SX -> detect GNSF in Matlab + # -> evaluated ca.SX GNSF functions with ca.MX. + u = model.u + symbol = get_casadi_symbol(u) + + y = symbol("y", gnsf_ny, 1) + uhat = symbol("uhat", gnsf_nuhat, 1) + p = model.p + x1 = symbol("gnsf_x1", gnsf_nx1, 1) + x1dot = symbol("gnsf_x1dot", gnsf_nx1, 1) + z1 = symbol("gnsf_z1", gnsf_nz1, 1) + dummy = symbol("gnsf_dummy", 1, 1) + empty_var = symbol("gnsf_empty_var", 0, 0) + + ## generate C code + fun_name = model_name + '_gnsf_phi_fun' + phi_fun_ = ca.Function(fun_name, [y, uhat, p], [phi_fun(y, uhat, p)]) + phi_fun_.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_gnsf_phi_fun_jac_y' + phi_fun_jac_y = model.phi_fun_jac_y + phi_fun_jac_y_ = ca.Function(fun_name, [y, uhat, p], phi_fun_jac_y(y, uhat, p)) + phi_fun_jac_y_.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_gnsf_phi_jac_y_uhat' + phi_jac_y_uhat = model.phi_jac_y_uhat + phi_jac_y_uhat_ = ca.Function(fun_name, [y, uhat, p], phi_jac_y_uhat(y, uhat, p)) + phi_jac_y_uhat_.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_gnsf_f_lo_fun_jac_x1k1uz' + f_lo_fun_jac_x1k1uz = model.f_lo_fun_jac_x1k1uz + f_lo_fun_jac_x1k1uz_eval = f_lo_fun_jac_x1k1uz(x1, x1dot, z1, u, p) + + # avoid codegeneration issue + if not isinstance(f_lo_fun_jac_x1k1uz_eval, tuple) and is_empty(f_lo_fun_jac_x1k1uz_eval): + f_lo_fun_jac_x1k1uz_eval = [empty_var] + + f_lo_fun_jac_x1k1uz_ = ca.Function(fun_name, [x1, x1dot, z1, u, p], + f_lo_fun_jac_x1k1uz_eval) + f_lo_fun_jac_x1k1uz_.generate(fun_name, casadi_codegen_opts) + + fun_name = model_name + '_gnsf_get_matrices_fun' + get_matrices_fun_ = ca.Function(fun_name, [dummy], get_matrices_fun(1)) + get_matrices_fun_.generate(fun_name, casadi_codegen_opts) + + # remove fields for json dump + del model.phi_fun + del model.phi_fun_jac_y + del model.phi_jac_y_uhat + del model.f_lo_fun_jac_x1k1uz + del model.get_matrices_fun + + os.chdir(cwd) + + return + + +################ +# Cost +################ + +def generate_c_code_external_cost(model, stage_type, opts): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + x = model.x + p = model.p + u = model.u + z = model.z + symbol = get_casadi_symbol(x) + + if stage_type == 'terminal': + suffix_name = "_cost_ext_cost_e_fun" + suffix_name_hess = "_cost_ext_cost_e_fun_jac_hess" + suffix_name_jac = "_cost_ext_cost_e_fun_jac" + ext_cost = model.cost_expr_ext_cost_e + custom_hess = model.cost_expr_ext_cost_custom_hess_e + # Last stage cannot depend on u and z + u = symbol("u", 0, 0) + z = symbol("z", 0, 0) + + elif stage_type == 'path': + suffix_name = "_cost_ext_cost_fun" + suffix_name_hess = "_cost_ext_cost_fun_jac_hess" + suffix_name_jac = "_cost_ext_cost_fun_jac" + ext_cost = model.cost_expr_ext_cost + custom_hess = model.cost_expr_ext_cost_custom_hess + + elif stage_type == 'initial': + suffix_name = "_cost_ext_cost_0_fun" + suffix_name_hess = "_cost_ext_cost_0_fun_jac_hess" + suffix_name_jac = "_cost_ext_cost_0_fun_jac" + ext_cost = model.cost_expr_ext_cost_0 + custom_hess = model.cost_expr_ext_cost_custom_hess_0 + + nunx = x.shape[0] + u.shape[0] + + # set up functions to be exported + fun_name = model.name + suffix_name + fun_name_hess = model.name + suffix_name_hess + fun_name_jac = model.name + suffix_name_jac + + # generate expression for full gradient and Hessian + hess_uxz, grad_uxz = ca.hessian(ext_cost, ca.vertcat(u, x, z)) + + hess_ux = hess_uxz[:nunx, :nunx] + hess_z = hess_uxz[nunx:, nunx:] + hess_z_ux = hess_uxz[nunx:, :nunx] + + if custom_hess is not None: + hess_ux = custom_hess + + ext_cost_fun = ca.Function(fun_name, [x, u, z, p], [ext_cost]) + + ext_cost_fun_jac_hess = ca.Function( + fun_name_hess, [x, u, z, p], [ext_cost, grad_uxz, hess_ux, hess_z, hess_z_ux] + ) + ext_cost_fun_jac = ca.Function( + fun_name_jac, [x, u, z, p], [ext_cost, grad_uxz] + ) + + # change directory + cwd = os.getcwd() + cost_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model.name}_cost')) + if not os.path.exists(cost_dir): + os.makedirs(cost_dir) + os.chdir(cost_dir) + + ext_cost_fun.generate(fun_name, casadi_codegen_opts) + ext_cost_fun_jac_hess.generate(fun_name_hess, casadi_codegen_opts) + ext_cost_fun_jac.generate(fun_name_jac, casadi_codegen_opts) + + os.chdir(cwd) + return + + +def generate_c_code_nls_cost( model, cost_name, stage_type, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + x = model.x + z = model.z + p = model.p + u = model.u + + symbol = get_casadi_symbol(x) + + if stage_type == 'terminal': + middle_name = '_cost_y_e' + u = symbol('u', 0, 0) + y_expr = model.cost_y_expr_e + + elif stage_type == 'initial': + middle_name = '_cost_y_0' + y_expr = model.cost_y_expr_0 + + elif stage_type == 'path': + middle_name = '_cost_y' + y_expr = model.cost_y_expr + + # change directory + cwd = os.getcwd() + cost_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model.name}_cost')) + if not os.path.exists(cost_dir): + os.makedirs(cost_dir) + os.chdir(cost_dir) + + # set up expressions + cost_jac_expr = ca.transpose(ca.jacobian(y_expr, ca.vertcat(u, x))) + dy_dz = ca.jacobian(y_expr, z) + ny = casadi_length(y_expr) + + y = symbol('y', ny, 1) + + y_adj = ca.jtimes(y_expr, ca.vertcat(u, x), y, True) + y_hess = ca.jacobian(y_adj, ca.vertcat(u, x)) + + ## generate C code + suffix_name = '_fun' + fun_name = cost_name + middle_name + suffix_name + y_fun = ca.Function( fun_name, [x, u, z, p], [ y_expr ]) + y_fun.generate( fun_name, casadi_codegen_opts ) + + suffix_name = '_fun_jac_ut_xt' + fun_name = cost_name + middle_name + suffix_name + y_fun_jac_ut_xt = ca.Function(fun_name, [x, u, z, p], [ y_expr, cost_jac_expr, dy_dz ]) + y_fun_jac_ut_xt.generate( fun_name, casadi_codegen_opts ) + + suffix_name = '_hess' + fun_name = cost_name + middle_name + suffix_name + y_hess = ca.Function(fun_name, [x, u, z, y, p], [ y_hess ]) + y_hess.generate( fun_name, casadi_codegen_opts ) + + os.chdir(cwd) + + return + + + +def generate_c_code_conl_cost(model, cost_name, stage_type, opts): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + x = model.x + z = model.z + p = model.p + + symbol = get_casadi_symbol(x) + + if stage_type == 'terminal': + u = symbol('u', 0, 0) + + yref = model.cost_r_in_psi_expr_e + inner_expr = model.cost_y_expr_e - yref + outer_expr = model.cost_psi_expr_e + res_expr = model.cost_r_in_psi_expr_e + + suffix_name_fun = '_conl_cost_e_fun' + suffix_name_fun_jac_hess = '_conl_cost_e_fun_jac_hess' + + custom_hess = model.cost_conl_custom_outer_hess_e + + elif stage_type == 'initial': + u = model.u + + yref = model.cost_r_in_psi_expr_0 + inner_expr = model.cost_y_expr_0 - yref + outer_expr = model.cost_psi_expr_0 + res_expr = model.cost_r_in_psi_expr_0 + + suffix_name_fun = '_conl_cost_0_fun' + suffix_name_fun_jac_hess = '_conl_cost_0_fun_jac_hess' + + custom_hess = model.cost_conl_custom_outer_hess_0 + + elif stage_type == 'path': + u = model.u + + yref = model.cost_r_in_psi_expr + inner_expr = model.cost_y_expr - yref + outer_expr = model.cost_psi_expr + res_expr = model.cost_r_in_psi_expr + + suffix_name_fun = '_conl_cost_fun' + suffix_name_fun_jac_hess = '_conl_cost_fun_jac_hess' + + custom_hess = model.cost_conl_custom_outer_hess + + # set up function names + fun_name_cost_fun = model.name + suffix_name_fun + fun_name_cost_fun_jac_hess = model.name + suffix_name_fun_jac_hess + + # set up functions to be exported + outer_loss_fun = ca.Function('psi', [res_expr, p], [outer_expr]) + cost_expr = outer_loss_fun(inner_expr, p) + + outer_loss_grad_fun = ca.Function('outer_loss_grad', [res_expr, p], [ca.jacobian(outer_expr, res_expr).T]) + + if custom_hess is None: + outer_hess_fun = ca.Function('inner_hess', [res_expr, p], [ca.hessian(outer_loss_fun(res_expr, p), res_expr)[0]]) + else: + outer_hess_fun = ca.Function('inner_hess', [res_expr, p], [custom_hess]) + + Jt_ux_expr = ca.jacobian(inner_expr, ca.vertcat(u, x)).T + Jt_z_expr = ca.jacobian(inner_expr, z).T + + cost_fun = ca.Function( + fun_name_cost_fun, + [x, u, z, yref, p], + [cost_expr]) + + cost_fun_jac_hess = ca.Function( + fun_name_cost_fun_jac_hess, + [x, u, z, yref, p], + [cost_expr, outer_loss_grad_fun(inner_expr, p), Jt_ux_expr, Jt_z_expr, outer_hess_fun(inner_expr, p)] + ) + # change directory + cwd = os.getcwd() + cost_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model.name}_cost')) + if not os.path.exists(cost_dir): + os.makedirs(cost_dir) + os.chdir(cost_dir) + + # generate C code + cost_fun.generate(fun_name_cost_fun, casadi_codegen_opts) + cost_fun_jac_hess.generate(fun_name_cost_fun_jac_hess, casadi_codegen_opts) + + os.chdir(cwd) + + return + + +################ +# Constraints +################ +def generate_c_code_constraint( model, con_name, is_terminal, opts ): + + casadi_codegen_opts = dict(mex=False, casadi_int='int', casadi_real='double') + + # load constraint variables and expression + x = model.x + p = model.p + + symbol = get_casadi_symbol(x) + + if is_terminal: + con_h_expr = model.con_h_expr_e + con_phi_expr = model.con_phi_expr_e + # create dummy u, z + u = symbol('u', 0, 0) + z = symbol('z', 0, 0) + else: + con_h_expr = model.con_h_expr + con_phi_expr = model.con_phi_expr + u = model.u + z = model.z + + if (not is_empty(con_h_expr)) and (not is_empty(con_phi_expr)): + raise Exception("acados: you can either have constraint_h, or constraint_phi, not both.") + + if (is_empty(con_h_expr) and is_empty(con_phi_expr)): + # both empty -> nothing to generate + return + + if is_empty(con_h_expr): + constr_type = 'BGP' + else: + constr_type = 'BGH' + + if is_empty(p): + p = symbol('p', 0, 0) + + if is_empty(z): + z = symbol('z', 0, 0) + + if not (is_empty(con_h_expr)) and opts['generate_hess']: + # multipliers for hessian + nh = casadi_length(con_h_expr) + lam_h = symbol('lam_h', nh, 1) + + # set up & change directory + cwd = os.getcwd() + constraints_dir = os.path.abspath(os.path.join(opts["code_export_directory"], f'{model.name}_constraints')) + if not os.path.exists(constraints_dir): + os.makedirs(constraints_dir) + os.chdir(constraints_dir) + + # export casadi functions + if constr_type == 'BGH': + if is_terminal: + fun_name = con_name + '_constr_h_e_fun_jac_uxt_zt' + else: + fun_name = con_name + '_constr_h_fun_jac_uxt_zt' + + jac_ux_t = ca.transpose(ca.jacobian(con_h_expr, ca.vertcat(u,x))) + jac_z_t = ca.jacobian(con_h_expr, z) + constraint_fun_jac_tran = ca.Function(fun_name, [x, u, z, p], \ + [con_h_expr, jac_ux_t, jac_z_t]) + + constraint_fun_jac_tran.generate(fun_name, casadi_codegen_opts) + if opts['generate_hess']: + + if is_terminal: + fun_name = con_name + '_constr_h_e_fun_jac_uxt_zt_hess' + else: + fun_name = con_name + '_constr_h_fun_jac_uxt_zt_hess' + + # adjoint + adj_ux = ca.jtimes(con_h_expr, ca.vertcat(u, x), lam_h, True) + # hessian + hess_ux = ca.jacobian(adj_ux, ca.vertcat(u, x)) + + adj_z = ca.jtimes(con_h_expr, z, lam_h, True) + hess_z = ca.jacobian(adj_z, z) + + # set up functions + constraint_fun_jac_tran_hess = \ + ca.Function(fun_name, [x, u, lam_h, z, p], \ + [con_h_expr, jac_ux_t, hess_ux, jac_z_t, hess_z]) + + # generate C code + constraint_fun_jac_tran_hess.generate(fun_name, casadi_codegen_opts) + + if is_terminal: + fun_name = con_name + '_constr_h_e_fun' + else: + fun_name = con_name + '_constr_h_fun' + h_fun = ca.Function(fun_name, [x, u, z, p], [con_h_expr]) + h_fun.generate(fun_name, casadi_codegen_opts) + + else: # BGP constraint + if is_terminal: + fun_name = con_name + '_phi_e_constraint' + r = model.con_r_in_phi_e + con_r_expr = model.con_r_expr_e + else: + fun_name = con_name + '_phi_constraint' + r = model.con_r_in_phi + con_r_expr = model.con_r_expr + + nphi = casadi_length(con_phi_expr) + con_phi_expr_x_u_z = ca.substitute(con_phi_expr, r, con_r_expr) + phi_jac_u = ca.jacobian(con_phi_expr_x_u_z, u) + phi_jac_x = ca.jacobian(con_phi_expr_x_u_z, x) + phi_jac_z = ca.jacobian(con_phi_expr_x_u_z, z) + + hess = ca.hessian(con_phi_expr[0], r)[0] + for i in range(1, nphi): + hess = ca.vertcat(hess, ca.hessian(con_phi_expr[i], r)[0]) + + r_jac_u = ca.jacobian(con_r_expr, u) + r_jac_x = ca.jacobian(con_r_expr, x) + + constraint_phi = \ + ca.Function(fun_name, [x, u, z, p], \ + [con_phi_expr_x_u_z, \ + ca.vertcat(ca.transpose(phi_jac_u), ca.transpose(phi_jac_x)), \ + ca.transpose(phi_jac_z), \ + hess, + ca.vertcat(ca.transpose(r_jac_u), ca.transpose(r_jac_x))]) + + constraint_phi.generate(fun_name, casadi_codegen_opts) + + # change directory back + os.chdir(cwd) + + return + diff --git a/third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.c b/third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.c new file mode 100644 index 0000000000..b39ff2e23b --- /dev/null +++ b/third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.c @@ -0,0 +1,819 @@ +/* + * Copyright (c) The acados authors. + * + * This file is part of acados. + * + * The 2-Clause BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.; + */ + +// This is a template based custom_update function +#include +#include +#include +#include + +#include "custom_update_function.h" +#include "acados_solver_{{ model.name }}.h" +#include "acados_c/ocp_nlp_interface.h" +#include "acados/utils/mem.h" + +#include "blasfeo/include/blasfeo_d_aux_ext_dep.h" +#include "blasfeo/include/blasfeo_d_blasfeo_api.h" + + +typedef struct custom_memory +{ + // covariance matrics + struct blasfeo_dmat *uncertainty_matrix_buffer; // shape = (N+1, nx, nx) + // covariance matrix of the additive disturbance + struct blasfeo_dmat W_mat; // shape = (nw, nw) + struct blasfeo_dmat unc_jac_G_mat; // shape = (nx, nw) + struct blasfeo_dmat temp_GW_mat; // shape = (nx, nw) + struct blasfeo_dmat GWG_mat; // shape = (nx, nx) + // sensitivity matrices + struct blasfeo_dmat A_mat; // shape = (nx, nx) + struct blasfeo_dmat B_mat; // shape = (nx, nu) + // matrix in linear constraints + struct blasfeo_dmat Cg_mat; // shape = (ng, nx) + struct blasfeo_dmat Dg_mat; // shape = (ng, nu) + struct blasfeo_dmat Cg_e_mat; // shape = (ng_e, nx) + struct blasfeo_dmat dummy_Dgh_e_mat; // shape = (ngh_e_max, nu) + // matrix in nonlinear constraints + struct blasfeo_dmat Ch_mat; // shape = (nh, nx) + struct blasfeo_dmat Dh_mat; // shape = (nh, nu) + struct blasfeo_dmat Ch_e_mat; // shape = (nh_e, nx) + // feedback gain matrix + struct blasfeo_dmat K_mat; // shape = (nu, nx) + // AK = A - B@K + struct blasfeo_dmat AK_mat; // shape = (nx, nx) + // A@P_k + struct blasfeo_dmat temp_AP_mat; // shape = (nx, nx) + // K@P_k, K@P_k@K^T + struct blasfeo_dmat temp_KP_mat; // shape = (nu, nx) + struct blasfeo_dmat temp_KPK_mat; // shape = (nu, nu) + // C + D @ K, (C + D @ K) @ P_k + struct blasfeo_dmat temp_CaDK_mat; // shape = (ngh_me_max, nx) + struct blasfeo_dmat temp_CaDKmP_mat; // shape = (ngh_me_max, nx) + struct blasfeo_dmat temp_beta_mat; // shape = (ngh_me_max, ngh_me_max) + + double *d_A_mat; // shape = (nx, nx) + double *d_B_mat; // shape = (nx, nu) + double *d_Cg_mat; // shape = (ng, nx) + double *d_Dg_mat; // shape = (ng, nu) + double *d_Cg_e_mat; // shape = (ng_e, nx) + double *d_Cgh_mat; // shape = (ng+nh, nx) + double *d_Dgh_mat; // shape = (ng+nh, nu) + double *d_Cgh_e_mat; // shape = (ng_e+nh_e, nx) + double *d_state_vec; + // upper and lower bounds on state variables + double *d_lbx; // shape = (nbx,) + double *d_ubx; // shape = (nbx,) + double *d_lbx_e; // shape = (nbx_e,) + double *d_ubx_e; // shape = (nbx_e,) + // tightened upper and lower bounds on state variables + double *d_lbx_tightened; // shape = (nbx,) + double *d_ubx_tightened; // shape = (nbx,) + double *d_lbx_e_tightened; // shape = (nbx_e,) + double *d_ubx_e_tightened; // shape = (nbx_e,) + // upper and lower bounds on control inputs + double *d_lbu; // shape = (nbu,) + double *d_ubu; // shape = (nbu,) + // tightened upper and lower bounds on control inputs + double *d_lbu_tightened; // shape = (nbu,) + double *d_ubu_tightened; // shape = (nbu,) + // upper and lower bounds on polytopic constraints + double *d_lg; // shape = (ng,) + double *d_ug; // shape = (ng,) + double *d_lg_e; // shape = (ng_e,) + double *d_ug_e; // shape = (ng_e,) + // tightened lower bounds on polytopic constraints + double *d_lg_tightened; // shape = (ng,) + double *d_ug_tightened; // shape = (ng,) + double *d_lg_e_tightened; // shape = (ng_e,) + double *d_ug_e_tightened; // shape = (ng_e,) + // upper and lower bounds on nonlinear constraints + double *d_lh; // shape = (nh,) + double *d_uh; // shape = (nh,) + double *d_lh_e; // shape = (nh_e,) + double *d_uh_e; // shape = (nh_e,) + // tightened upper and lower bounds on nonlinear constraints + double *d_lh_tightened; // shape = (nh,) + double *d_uh_tightened; // shape = (nh,) + double *d_lh_e_tightened; // shape = (nh_e,) + double *d_uh_e_tightened; // shape = (nh_e,) + + int *idxbx; // shape = (nbx,) + int *idxbu; // shape = (nbu,) + int *idxbx_e; // shape = (nbx_e,) + + void *raw_memory; // Pointer to allocated memory, to be used for freeing +} custom_memory; + +static int int_max(int num1, int num2) +{ + return (num1 > num2 ) ? num1 : num2; +} + + +static int custom_memory_calculate_size(ocp_nlp_config *nlp_config, ocp_nlp_dims *nlp_dims) +{ + int N = nlp_dims->N; + int nx = {{ dims.nx }}; + int nu = {{ dims.nu }}; + int nw = {{ zoro_description.nw }}; + + int ng = {{ dims.ng }}; + int nh = {{ dims.nh }}; + int nbx = {{ dims.nbx }}; + int nbu = {{ dims.nbu }}; + + int ng_e = {{ dims.ng_e }}; + int nh_e = {{ dims.nh_e }}; + int ngh_e_max = int_max(ng_e, nh_e); + int ngh_me_max = int_max(ngh_e_max, int_max(ng, nh)); + int nbx_e = {{ dims.nbx_e }}; + + assert({{zoro_description.nlbx_t}} <= nbx); + assert({{zoro_description.nubx_t}} <= nbx); + assert({{zoro_description.nlbu_t}} <= nbu); + assert({{zoro_description.nubu_t}} <= nbu); + assert({{zoro_description.nlg_t}} <= ng); + assert({{zoro_description.nug_t}} <= ng); + assert({{zoro_description.nlh_t}} <= nh); + assert({{zoro_description.nuh_t}} <= nh); + assert({{zoro_description.nlbx_e_t}} <= nbx_e); + assert({{zoro_description.nubx_e_t}} <= nbx_e); + assert({{zoro_description.nlg_e_t}} <= ng_e); + assert({{zoro_description.nug_e_t}} <= ng_e); + assert({{zoro_description.nlh_e_t}} <= nh_e); + assert({{zoro_description.nuh_e_t}} <= nh_e); + + acados_size_t size = sizeof(custom_memory); + size += nbx * sizeof(int); + /* blasfeo structs */ + size += (N + 1) * sizeof(struct blasfeo_dmat); + /* blasfeo mem: mat */ + size += (N + 1) * blasfeo_memsize_dmat(nx, nx); // uncertainty_matrix_buffer + size += blasfeo_memsize_dmat(nw, nw); // W_mat + size += 2 * blasfeo_memsize_dmat(nx, nw); // unc_jac_G_mat, temp_GW_mat + size += 4 * blasfeo_memsize_dmat(nx, nx); // GWG_mat, A_mat, AK_mat, temp_AP_mat + size += blasfeo_memsize_dmat(nx, nu); // B_mat + size += 2 * blasfeo_memsize_dmat(nu, nx); // K_mat, temp_KP_mat + size += blasfeo_memsize_dmat(nu, nu); // temp_KPK_mat + size += blasfeo_memsize_dmat(ng, nx); // Cg_mat + size += blasfeo_memsize_dmat(ng, nu); // Dg_mat + size += blasfeo_memsize_dmat(ng_e, nx); // Cg_e_mat + size += blasfeo_memsize_dmat(ngh_e_max, nu); // dummy_Dgh_e_mat + size += blasfeo_memsize_dmat(nh, nx); // Ch_mat + size += blasfeo_memsize_dmat(nh, nu); // Dh_mat + size += blasfeo_memsize_dmat(nh_e, nx); // Ch_e_mat + size += 2 * blasfeo_memsize_dmat(ngh_me_max, nx); // temp_CaDK_mat, temp_CaDKmP_mat + size += blasfeo_memsize_dmat(ngh_me_max, ngh_me_max); // temp_beta_mat + /* blasfeo mem: vec */ + /* Arrays */ + size += nx*nx *sizeof(double); // d_A_mat + size += nx*nu *sizeof(double); // d_B_mat + size += (ng + ng_e) * nx * sizeof(double); // d_Cg_mat, d_Cg_e_mat + size += (ng) * nu * sizeof(double); // d_Dg_mat + size += (nh + nh_e + ng + ng_e) * nx * sizeof(double); // d_Cgh_mat, d_Cgh_e_mat + size += (nh + ng) * nu * sizeof(double); // d_Dgh_mat + // d_state_vec + size += nx *sizeof(double); + // constraints and tightened constraints + size += 4 * (nbx + nbu + ng + nh)*sizeof(double); + size += 4 * (nbx_e + ng_e + nh_e)*sizeof(double); + size += (nbx + nbu + nbx_e)*sizeof(int); // idxbx, idxbu, idxbx_e + + size += 1 * 8; // initial alignment + make_int_multiple_of(64, &size); + size += 1 * 64; + + return size; +} + + +static custom_memory *custom_memory_assign(ocp_nlp_config *nlp_config, ocp_nlp_dims *nlp_dims, void *raw_memory) +{ + int N = nlp_dims->N; + int nx = {{ dims.nx }}; + int nu = {{ dims.nu }}; + int nw = {{ zoro_description.nw }}; + + int ng = {{ dims.ng }}; + int nh = {{ dims.nh }}; + int nbx = {{ dims.nbx }}; + int nbu = {{ dims.nbu }}; + + int ng_e = {{ dims.ng_e }}; + int nh_e = {{ dims.nh_e }}; + int ngh_e_max = int_max(ng_e, nh_e); + int ngh_me_max = int_max(ngh_e_max, int_max(ng, nh)); + int nbx_e = {{ dims.nbx_e }}; + + char *c_ptr = (char *) raw_memory; + custom_memory *mem = (custom_memory *) c_ptr; + c_ptr += sizeof(custom_memory); + + align_char_to(8, &c_ptr); + assign_and_advance_blasfeo_dmat_structs(N+1, &mem->uncertainty_matrix_buffer, &c_ptr); + + align_char_to(64, &c_ptr); + + for (int ii = 0; ii <= N; ii++) + { + assign_and_advance_blasfeo_dmat_mem(nx, nx, &mem->uncertainty_matrix_buffer[ii], &c_ptr); + } + // Disturbance Dynamics + assign_and_advance_blasfeo_dmat_mem(nw, nw, &mem->W_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nw, &mem->unc_jac_G_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nw, &mem->temp_GW_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nx, &mem->GWG_mat, &c_ptr); + // System Dynamics + assign_and_advance_blasfeo_dmat_mem(nx, nx, &mem->A_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nu, &mem->B_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ng, nx, &mem->Cg_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ng, nu, &mem->Dg_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ng_e, nx, &mem->Cg_e_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ngh_e_max, nu, &mem->dummy_Dgh_e_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nh, nx, &mem->Ch_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nh, nu, &mem->Dh_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nh_e, nx, &mem->Ch_e_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nu, nx, &mem->K_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nx, &mem->AK_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nx, nx, &mem->temp_AP_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nu, nx, &mem->temp_KP_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(nu, nu, &mem->temp_KPK_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ngh_me_max, nx, &mem->temp_CaDK_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ngh_me_max, nx, &mem->temp_CaDKmP_mat, &c_ptr); + assign_and_advance_blasfeo_dmat_mem(ngh_me_max, ngh_me_max, &mem->temp_beta_mat, &c_ptr); + + assign_and_advance_double(nx*nx, &mem->d_A_mat, &c_ptr); + assign_and_advance_double(nx*nu, &mem->d_B_mat, &c_ptr); + assign_and_advance_double(ng*nx, &mem->d_Cg_mat, &c_ptr); + assign_and_advance_double(ng*nu, &mem->d_Dg_mat, &c_ptr); + assign_and_advance_double(ng_e*nx, &mem->d_Cg_e_mat, &c_ptr); + assign_and_advance_double((ng + nh)*nx, &mem->d_Cgh_mat, &c_ptr); + assign_and_advance_double((ng + nh)*nu, &mem->d_Dgh_mat, &c_ptr); + assign_and_advance_double((ng_e + nh_e)*nx, &mem->d_Cgh_e_mat, &c_ptr); + assign_and_advance_double(nx, &mem->d_state_vec, &c_ptr); + assign_and_advance_double(nbx, &mem->d_lbx, &c_ptr); + assign_and_advance_double(nbx, &mem->d_ubx, &c_ptr); + assign_and_advance_double(nbx_e, &mem->d_lbx_e, &c_ptr); + assign_and_advance_double(nbx_e, &mem->d_ubx_e, &c_ptr); + assign_and_advance_double(nbx, &mem->d_lbx_tightened, &c_ptr); + assign_and_advance_double(nbx, &mem->d_ubx_tightened, &c_ptr); + assign_and_advance_double(nbx_e, &mem->d_lbx_e_tightened, &c_ptr); + assign_and_advance_double(nbx_e, &mem->d_ubx_e_tightened, &c_ptr); + assign_and_advance_double(nbu, &mem->d_lbu, &c_ptr); + assign_and_advance_double(nbu, &mem->d_ubu, &c_ptr); + assign_and_advance_double(nbu, &mem->d_lbu_tightened, &c_ptr); + assign_and_advance_double(nbu, &mem->d_ubu_tightened, &c_ptr); + assign_and_advance_double(ng, &mem->d_lg, &c_ptr); + assign_and_advance_double(ng, &mem->d_ug, &c_ptr); + assign_and_advance_double(ng_e, &mem->d_lg_e, &c_ptr); + assign_and_advance_double(ng_e, &mem->d_ug_e, &c_ptr); + assign_and_advance_double(ng, &mem->d_lg_tightened, &c_ptr); + assign_and_advance_double(ng, &mem->d_ug_tightened, &c_ptr); + assign_and_advance_double(ng_e, &mem->d_lg_e_tightened, &c_ptr); + assign_and_advance_double(ng_e, &mem->d_ug_e_tightened, &c_ptr); + assign_and_advance_double(nh, &mem->d_lh, &c_ptr); + assign_and_advance_double(nh, &mem->d_uh, &c_ptr); + assign_and_advance_double(nh_e, &mem->d_lh_e, &c_ptr); + assign_and_advance_double(nh_e, &mem->d_uh_e, &c_ptr); + assign_and_advance_double(nh, &mem->d_lh_tightened, &c_ptr); + assign_and_advance_double(nh, &mem->d_uh_tightened, &c_ptr); + assign_and_advance_double(nh_e, &mem->d_lh_e_tightened, &c_ptr); + assign_and_advance_double(nh_e, &mem->d_uh_e_tightened, &c_ptr); + + assign_and_advance_int(nbx, &mem->idxbx, &c_ptr); + assign_and_advance_int(nbu, &mem->idxbu, &c_ptr); + assign_and_advance_int(nbx_e, &mem->idxbx_e, &c_ptr); + + assert((char *) raw_memory + custom_memory_calculate_size(nlp_config, nlp_dims) >= c_ptr); + mem->raw_memory = raw_memory; + + return mem; +} + + + +static void *custom_memory_create({{ model.name }}_solver_capsule* capsule) +{ + printf("\nin custom_memory_create_function\n"); + + ocp_nlp_dims *nlp_dims = {{ model.name }}_acados_get_nlp_dims(capsule); + ocp_nlp_config *nlp_config = {{ model.name }}_acados_get_nlp_config(capsule); + acados_size_t bytes = custom_memory_calculate_size(nlp_config, nlp_dims); + + void *ptr = acados_calloc(1, bytes); + + custom_memory *custom_mem = custom_memory_assign(nlp_config, nlp_dims, ptr); + custom_mem->raw_memory = ptr; + + return custom_mem; +} + + +static void custom_val_init_function(ocp_nlp_dims *nlp_dims, ocp_nlp_in *nlp_in, ocp_nlp_solver *nlp_solver, custom_memory *custom_mem) +{ + int N = nlp_dims->N; + int nx = {{ dims.nx }}; + int nu = {{ dims.nu }}; + int nw = {{ zoro_description.nw }}; + + int ng = {{ dims.ng }}; + int nh = {{ dims.nh }}; + int nbx = {{ dims.nbx }}; + int nbu = {{ dims.nbu }}; + + int ng_e = {{ dims.ng_e }}; + int nh_e = {{ dims.nh_e }}; + int ngh_e_max = int_max(ng_e, nh_e); + int nbx_e = {{ dims.nbx_e }}; + + /* Get the state constraint bounds */ + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "idxbx", custom_mem->idxbx); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "idxbx", custom_mem->idxbx_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lbx", custom_mem->d_lbx); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ubx", custom_mem->d_ubx); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lbx", custom_mem->d_lbx_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "ubx", custom_mem->d_ubx_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "idxbu", custom_mem->idxbu); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lbu", custom_mem->d_lbu); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ubu", custom_mem->d_ubu); + // Get the Jacobians and the bounds of the linear constraints + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lg", custom_mem->d_lg); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ug", custom_mem->d_ug); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lg", custom_mem->d_lg_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "ug", custom_mem->d_ug_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "C", custom_mem->d_Cg_mat); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "D", custom_mem->d_Dg_mat); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "C", custom_mem->d_Cg_e_mat); + blasfeo_pack_dmat(ng, nx, custom_mem->d_Cg_mat, ng, &custom_mem->Cg_mat, 0, 0); + blasfeo_pack_dmat(ng, nu, custom_mem->d_Dg_mat, ng, &custom_mem->Dg_mat, 0, 0); + blasfeo_pack_dmat(ng_e, nx, custom_mem->d_Cg_e_mat, ng_e, &custom_mem->Cg_e_mat, 0, 0); + blasfeo_dgese(ngh_e_max, nu, 0., &custom_mem->dummy_Dgh_e_mat, 0, 0); //fill with zeros + // NOTE: fixed lower and upper bounds of nonlinear constraints + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lh", custom_mem->d_lh); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "uh", custom_mem->d_uh); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lh", custom_mem->d_lh_e); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "uh", custom_mem->d_uh_e); + + /* Initilize tightened constraints*/ + // NOTE: tightened constraints are only initialized once + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lbx", custom_mem->d_lbx_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ubx", custom_mem->d_ubx_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lbx", custom_mem->d_lbx_e_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "ubx", custom_mem->d_ubx_e_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lbu", custom_mem->d_lbu_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ubu", custom_mem->d_ubu_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lg", custom_mem->d_lg_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "ug", custom_mem->d_ug_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lg", custom_mem->d_lg_e_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "ug", custom_mem->d_ug_e_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "lh", custom_mem->d_lh_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, 1, "uh", custom_mem->d_uh_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "lh", custom_mem->d_lh_e_tightened); + ocp_nlp_constraints_model_get(nlp_solver->config, nlp_dims, nlp_in, N, "uh", custom_mem->d_uh_e_tightened); + + /* Initialize the W matrix */ + // blasfeo_dgese(nw, nw, 0., &custom_mem->W_mat, 0, 0); +{%- for ir in range(end=zoro_description.nw) %} + {%- for ic in range(end=zoro_description.nw) %} + blasfeo_dgein1({{zoro_description.W_mat[ir][ic]}}, &custom_mem->W_mat, {{ir}}, {{ic}}); + {%- endfor %} +{%- endfor %} + +{%- for ir in range(end=dims.nx) %} + {%- for ic in range(end=zoro_description.nw) %} + blasfeo_dgein1({{zoro_description.unc_jac_G_mat[ir][ic]}}, &custom_mem->unc_jac_G_mat, {{ir}}, {{ic}}); + {%- endfor %} +{%- endfor %} + + // NOTE: if G is changing this is not in init! + // temp_GW_mat = unc_jac_G_mat * W_mat + blasfeo_dgemm_nn(nx, nw, nw, 1.0, &custom_mem->unc_jac_G_mat, 0, 0, + &custom_mem->W_mat, 0, 0, 0.0, + &custom_mem->temp_GW_mat, 0, 0, &custom_mem->temp_GW_mat, 0, 0); + // GWG_mat = temp_GW_mat * unc_jac_G_mat^T + blasfeo_dgemm_nt(nx, nx, nw, 1.0, &custom_mem->temp_GW_mat, 0, 0, + &custom_mem->unc_jac_G_mat, 0, 0, 0.0, + &custom_mem->GWG_mat, 0, 0, &custom_mem->GWG_mat, 0, 0); + + /* Initialize the uncertainty_matrix_buffer[0] */ +{%- for ir in range(end=dims.nx) %} + {%- for ic in range(end=dims.nx) %} + blasfeo_dgein1({{zoro_description.P0_mat[ir][ic]}}, &custom_mem->uncertainty_matrix_buffer[0], {{ir}}, {{ic}}); + {%- endfor %} +{%- endfor %} + + /* Initialize the feedback gain matrix */ +{%- for ir in range(end=dims.nu) %} + {%- for ic in range(end=dims.nx) %} + blasfeo_dgein1({{zoro_description.fdbk_K_mat[ir][ic]}}, &custom_mem->K_mat, {{ir}}, {{ic}}); + {%- endfor %} +{%- endfor %} +} + + +int custom_update_init_function({{ model.name }}_solver_capsule* capsule) +{ + capsule->custom_update_memory = custom_memory_create(capsule); + ocp_nlp_in *nlp_in = {{ model.name }}_acados_get_nlp_in(capsule); + + ocp_nlp_dims *nlp_dims = {{ model.name }}_acados_get_nlp_dims(capsule); + ocp_nlp_solver *nlp_solver = {{ model.name }}_acados_get_nlp_solver(capsule); + custom_val_init_function(nlp_dims, nlp_in, nlp_solver, capsule->custom_update_memory); + return 1; +} + +static void compute_gh_beta(struct blasfeo_dmat* K_mat, struct blasfeo_dmat* C_mat, + struct blasfeo_dmat* D_mat, struct blasfeo_dmat* CaDK_mat, + struct blasfeo_dmat* CaDKmP_mat, struct blasfeo_dmat* beta_mat, + struct blasfeo_dmat* P_mat, + int n_cstr, int nx, int nu) +{ + // (C+DK)@P@(C^T+K^TD^T) + // CaDK_mat = C_mat + D_mat @ K_mat + blasfeo_dgemm_nn(n_cstr, nx, nu, 1.0, D_mat, 0, 0, + K_mat, 0, 0, 1.0, + C_mat, 0, 0, CaDK_mat, 0, 0); + // CaDKmP_mat = CaDK_mat @ P_mat + blasfeo_dgemm_nn(n_cstr, nx, nx, 1.0, CaDK_mat, 0, 0, + P_mat, 0, 0, 0.0, + CaDKmP_mat, 0, 0, CaDKmP_mat, 0, 0); + // beta_mat = CaDKmP_mat @ CaDK_mat^T + blasfeo_dgemm_nt(n_cstr, n_cstr, nx, 1.0, CaDKmP_mat, 0, 0, + CaDK_mat, 0, 0, 0.0, + beta_mat, 0, 0, beta_mat, 0, 0); +} + +static void compute_KPK(struct blasfeo_dmat* K_mat, struct blasfeo_dmat* temp_KP_mat, + struct blasfeo_dmat* temp_KPK_mat, struct blasfeo_dmat* P_mat, + int nx, int nu) +{ + // K @ P_k @ K^T + // temp_KP_mat = K_mat @ P_mat + blasfeo_dgemm_nn(nu, nx, nx, 1.0, K_mat, 0, 0, + P_mat, 0, 0, 0.0, + temp_KP_mat, 0, 0, temp_KP_mat, 0, 0); + // temp_KPK_mat = temp_KP_mat @ K_mat^T + blasfeo_dgemm_nt(nu, nu, nx, 1.0, temp_KP_mat, 0, 0, + K_mat, 0, 0, 0.0, + temp_KPK_mat, 0, 0, temp_KPK_mat, 0, 0); +} + +static void compute_next_P_matrix(struct blasfeo_dmat* P_mat, struct blasfeo_dmat* P_next_mat, + struct blasfeo_dmat* A_mat, struct blasfeo_dmat* B_mat, + struct blasfeo_dmat* K_mat, struct blasfeo_dmat* W_mat, + struct blasfeo_dmat* AK_mat, struct blasfeo_dmat* temp_AP_mat, int nx, int nu) +{ + // AK_mat = -B@K + A + blasfeo_dgemm_nn(nx, nx, nu, -1.0, B_mat, 0, 0, K_mat, 0, 0, + 1.0, A_mat, 0, 0, AK_mat, 0, 0); + // temp_AP_mat = AK_mat @ P_k + blasfeo_dgemm_nn(nx, nx, nx, 1.0, AK_mat, 0, 0, + P_mat, 0, 0, 0.0, + temp_AP_mat, 0, 0, temp_AP_mat, 0, 0); + // P_{k+1} = temp_AP_mat @ AK_mat^T + GWG_mat + blasfeo_dgemm_nt(nx, nx, nx, 1.0, temp_AP_mat, 0, 0, + AK_mat, 0, 0, 1.0, + W_mat, 0, 0, P_next_mat, 0, 0); +} + +static void reset_P0_matrix(ocp_nlp_dims *nlp_dims, struct blasfeo_dmat* P_mat, double* data) +{ + int nx = nlp_dims->nx[0]; + blasfeo_pack_dmat(nx, nx, data, nx, P_mat, 0, 0); +} + +static void uncertainty_propagate_and_update(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in, ocp_nlp_out *nlp_out, custom_memory *custom_mem) +{ + ocp_nlp_config *nlp_config = solver->config; + ocp_nlp_dims *nlp_dims = solver->dims; + + int N = nlp_dims->N; + int nx = nlp_dims->nx[0]; + int nu = nlp_dims->nu[0]; + int nx_sqr = nx*nx; + int nbx = {{ dims.nbx }}; + int nbu = {{ dims.nbu }}; + int ng = {{ dims.ng }}; + int nh = {{ dims.nh }}; + int ng_e = {{ dims.ng_e }}; + int nh_e = {{ dims.nh_e }}; + int nbx_e = {{ dims.nbx_e }}; + double backoff_scaling_gamma = {{ zoro_description.backoff_scaling_gamma }}; + + // First Stage + // NOTE: lbx_0 and ubx_0 should not be tightened. + // NOTE: lg_0 and ug_0 are not tightened. + // NOTE: lh_0 and uh_0 are not tightened. +{%- if zoro_description.nlbu_t + zoro_description.nubu_t > 0 %} + compute_KPK(&custom_mem->K_mat, &custom_mem->temp_KP_mat, + &custom_mem->temp_KPK_mat, &(custom_mem->uncertainty_matrix_buffer[0]), nx, nu); + +{%- if zoro_description.nlbu_t > 0 %} + // backoff lbu + {%- for it in zoro_description.idx_lbu_t %} + custom_mem->d_lbu_tightened[{{it}}] + = custom_mem->d_lbu[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_KPK_mat, + custom_mem->idxbu[{{it}}],custom_mem->idxbu[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, 0, "lbu", custom_mem->d_lbu_tightened); +{%- endif %} +{%- if zoro_description.nubu_t > 0 %} + // backoff ubu + {%- for it in zoro_description.idx_ubu_t %} + custom_mem->d_ubu_tightened[{{it}}] + = custom_mem->d_ubu[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_KPK_mat, + custom_mem->idxbu[{{it}}],custom_mem->idxbu[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, 0, "ubu", custom_mem->d_ubu_tightened); +{%- endif %} +{%- endif %} + // Middle Stages + // constraint tightening: for next stage based on dynamics of ii stage + // P[ii+1] = (A-B@K) @ P[ii] @ (A-B@K).T + G@W@G.T + for (int ii = 0; ii < N-1; ii++) + { + // get and pack: A, B + ocp_nlp_get_at_stage(nlp_config, nlp_dims, solver, ii, "A", custom_mem->d_A_mat); + blasfeo_pack_dmat(nx, nx, custom_mem->d_A_mat, nx, &custom_mem->A_mat, 0, 0); + ocp_nlp_get_at_stage(nlp_config, nlp_dims, solver, ii, "B", custom_mem->d_B_mat); + blasfeo_pack_dmat(nx, nu, custom_mem->d_B_mat, nx, &custom_mem->B_mat, 0, 0); + + compute_next_P_matrix(&(custom_mem->uncertainty_matrix_buffer[ii]), + &(custom_mem->uncertainty_matrix_buffer[ii+1]), + &custom_mem->A_mat, &custom_mem->B_mat, + &custom_mem->K_mat, &custom_mem->GWG_mat, + &custom_mem->AK_mat, &custom_mem->temp_AP_mat, nx, nu); + + // state constraints +{%- if zoro_description.nlbx_t + zoro_description.nubx_t> 0 %} + {%- if zoro_description.nlbx_t > 0 %} + // lbx + {%- for it in zoro_description.idx_lbx_t %} + custom_mem->d_lbx_tightened[{{it}}] + = custom_mem->d_lbx[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->uncertainty_matrix_buffer[ii+1], + custom_mem->idxbx[{{it}}],custom_mem->idxbx[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "lbx", custom_mem->d_lbx_tightened); + {%- endif %} + {% if zoro_description.nubx_t > 0 %} + // ubx + {%- for it in zoro_description.idx_ubx_t %} + custom_mem->d_ubx_tightened[{{it}}] = custom_mem->d_ubx[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->uncertainty_matrix_buffer[ii+1], + custom_mem->idxbx[{{it}}],custom_mem->idxbx[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "ubx", custom_mem->d_ubx_tightened); + {%- endif %} +{%- endif %} + +{%- if zoro_description.nlbu_t + zoro_description.nubu_t > 0 %} + // input constraints + compute_KPK(&custom_mem->K_mat, &custom_mem->temp_KP_mat, + &custom_mem->temp_KPK_mat, &(custom_mem->uncertainty_matrix_buffer[ii+1]), nx, nu); + + {%- if zoro_description.nlbu_t > 0 %} + {%- for it in zoro_description.idx_lbu_t %} + custom_mem->d_lbu_tightened[{{it}}] = custom_mem->d_lbu[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_KPK_mat, + custom_mem->idxbu[{{it}}], custom_mem->idxbu[{{it}}])); + {%- endfor %} + + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "lbu", custom_mem->d_lbu_tightened); + {%- endif %} + {%- if zoro_description.nubu_t > 0 %} + {%- for it in zoro_description.idx_ubu_t %} + custom_mem->d_ubu_tightened[{{it}}] = custom_mem->d_ubu[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_KPK_mat, + custom_mem->idxbu[{{it}}], custom_mem->idxbu[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "ubu", custom_mem->d_ubu_tightened); + {%- endif %} +{%- endif %} + +{%- if zoro_description.nlg_t + zoro_description.nug_t > 0 %} + // Linear constraints: g + compute_gh_beta(&custom_mem->K_mat, &custom_mem->Cg_mat, + &custom_mem->Dg_mat, &custom_mem->temp_CaDK_mat, + &custom_mem->temp_CaDKmP_mat, &custom_mem->temp_beta_mat, + &custom_mem->uncertainty_matrix_buffer[ii+1], ng, nx, nu); + + {%- if zoro_description.nlg_t > 0 %} + {%- for it in zoro_description.idx_lg_t %} + custom_mem->d_lg_tightened[{{it}}] + = custom_mem->d_lg[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "lg", custom_mem->d_lg_tightened); + {%- endif %} + {%- if zoro_description.nug_t > 0 %} + {%- for it in zoro_description.idx_ug_t %} + custom_mem->d_ug_tightened[{{it}}] + = custom_mem->d_ug[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "ug", custom_mem->d_ug_tightened); + {%- endif %} +{%- endif %} + + +{%- if zoro_description.nlh_t + zoro_description.nuh_t > 0 %} + // nonlinear constraints: h + // Get C_{k+1} and D_{k+1} + ocp_nlp_get_at_stage(solver->config, nlp_dims, solver, ii+1, "C", custom_mem->d_Cgh_mat); + ocp_nlp_get_at_stage(solver->config, nlp_dims, solver, ii+1, "D", custom_mem->d_Dgh_mat); + // NOTE: the d_Cgh_mat is column-major, the first ng rows are the Jacobians of the linear constraints + blasfeo_pack_dmat(nh, nx, custom_mem->d_Cgh_mat+ng, ng+nh, &custom_mem->Ch_mat, 0, 0); + blasfeo_pack_dmat(nh, nu, custom_mem->d_Dgh_mat+ng, ng+nh, &custom_mem->Dh_mat, 0, 0); + + compute_gh_beta(&custom_mem->K_mat, &custom_mem->Ch_mat, + &custom_mem->Dh_mat, &custom_mem->temp_CaDK_mat, + &custom_mem->temp_CaDKmP_mat, &custom_mem->temp_beta_mat, + &custom_mem->uncertainty_matrix_buffer[ii+1], nh, nx, nu); + + {%- if zoro_description.nlh_t > 0 %} + {%- for it in zoro_description.idx_lh_t %} + custom_mem->d_lh_tightened[{{it}}] + = custom_mem->d_lh[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "lh", custom_mem->d_lh_tightened); + {%- endif %} + {%- if zoro_description.nuh_t > 0 %} + {%- for it in zoro_description.idx_uh_t %} + custom_mem->d_uh_tightened[{{it}}] = custom_mem->d_uh[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, ii+1, "uh", custom_mem->d_uh_tightened); + {%- endif %} +{%- endif %} + } + + // Last stage + // get and pack: A, B + ocp_nlp_get_at_stage(nlp_config, nlp_dims, solver, N-1, "A", custom_mem->d_A_mat); + blasfeo_pack_dmat(nx, nx, custom_mem->d_A_mat, nx, &custom_mem->A_mat, 0, 0); + ocp_nlp_get_at_stage(nlp_config, nlp_dims, solver, N-1, "B", custom_mem->d_B_mat); + blasfeo_pack_dmat(nx, nu, custom_mem->d_B_mat, nx, &custom_mem->B_mat, 0, 0); + // AK_mat = -B*K + A + compute_next_P_matrix(&(custom_mem->uncertainty_matrix_buffer[N-1]), + &(custom_mem->uncertainty_matrix_buffer[N]), + &custom_mem->A_mat, &custom_mem->B_mat, + &custom_mem->K_mat, &custom_mem->GWG_mat, + &custom_mem->AK_mat, &custom_mem->temp_AP_mat, nx, nu); + + // state constraints nlbx_e_t +{%- if zoro_description.nlbx_e_t + zoro_description.nubx_e_t> 0 %} +{%- if zoro_description.nlbx_e_t > 0 %} + // lbx_e + {%- for it in zoro_description.idx_lbx_e_t %} + custom_mem->d_lbx_e_tightened[{{it}}] + = custom_mem->d_lbx_e[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->uncertainty_matrix_buffer[N], + custom_mem->idxbx_e[{{it}}],custom_mem->idxbx_e[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "lbx", custom_mem->d_lbx_e_tightened); +{%- endif %} +{% if zoro_description.nubx_e_t > 0 %} + // ubx_e + {%- for it in zoro_description.idx_ubx_e_t %} + custom_mem->d_ubx_e_tightened[{{it}}] = custom_mem->d_ubx_e[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->uncertainty_matrix_buffer[N], + custom_mem->idxbx_e[{{it}}],custom_mem->idxbx_e[{{it}}])); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "ubx", custom_mem->d_ubx_e_tightened); +{%- endif %} +{%- endif %} + +{%- if zoro_description.nlg_e_t + zoro_description.nug_e_t > 0 %} + // Linear constraints: g + compute_gh_beta(&custom_mem->K_mat, &custom_mem->Cg_mat, + &custom_mem->dummy_Dgh_e_mat, &custom_mem->temp_CaDK_mat, + &custom_mem->temp_CaDKmP_mat, &custom_mem->temp_beta_mat, + &custom_mem->uncertainty_matrix_buffer[N], ng, nx, nu); + +{%- if zoro_description.nlg_e_t > 0 %} + {%- for it in zoro_description.idx_lg_e_t %} + custom_mem->d_lg_e_tightened[{{it}}] + = custom_mem->d_lg_e[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "lg", custom_mem->d_lg_e_tightened); +{%- endif %} +{%- if zoro_description.nug_e_t > 0 %} + {%- for it in zoro_description.idx_ug_e_t %} + custom_mem->d_ug_e_tightened[{{it}}] + = custom_mem->d_ug_e[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "ug", custom_mem->d_ug_e_tightened); +{%- endif %} +{%- endif %} + + +{%- if zoro_description.nlh_e_t + zoro_description.nuh_e_t > 0 %} + // nonlinear constraints: h + // Get C_{k+1} and D_{k+1} + ocp_nlp_get_at_stage(solver->config, nlp_dims, solver, N, "C", custom_mem->d_Cgh_mat); + // NOTE: the d_Cgh_mat is column-major, the first ng rows are the Jacobians of the linear constraints + blasfeo_pack_dmat(nh, nx, custom_mem->d_Cgh_mat+ng, ng+nh, &custom_mem->Ch_mat, 0, 0); + + compute_gh_beta(&custom_mem->K_mat, &custom_mem->Ch_mat, + &custom_mem->dummy_Dgh_e_mat, &custom_mem->temp_CaDK_mat, + &custom_mem->temp_CaDKmP_mat, &custom_mem->temp_beta_mat, + &custom_mem->uncertainty_matrix_buffer[N], nh, nx, nu); + + {%- if zoro_description.nlh_e_t > 0 %} + {%- for it in zoro_description.idx_lh_e_t %} + custom_mem->d_lh_e_tightened[{{it}}] + = custom_mem->d_lh_e[{{it}}] + + backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "lh", custom_mem->d_lh_e_tightened); + {%- endif %} + {%- if zoro_description.nuh_e_t > 0 %} + {%- for it in zoro_description.idx_uh_e_t %} + custom_mem->d_uh_e_tightened[{{it}}] = custom_mem->d_uh_e[{{it}}] + - backoff_scaling_gamma * sqrt(blasfeo_dgeex1(&custom_mem->temp_beta_mat, {{it}}, {{it}})); + {%- endfor %} + ocp_nlp_constraints_model_set(nlp_config, nlp_dims, nlp_in, N, "uh", custom_mem->d_uh_e_tightened); + {%- endif %} +{%- endif %} + +} + + +int custom_update_function({{ model.name }}_solver_capsule* capsule, double* data, int data_len) +{ + custom_memory *custom_mem = (custom_memory *) capsule->custom_update_memory; + ocp_nlp_config *nlp_config = {{ model.name }}_acados_get_nlp_config(capsule); + ocp_nlp_dims *nlp_dims = {{ model.name }}_acados_get_nlp_dims(capsule); + ocp_nlp_in *nlp_in = {{ model.name }}_acados_get_nlp_in(capsule); + ocp_nlp_out *nlp_out = {{ model.name }}_acados_get_nlp_out(capsule); + ocp_nlp_solver *nlp_solver = {{ model.name }}_acados_get_nlp_solver(capsule); + void *nlp_opts = {{ model.name }}_acados_get_nlp_opts(capsule); + + if (data_len > 0) + { + reset_P0_matrix(nlp_dims, &custom_mem->uncertainty_matrix_buffer[0], data); + } + uncertainty_propagate_and_update(nlp_solver, nlp_in, nlp_out, custom_mem); + + return 1; +} + + +int custom_update_terminate_function({{ model.name }}_solver_capsule* capsule) +{ + custom_memory *mem = capsule->custom_update_memory; + + free(mem->raw_memory); + return 1; +} + +// useful prints for debugging + +/* +printf("A_mat:\n"); +blasfeo_print_exp_dmat(nx, nx, &custom_mem->A_mat, 0, 0); +printf("B_mat:\n"); +blasfeo_print_exp_dmat(nx, nu, &custom_mem->B_mat, 0, 0); +printf("K_mat:\n"); +blasfeo_print_exp_dmat(nu, nx, &custom_mem->K_mat, 0, 0); +printf("AK_mat:\n"); +blasfeo_print_exp_dmat(nx, nx, &custom_mem->AK_mat, 0, 0); +printf("temp_AP_mat:\n"); +blasfeo_print_exp_dmat(nx, nx, &custom_mem->temp_AP_mat, 0, 0); +printf("W_mat:\n"); +blasfeo_print_exp_dmat(nx, nx, &custom_mem->W_mat, 0, 0); +printf("P_k+1:\n"); +blasfeo_print_exp_dmat(nx, nx, &(custom_mem->uncertainty_matrix_buffer[ii+1]), 0, 0);*/ \ No newline at end of file diff --git a/third_party/acados/acados_template/c_templates_tera/phi_constraint.in.h b/third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.h similarity index 59% rename from third_party/acados/acados_template/c_templates_tera/phi_constraint.in.h rename to third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.h index 283ed7f889..9611ea210c 100644 --- a/third_party/acados/acados_template/c_templates_tera/phi_constraint.in.h +++ b/third_party/acados/acados_template/custom_update_templates/custom_update_function_zoro_template.in.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -31,25 +28,17 @@ * POSSIBILITY OF SUCH DAMAGE.; */ -#ifndef {{ model.name }}_PHI_CONSTRAINT -#define {{ model.name }}_PHI_CONSTRAINT +#include "acados_solver_{{ model.name }}.h" -#ifdef __cplusplus -extern "C" { -#endif +// Called at the end of solver creation. +// This is allowed to allocate memory and store the pointer to it into capsule->custom_update_memory. +int custom_update_init_function({{ model.name }}_solver_capsule* capsule); -{% if dims.nphi > 0 %} -// implicit ODE -int {{ model.name }}_phi_constraint(const real_t** arg, real_t** res, int* iw, real_t* w, void *mem); -int {{ model.name }}_phi_constraint_work(int *, int *, int *, int *); -const int *{{ model.name }}_phi_constraint_sparsity_in(int); -const int *{{ model.name }}_phi_constraint_sparsity_out(int); -int {{ model.name }}_phi_constraint_n_in(void); -int {{ model.name }}_phi_constraint_n_out(void); -{% endif %} -#ifdef __cplusplus -} /* extern "C" */ -#endif +// Custom update function that can be called between solver calls +int custom_update_function({{ model.name }}_solver_capsule* capsule, double* data, int data_len); -#endif // {{ model.name }}_PHI_CONSTRAINT + +// Called just before destroying the solver. +// Responsible to free allocated memory, stored at capsule->custom_update_memory. +int custom_update_terminate_function({{ model.name }}_solver_capsule* capsule); diff --git a/third_party/acados/acados_template/generate_c_code_constraint.py b/third_party/acados/acados_template/generate_c_code_constraint.py deleted file mode 100644 index c79ddc129a..0000000000 --- a/third_party/acados/acados_template/generate_c_code_constraint.py +++ /dev/null @@ -1,180 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import * -from .utils import ALLOWED_CASADI_VERSIONS, is_empty, casadi_length, casadi_version_warning - -def generate_c_code_constraint( model, con_name, is_terminal, opts ): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - # load constraint variables and expression - x = model.x - p = model.p - - if isinstance(x, casadi.MX): - symbol = MX.sym - else: - symbol = SX.sym - - if is_terminal: - con_h_expr = model.con_h_expr_e - con_phi_expr = model.con_phi_expr_e - # create dummy u, z - u = symbol('u', 0, 0) - z = symbol('z', 0, 0) - else: - con_h_expr = model.con_h_expr - con_phi_expr = model.con_phi_expr - u = model.u - z = model.z - - if (not is_empty(con_h_expr)) and (not is_empty(con_phi_expr)): - raise Exception("acados: you can either have constraint_h, or constraint_phi, not both.") - - if not (is_empty(con_h_expr) and is_empty(con_phi_expr)): - if is_empty(con_h_expr): - constr_type = 'BGP' - else: - constr_type = 'BGH' - - if is_empty(p): - p = symbol('p', 0, 0) - - if is_empty(z): - z = symbol('z', 0, 0) - - if not (is_empty(con_h_expr)) and opts['generate_hess']: - # multipliers for hessian - nh = casadi_length(con_h_expr) - lam_h = symbol('lam_h', nh, 1) - - # set up & change directory - code_export_dir = opts["code_export_directory"] - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - gen_dir = con_name + '_constraints' - if not os.path.exists(gen_dir): - os.mkdir(gen_dir) - gen_dir_location = os.path.join('.', gen_dir) - os.chdir(gen_dir_location) - - # export casadi functions - if constr_type == 'BGH': - if is_terminal: - fun_name = con_name + '_constr_h_e_fun_jac_uxt_zt' - else: - fun_name = con_name + '_constr_h_fun_jac_uxt_zt' - - jac_ux_t = transpose(jacobian(con_h_expr, vertcat(u,x))) - jac_z_t = jacobian(con_h_expr, z) - constraint_fun_jac_tran = Function(fun_name, [x, u, z, p], \ - [con_h_expr, jac_ux_t, jac_z_t]) - - constraint_fun_jac_tran.generate(fun_name, casadi_opts) - if opts['generate_hess']: - - if is_terminal: - fun_name = con_name + '_constr_h_e_fun_jac_uxt_zt_hess' - else: - fun_name = con_name + '_constr_h_fun_jac_uxt_zt_hess' - - # adjoint - adj_ux = jtimes(con_h_expr, vertcat(u, x), lam_h, True) - # hessian - hess_ux = jacobian(adj_ux, vertcat(u, x)) - - adj_z = jtimes(con_h_expr, z, lam_h, True) - hess_z = jacobian(adj_z, z) - - # set up functions - constraint_fun_jac_tran_hess = \ - Function(fun_name, [x, u, lam_h, z, p], \ - [con_h_expr, jac_ux_t, hess_ux, jac_z_t, hess_z]) - - # generate C code - constraint_fun_jac_tran_hess.generate(fun_name, casadi_opts) - - if is_terminal: - fun_name = con_name + '_constr_h_e_fun' - else: - fun_name = con_name + '_constr_h_fun' - h_fun = Function(fun_name, [x, u, z, p], [con_h_expr]) - h_fun.generate(fun_name, casadi_opts) - - else: # BGP constraint - if is_terminal: - fun_name = con_name + '_phi_e_constraint' - r = model.con_r_in_phi_e - con_r_expr = model.con_r_expr_e - else: - fun_name = con_name + '_phi_constraint' - r = model.con_r_in_phi - con_r_expr = model.con_r_expr - - nphi = casadi_length(con_phi_expr) - con_phi_expr_x_u_z = substitute(con_phi_expr, r, con_r_expr) - phi_jac_u = jacobian(con_phi_expr_x_u_z, u) - phi_jac_x = jacobian(con_phi_expr_x_u_z, x) - phi_jac_z = jacobian(con_phi_expr_x_u_z, z) - - hess = hessian(con_phi_expr[0], r)[0] - for i in range(1, nphi): - hess = vertcat(hess, hessian(con_phi_expr[i], r)[0]) - - r_jac_u = jacobian(con_r_expr, u) - r_jac_x = jacobian(con_r_expr, x) - - constraint_phi = \ - Function(fun_name, [x, u, z, p], \ - [con_phi_expr_x_u_z, \ - vertcat(transpose(phi_jac_u), \ - transpose(phi_jac_x)), \ - transpose(phi_jac_z), \ - hess, vertcat(transpose(r_jac_u), \ - transpose(r_jac_x))]) - - constraint_phi.generate(fun_name, casadi_opts) - - # change directory back - os.chdir(cwd) - - return diff --git a/third_party/acados/acados_template/generate_c_code_discrete_dynamics.py b/third_party/acados/acados_template/generate_c_code_discrete_dynamics.py deleted file mode 100644 index c6a245ff81..0000000000 --- a/third_party/acados/acados_template/generate_c_code_discrete_dynamics.py +++ /dev/null @@ -1,98 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR PROFITS OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import os -import casadi as ca -from .utils import ALLOWED_CASADI_VERSIONS, casadi_length, casadi_version_warning - -def generate_c_code_discrete_dynamics( model, opts ): - - casadi_version = ca.CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - # load model - x = model.x - u = model.u - p = model.p - phi = model.disc_dyn_expr - model_name = model.name - nx = casadi_length(x) - - if isinstance(phi, ca.MX): - symbol = ca.MX.sym - elif isinstance(phi, ca.SX): - symbol = ca.SX.sym - else: - Exception("generate_c_code_disc_dyn: disc_dyn_expr must be a CasADi expression, you have type: {}".format(type(phi))) - - # assume nx1 = nx !!! - lam = symbol('lam', nx, 1) - - # generate jacobians - ux = ca.vertcat(u,x) - jac_ux = ca.jacobian(phi, ux) - # generate adjoint - adj_ux = ca.jtimes(phi, ux, lam, True) - # generate hessian - hess_ux = ca.jacobian(adj_ux, ux) - - ## change directory - code_export_dir = opts["code_export_directory"] - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - model_dir = model_name + '_model' - if not os.path.exists(model_dir): - os.mkdir(model_dir) - model_dir_location = os.path.join('.', model_dir) - os.chdir(model_dir_location) - - # set up & generate Functions - fun_name = model_name + '_dyn_disc_phi_fun' - phi_fun = ca.Function(fun_name, [x, u, p], [phi]) - phi_fun.generate(fun_name, casadi_opts) - - fun_name = model_name + '_dyn_disc_phi_fun_jac' - phi_fun_jac_ut_xt = ca.Function(fun_name, [x, u, p], [phi, jac_ux.T]) - phi_fun_jac_ut_xt.generate(fun_name, casadi_opts) - - fun_name = model_name + '_dyn_disc_phi_fun_jac_hess' - phi_fun_jac_ut_xt_hess = ca.Function(fun_name, [x, u, lam, p], [phi, jac_ux.T, hess_ux]) - phi_fun_jac_ut_xt_hess.generate(fun_name, casadi_opts) - - os.chdir(cwd) diff --git a/third_party/acados/acados_template/generate_c_code_explicit_ode.py b/third_party/acados/acados_template/generate_c_code_explicit_ode.py deleted file mode 100644 index 76e6400535..0000000000 --- a/third_party/acados/acados_template/generate_c_code_explicit_ode.py +++ /dev/null @@ -1,124 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import * -from .utils import ALLOWED_CASADI_VERSIONS, is_empty, casadi_version_warning - -def generate_c_code_explicit_ode( model, opts ): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - - generate_hess = opts["generate_hess"] - code_export_dir = opts["code_export_directory"] - - # load model - x = model.x - u = model.u - p = model.p - f_expl = model.f_expl_expr - model_name = model.name - - ## get model dimensions - nx = x.size()[0] - nu = u.size()[0] - - if isinstance(f_expl, casadi.MX): - symbol = MX.sym - elif isinstance(f_expl, casadi.SX): - symbol = SX.sym - else: - raise Exception("Invalid type for f_expl! Possible types are 'SX' and 'MX'. Exiting.") - ## set up functions to be exported - Sx = symbol('Sx', nx, nx) - Sp = symbol('Sp', nx, nu) - lambdaX = symbol('lambdaX', nx, 1) - - fun_name = model_name + '_expl_ode_fun' - - ## Set up functions - expl_ode_fun = Function(fun_name, [x, u, p], [f_expl]) - - vdeX = jtimes(f_expl,x,Sx) - vdeP = jacobian(f_expl,u) + jtimes(f_expl,x,Sp) - - fun_name = model_name + '_expl_vde_forw' - - expl_vde_forw = Function(fun_name, [x, Sx, Sp, u, p], [f_expl, vdeX, vdeP]) - - adj = jtimes(f_expl, vertcat(x, u), lambdaX, True) - - fun_name = model_name + '_expl_vde_adj' - expl_vde_adj = Function(fun_name, [x, lambdaX, u, p], [adj]) - - if generate_hess: - S_forw = vertcat(horzcat(Sx, Sp), horzcat(DM.zeros(nu,nx), DM.eye(nu))) - hess = mtimes(transpose(S_forw),jtimes(adj, vertcat(x,u), S_forw)) - hess2 = [] - for j in range(nx+nu): - for i in range(j,nx+nu): - hess2 = vertcat(hess2, hess[i,j]) - - fun_name = model_name + '_expl_ode_hess' - expl_ode_hess = Function(fun_name, [x, Sx, Sp, lambdaX, u, p], [adj, hess2]) - - ## generate C code - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - model_dir = model_name + '_model' - if not os.path.exists(model_dir): - os.mkdir(model_dir) - model_dir_location = os.path.join('.', model_dir) - os.chdir(model_dir_location) - fun_name = model_name + '_expl_ode_fun' - expl_ode_fun.generate(fun_name, casadi_opts) - - fun_name = model_name + '_expl_vde_forw' - expl_vde_forw.generate(fun_name, casadi_opts) - - fun_name = model_name + '_expl_vde_adj' - expl_vde_adj.generate(fun_name, casadi_opts) - - if generate_hess: - fun_name = model_name + '_expl_ode_hess' - expl_ode_hess.generate(fun_name, casadi_opts) - os.chdir(cwd) - - return diff --git a/third_party/acados/acados_template/generate_c_code_external_cost.py b/third_party/acados/acados_template/generate_c_code_external_cost.py deleted file mode 100644 index 8396522619..0000000000 --- a/third_party/acados/acados_template/generate_c_code_external_cost.py +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import SX, MX, Function, transpose, vertcat, horzcat, hessian, CasadiMeta -from .utils import ALLOWED_CASADI_VERSIONS, casadi_version_warning - - -def generate_c_code_external_cost(model, stage_type, opts): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int="int", casadi_real="double") - - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - x = model.x - p = model.p - - if isinstance(x, MX): - symbol = MX.sym - else: - symbol = SX.sym - - if stage_type == 'terminal': - suffix_name = "_cost_ext_cost_e_fun" - suffix_name_hess = "_cost_ext_cost_e_fun_jac_hess" - suffix_name_jac = "_cost_ext_cost_e_fun_jac" - u = symbol("u", 0, 0) - ext_cost = model.cost_expr_ext_cost_e - custom_hess = model.cost_expr_ext_cost_custom_hess_e - - elif stage_type == 'path': - suffix_name = "_cost_ext_cost_fun" - suffix_name_hess = "_cost_ext_cost_fun_jac_hess" - suffix_name_jac = "_cost_ext_cost_fun_jac" - u = model.u - ext_cost = model.cost_expr_ext_cost - custom_hess = model.cost_expr_ext_cost_custom_hess - - elif stage_type == 'initial': - suffix_name = "_cost_ext_cost_0_fun" - suffix_name_hess = "_cost_ext_cost_0_fun_jac_hess" - suffix_name_jac = "_cost_ext_cost_0_fun_jac" - u = model.u - ext_cost = model.cost_expr_ext_cost_0 - custom_hess = model.cost_expr_ext_cost_custom_hess_0 - - # set up functions to be exported - fun_name = model.name + suffix_name - fun_name_hess = model.name + suffix_name_hess - fun_name_jac = model.name + suffix_name_jac - - # generate expression for full gradient and Hessian - full_hess, grad = hessian(ext_cost, vertcat(u, x)) - - if custom_hess is not None: - full_hess = custom_hess - - ext_cost_fun = Function(fun_name, [x, u, p], [ext_cost]) - ext_cost_fun_jac_hess = Function( - fun_name_hess, [x, u, p], [ext_cost, grad, full_hess] - ) - ext_cost_fun_jac = Function( - fun_name_jac, [x, u, p], [ext_cost, grad] - ) - - # generate C code - code_export_dir = opts["code_export_directory"] - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - gen_dir = model.name + '_cost' - if not os.path.exists(gen_dir): - os.mkdir(gen_dir) - gen_dir_location = "./" + gen_dir - os.chdir(gen_dir_location) - - ext_cost_fun.generate(fun_name, casadi_opts) - ext_cost_fun_jac_hess.generate(fun_name_hess, casadi_opts) - ext_cost_fun_jac.generate(fun_name_jac, casadi_opts) - - os.chdir(cwd) - return diff --git a/third_party/acados/acados_template/generate_c_code_gnsf.py b/third_party/acados/acados_template/generate_c_code_gnsf.py deleted file mode 100644 index 97acb8e330..0000000000 --- a/third_party/acados/acados_template/generate_c_code_gnsf.py +++ /dev/null @@ -1,131 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import * -from .utils import ALLOWED_CASADI_VERSIONS, is_empty, casadi_version_warning - -def generate_c_code_gnsf( model, opts ): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - model_name = model.name - code_export_dir = opts["code_export_directory"] - - # set up directory - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - model_dir = model_name + '_model' - if not os.path.exists(model_dir): - os.mkdir(model_dir) - model_dir_location = os.path.join('.', model_dir) - os.chdir(model_dir_location) - - # obtain gnsf dimensions - get_matrices_fun = model.get_matrices_fun - phi_fun = model.phi_fun - - size_gnsf_A = get_matrices_fun.size_out(0) - gnsf_nx1 = size_gnsf_A[1] - gnsf_nz1 = size_gnsf_A[0] - size_gnsf_A[1] - gnsf_nuhat = max(phi_fun.size_in(1)) - gnsf_ny = max(phi_fun.size_in(0)) - gnsf_nout = max(phi_fun.size_out(0)) - - # set up expressions - # if the model uses MX because of cost/constraints - # the DAE can be exported as SX -> detect GNSF in Matlab - # -> evaluated SX GNSF functions with MX. - u = model.u - - if isinstance(u, casadi.MX): - symbol = MX.sym - else: - symbol = SX.sym - - y = symbol("y", gnsf_ny, 1) - uhat = symbol("uhat", gnsf_nuhat, 1) - p = model.p - x1 = symbol("gnsf_x1", gnsf_nx1, 1) - x1dot = symbol("gnsf_x1dot", gnsf_nx1, 1) - z1 = symbol("gnsf_z1", gnsf_nz1, 1) - dummy = symbol("gnsf_dummy", 1, 1) - empty_var = symbol("gnsf_empty_var", 0, 0) - - ## generate C code - fun_name = model_name + '_gnsf_phi_fun' - phi_fun_ = Function(fun_name, [y, uhat, p], [phi_fun(y, uhat, p)]) - phi_fun_.generate(fun_name, casadi_opts) - - fun_name = model_name + '_gnsf_phi_fun_jac_y' - phi_fun_jac_y = model.phi_fun_jac_y - phi_fun_jac_y_ = Function(fun_name, [y, uhat, p], phi_fun_jac_y(y, uhat, p)) - phi_fun_jac_y_.generate(fun_name, casadi_opts) - - fun_name = model_name + '_gnsf_phi_jac_y_uhat' - phi_jac_y_uhat = model.phi_jac_y_uhat - phi_jac_y_uhat_ = Function(fun_name, [y, uhat, p], phi_jac_y_uhat(y, uhat, p)) - phi_jac_y_uhat_.generate(fun_name, casadi_opts) - - fun_name = model_name + '_gnsf_f_lo_fun_jac_x1k1uz' - f_lo_fun_jac_x1k1uz = model.f_lo_fun_jac_x1k1uz - f_lo_fun_jac_x1k1uz_eval = f_lo_fun_jac_x1k1uz(x1, x1dot, z1, u, p) - - # avoid codegeneration issue - if not isinstance(f_lo_fun_jac_x1k1uz_eval, tuple) and is_empty(f_lo_fun_jac_x1k1uz_eval): - f_lo_fun_jac_x1k1uz_eval = [empty_var] - - f_lo_fun_jac_x1k1uz_ = Function(fun_name, [x1, x1dot, z1, u, p], - f_lo_fun_jac_x1k1uz_eval) - f_lo_fun_jac_x1k1uz_.generate(fun_name, casadi_opts) - - fun_name = model_name + '_gnsf_get_matrices_fun' - get_matrices_fun_ = Function(fun_name, [dummy], get_matrices_fun(1)) - get_matrices_fun_.generate(fun_name, casadi_opts) - - # remove fields for json dump - del model.phi_fun - del model.phi_fun_jac_y - del model.phi_jac_y_uhat - del model.f_lo_fun_jac_x1k1uz - del model.get_matrices_fun - - os.chdir(cwd) - - return diff --git a/third_party/acados/acados_template/generate_c_code_implicit_ode.py b/third_party/acados/acados_template/generate_c_code_implicit_ode.py deleted file mode 100644 index f2d50b43ab..0000000000 --- a/third_party/acados/acados_template/generate_c_code_implicit_ode.py +++ /dev/null @@ -1,139 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import * -from .utils import ALLOWED_CASADI_VERSIONS, is_empty, casadi_length, casadi_version_warning - -def generate_c_code_implicit_ode( model, opts ): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - generate_hess = opts["generate_hess"] - code_export_dir = opts["code_export_directory"] - - ## load model - x = model.x - xdot = model.xdot - u = model.u - z = model.z - p = model.p - f_impl = model.f_impl_expr - model_name = model.name - - ## get model dimensions - nx = casadi_length(x) - nu = casadi_length(u) - nz = casadi_length(z) - - ## generate jacobians - jac_x = jacobian(f_impl, x) - jac_xdot = jacobian(f_impl, xdot) - jac_u = jacobian(f_impl, u) - jac_z = jacobian(f_impl, z) - - ## generate hessian - x_xdot_z_u = vertcat(x, xdot, z, u) - - if isinstance(x, casadi.MX): - symbol = MX.sym - else: - symbol = SX.sym - - multiplier = symbol('multiplier', nx + nz) - - ADJ = jtimes(f_impl, x_xdot_z_u, multiplier, True) - HESS = jacobian(ADJ, x_xdot_z_u) - - ## Set up functions - p = model.p - fun_name = model_name + '_impl_dae_fun' - impl_dae_fun = Function(fun_name, [x, xdot, u, z, p], [f_impl]) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_z' - impl_dae_fun_jac_x_xdot_z = Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_z]) - - # fun_name = model_name + '_impl_dae_fun_jac_x_xdot_z' - # impl_dae_fun_jac_x_xdot = Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_z]) - - # fun_name = model_name + '_impl_dae_jac_x_xdot_u' - # impl_dae_jac_x_xdot_u = Function(fun_name, [x, xdot, u, z, p], [jac_x, jac_xdot, jac_u, jac_z]) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u_z' - impl_dae_fun_jac_x_xdot_u_z = Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_u, jac_z]) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u' - impl_dae_fun_jac_x_xdot_u = Function(fun_name, [x, xdot, u, z, p], [f_impl, jac_x, jac_xdot, jac_u]) - - fun_name = model_name + '_impl_dae_jac_x_xdot_u_z' - impl_dae_jac_x_xdot_u_z = Function(fun_name, [x, xdot, u, z, p], [jac_x, jac_xdot, jac_u, jac_z]) - - - fun_name = model_name + '_impl_dae_hess' - impl_dae_hess = Function(fun_name, [x, xdot, u, z, multiplier, p], [HESS]) - - # generate C code - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - model_dir = model_name + '_model' - if not os.path.exists(model_dir): - os.mkdir(model_dir) - model_dir_location = os.path.join('.', model_dir) - os.chdir(model_dir_location) - - fun_name = model_name + '_impl_dae_fun' - impl_dae_fun.generate(fun_name, casadi_opts) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_z' - impl_dae_fun_jac_x_xdot_z.generate(fun_name, casadi_opts) - - fun_name = model_name + '_impl_dae_jac_x_xdot_u_z' - impl_dae_jac_x_xdot_u_z.generate(fun_name, casadi_opts) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u_z' - impl_dae_fun_jac_x_xdot_u_z.generate(fun_name, casadi_opts) - - fun_name = model_name + '_impl_dae_fun_jac_x_xdot_u' - impl_dae_fun_jac_x_xdot_u.generate(fun_name, casadi_opts) - - if generate_hess: - fun_name = model_name + '_impl_dae_hess' - impl_dae_hess.generate(fun_name, casadi_opts) - - os.chdir(cwd) diff --git a/third_party/acados/acados_template/generate_c_code_nls_cost.py b/third_party/acados/acados_template/generate_c_code_nls_cost.py deleted file mode 100644 index ffcd78ca7b..0000000000 --- a/third_party/acados/acados_template/generate_c_code_nls_cost.py +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl -# -# This file is part of acados. -# -# The 2-Clause BSD License -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE.; -# - -import os -from casadi import * -from .utils import ALLOWED_CASADI_VERSIONS, casadi_length, casadi_version_warning - -def generate_c_code_nls_cost( model, cost_name, stage_type, opts ): - - casadi_version = CasadiMeta.version() - casadi_opts = dict(mex=False, casadi_int='int', casadi_real='double') - - if casadi_version not in (ALLOWED_CASADI_VERSIONS): - casadi_version_warning(casadi_version) - - x = model.x - p = model.p - - if isinstance(x, casadi.MX): - symbol = MX.sym - else: - symbol = SX.sym - - if stage_type == 'terminal': - middle_name = '_cost_y_e' - u = symbol('u', 0, 0) - cost_expr = model.cost_y_expr_e - - elif stage_type == 'initial': - middle_name = '_cost_y_0' - u = model.u - cost_expr = model.cost_y_expr_0 - - elif stage_type == 'path': - middle_name = '_cost_y' - u = model.u - cost_expr = model.cost_y_expr - - # set up directory - code_export_dir = opts["code_export_directory"] - if not os.path.exists(code_export_dir): - os.makedirs(code_export_dir) - - cwd = os.getcwd() - os.chdir(code_export_dir) - gen_dir = cost_name + '_cost' - if not os.path.exists(gen_dir): - os.mkdir(gen_dir) - gen_dir_location = os.path.join('.', gen_dir) - os.chdir(gen_dir_location) - - # set up expressions - cost_jac_expr = transpose(jacobian(cost_expr, vertcat(u, x))) - - ny = casadi_length(cost_expr) - - y = symbol('y', ny, 1) - - y_adj = jtimes(cost_expr, vertcat(u, x), y, True) - y_hess = jacobian(y_adj, vertcat(u, x)) - - ## generate C code - suffix_name = '_fun' - fun_name = cost_name + middle_name + suffix_name - y_fun = Function( fun_name, [x, u, p], \ - [ cost_expr ]) - y_fun.generate( fun_name, casadi_opts ) - - suffix_name = '_fun_jac_ut_xt' - fun_name = cost_name + middle_name + suffix_name - y_fun_jac_ut_xt = Function(fun_name, [x, u, p], \ - [ cost_expr, cost_jac_expr ]) - y_fun_jac_ut_xt.generate( fun_name, casadi_opts ) - - suffix_name = '_hess' - fun_name = cost_name + middle_name + suffix_name - y_hess = Function(fun_name, [x, u, y, p], [ y_hess ]) - y_hess.generate( fun_name, casadi_opts ) - - os.chdir(cwd) - - return - diff --git a/third_party/acados/acados_template/gnsf/__init__.py b/third_party/acados/acados_template/gnsf/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/__init__.py @@ -0,0 +1 @@ + diff --git a/third_party/acados/acados_template/gnsf/check_reformulation.py b/third_party/acados/acados_template/gnsf/check_reformulation.py new file mode 100644 index 0000000000..2bdfbbc336 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/check_reformulation.py @@ -0,0 +1,216 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + +from acados_template.utils import casadi_length +from casadi import * +import numpy as np + + +def check_reformulation(model, gnsf, print_info): + + ## Description: + # this function takes the implicit ODE/ index-1 DAE and a gnsf structure + # to evaluate both models at num_eval random points x0, x0dot, z0, u0 + # if for all points the relative error is <= TOL, the function will return:: + # 1, otherwise it will give an error. + + TOL = 1e-14 + num_eval = 10 + + # get dimensions + nx = gnsf["nx"] + nu = gnsf["nu"] + nz = gnsf["nz"] + nx1 = gnsf["nx1"] + nx2 = gnsf["nx2"] + nz1 = gnsf["nz1"] + nz2 = gnsf["nz2"] + n_out = gnsf["n_out"] + + # get model matrices + A = gnsf["A"] + B = gnsf["B"] + C = gnsf["C"] + E = gnsf["E"] + c = gnsf["c"] + + L_x = gnsf["L_x"] + L_xdot = gnsf["L_xdot"] + L_z = gnsf["L_z"] + L_u = gnsf["L_u"] + + A_LO = gnsf["A_LO"] + E_LO = gnsf["E_LO"] + B_LO = gnsf["B_LO"] + c_LO = gnsf["c_LO"] + + I_x1 = range(nx1) + I_x2 = range(nx1, nx) + + I_z1 = range(nz1) + I_z2 = range(nz1, nz) + + idx_perm_f = gnsf["idx_perm_f"] + + # get casadi variables + x = gnsf["x"] + xdot = gnsf["xdot"] + z = gnsf["z"] + u = gnsf["u"] + y = gnsf["y"] + uhat = gnsf["uhat"] + p = gnsf["p"] + + # create functions + impl_dae_fun = Function("impl_dae_fun", [x, xdot, u, z, p], [model.f_impl_expr]) + phi_fun = Function("phi_fun", [y, uhat, p], [gnsf["phi_expr"]]) + f_lo_fun = Function( + "f_lo_fun", [x[range(nx1)], xdot[range(nx1)], z, u, p], [gnsf["f_lo_expr"]] + ) + + # print(gnsf) + # print(gnsf["n_out"]) + + for i_check in range(num_eval): + # generate random values + x0 = np.random.rand(nx, 1) + x0dot = np.random.rand(nx, 1) + z0 = np.random.rand(nz, 1) + u0 = np.random.rand(nu, 1) + + if gnsf["ny"] > 0: + y0 = L_x @ x0[I_x1] + L_xdot @ x0dot[I_x1] + L_z @ z0[I_z1] + else: + y0 = [] + if gnsf["nuhat"] > 0: + uhat0 = L_u @ u0 + else: + uhat0 = [] + + # eval functions + p0 = np.random.rand(gnsf["np"], 1) + f_impl_val = impl_dae_fun(x0, x0dot, u0, z0, p0).full() + phi_val = phi_fun(y0, uhat0, p0) + f_lo_val = f_lo_fun(x0[I_x1], x0dot[I_x1], z0[I_z1], u0, p0) + + f_impl_val = f_impl_val[idx_perm_f] + # eval gnsf + if n_out > 0: + C_phi = C @ phi_val + else: + C_phi = np.zeros((nx1 + nz1, 1)) + try: + gnsf_val1 = ( + A @ x0[I_x1] + B @ u0 + C_phi + c - E @ vertcat(x0dot[I_x1], z0[I_z1]) + ) + # gnsf_1 = (A @ x[I_x1] + B @ u + C_phi + c - E @ vertcat(xdot[I_x1], z[I_z1])) + except: + import pdb + + pdb.set_trace() + + if nx2 > 0: # eval LOS: + gnsf_val2 = ( + A_LO @ x0[I_x2] + + B_LO @ u0 + + c_LO + + f_lo_val + - E_LO @ vertcat(x0dot[I_x2], z0[I_z2]) + ) + gnsf_val = vertcat(gnsf_val1, gnsf_val2).full() + else: + gnsf_val = gnsf_val1.full() + # compute error and check + rel_error = np.linalg.norm(f_impl_val - gnsf_val) / np.linalg.norm(f_impl_val) + + if rel_error > TOL: + print("transcription failed rel_error > TOL") + print("you are in debug mode now: import pdb; pdb.set_trace()") + abs_error = gnsf_val - f_impl_val + # T = table(f_impl_val, gnsf_val, abs_error) + # print(T) + print("abs_error:", abs_error) + # error('transcription failed rel_error > TOL') + # check = 0 + import pdb + + pdb.set_trace() + if print_info: + print(" ") + print("model reformulation checked: relative error <= TOL = ", str(TOL)) + print(" ") + check = 1 + ## helpful for debugging: + # # use in calling function and compare + # # compare f_impl(i) with gnsf_val1(i) + # + + # nx = gnsf['nx'] + # nu = gnsf['nu'] + # nz = gnsf['nz'] + # nx1 = gnsf['nx1'] + # nx2 = gnsf['nx2'] + # + # A = gnsf['A'] + # B = gnsf['B'] + # C = gnsf['C'] + # E = gnsf['E'] + # c = gnsf['c'] + # + # L_x = gnsf['L_x'] + # L_z = gnsf['L_z'] + # L_xdot = gnsf['L_xdot'] + # L_u = gnsf['L_u'] + # + # A_LO = gnsf['A_LO'] + # + # x0 = rand(nx, 1) + # x0dot = rand(nx, 1) + # z0 = rand(nz, 1) + # u0 = rand(nu, 1) + # I_x1 = range(nx1) + # I_x2 = nx1+range(nx) + # + # y0 = L_x @ x0[I_x1] + L_xdot @ x0dot[I_x1] + L_z @ z0 + # uhat0 = L_u @ u0 + # + # gnsf_val1 = (A @ x[I_x1] + B @ u + # C @ phi_current + c) - E @ [xdot[I_x1] z] + # gnsf_val1 = gnsf_val1.simplify() + # + # # gnsf_val2 = A_LO @ x[I_x2] + gnsf['f_lo_fun'](x[I_x1], xdot[I_x1], z, u) - xdot[I_x2] + # gnsf_val2 = A_LO @ x[I_x2] + gnsf['f_lo_fun'](x[I_x1], xdot[I_x1], z, u) - xdot[I_x2] + # + # + # gnsf_val = [gnsf_val1 gnsf_val2] + # gnsf_val = gnsf_val.simplify() + # dyn_expr_f = dyn_expr_f.simplify() + # import pdb; pdb.set_trace() + + return check diff --git a/third_party/acados/acados_template/gnsf/detect_affine_terms_reduce_nonlinearity.py b/third_party/acados/acados_template/gnsf/detect_affine_terms_reduce_nonlinearity.py new file mode 100644 index 0000000000..ebf1f373a4 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/detect_affine_terms_reduce_nonlinearity.py @@ -0,0 +1,278 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + +from casadi import * +from .check_reformulation import check_reformulation +from .determine_input_nonlinearity_function import determine_input_nonlinearity_function +from ..utils import casadi_length, print_casadi_expression + + +def detect_affine_terms_reduce_nonlinearity(gnsf, acados_ocp, print_info): + + ## Description + # this function takes a gnsf structure with trivial model matrices (A, B, + # E, c are zeros, and C is eye). + # It detects all affine linear terms and sets up an equivalent model in the + # GNSF structure, where all affine linear terms are modeled through the + # matrices A, B, E, c and the linear output system (LOS) is empty. + # NOTE: model is just taken as an argument to check equivalence of the + # models within the function. + + model = acados_ocp.model + if print_info: + print(" ") + print("====================================================================") + print(" ") + print("============ Detect affine-linear dependencies ==================") + print(" ") + print("====================================================================") + print(" ") + # symbolics + x = gnsf["x"] + xdot = gnsf["xdot"] + u = gnsf["u"] + z = gnsf["z"] + + # dimensions + nx = gnsf["nx"] + nu = gnsf["nu"] + nz = gnsf["nz"] + + ny_old = gnsf["ny"] + nuhat_old = gnsf["nuhat"] + + ## Represent all affine dependencies through the model matrices A, B, E, c + ## determine A + n_nodes_current = n_nodes(gnsf["phi_expr"]) + + for ii in range(casadi_length(gnsf["phi_expr"])): + fii = gnsf["phi_expr"][ii] + for ix in range(nx): + var = x[ix] + varname = var.name + # symbolic jacobian of fii w.r.t. xi + jac_fii_xi = jacobian(fii, var) + if jac_fii_xi.is_constant(): + # jacobian value + jac_fii_xi_fun = Function("jac_fii_xi_fun", [x[1]], [jac_fii_xi]) + # x[1] as input just to have a scalar input and call the function as follows: + gnsf["A"][ii, ix] = jac_fii_xi_fun(0).full() + else: + gnsf["A"][ii, ix] = 0 + if print_info: + print( + "phi(", + str(ii), + ") is nonlinear in x(", + str(ix), + ") = ", + varname, + ) + print(fii) + print("-----------------------------------------------------") + f_next = gnsf["phi_expr"] - gnsf["A"] @ x + f_next = simplify(f_next) + n_nodes_next = n_nodes(f_next) + + if print_info: + print("\n") + print(f"determined matrix A:") + print(gnsf["A"]) + print(f"reduced nonlinearity from {n_nodes_current} to {n_nodes_next} nodes") + # assert(n_nodes_current >= n_nodes_next,'n_nodes_current >= n_nodes_next FAILED') + gnsf["phi_expr"] = f_next + + check_reformulation(model, gnsf, print_info) + + ## determine B + n_nodes_current = n_nodes(gnsf["phi_expr"]) + + for ii in range(casadi_length(gnsf["phi_expr"])): + fii = gnsf["phi_expr"][ii] + for iu in range(nu): + var = u[iu] + varname = var.name + # symbolic jacobian of fii w.r.t. ui + jac_fii_ui = jacobian(fii, var) + if jac_fii_ui.is_constant(): # i.e. hessian is structural zero: + # jacobian value + jac_fii_ui_fun = Function("jac_fii_ui_fun", [x[1]], [jac_fii_ui]) + gnsf["B"][ii, iu] = jac_fii_ui_fun(0).full() + else: + gnsf["B"][ii, iu] = 0 + if print_info: + print(f"phi({ii}) is nonlinear in u(", str(iu), ") = ", varname) + print(fii) + print("-----------------------------------------------------") + f_next = gnsf["phi_expr"] - gnsf["B"] @ u + f_next = simplify(f_next) + n_nodes_next = n_nodes(f_next) + + if print_info: + print("\n") + print(f"determined matrix B:") + print(gnsf["B"]) + print(f"reduced nonlinearity from {n_nodes_current} to {n_nodes_next} nodes") + + gnsf["phi_expr"] = f_next + + check_reformulation(model, gnsf, print_info) + + ## determine E + n_nodes_current = n_nodes(gnsf["phi_expr"]) + k = vertcat(xdot, z) + + for ii in range(casadi_length(gnsf["phi_expr"])): + fii = gnsf["phi_expr"][ii] + for ik in range(casadi_length(k)): + # symbolic jacobian of fii w.r.t. ui + var = k[ik] + varname = var.name + jac_fii_ki = jacobian(fii, var) + if jac_fii_ki.is_constant(): + # jacobian value + jac_fii_ki_fun = Function("jac_fii_ki_fun", [x[1]], [jac_fii_ki]) + gnsf["E"][ii, ik] = -jac_fii_ki_fun(0).full() + else: + gnsf["E"][ii, ik] = 0 + if print_info: + print(f"phi( {ii}) is nonlinear in xdot_z({ik}) = ", varname) + print(fii) + print("-----------------------------------------------------") + f_next = gnsf["phi_expr"] + gnsf["E"] @ k + f_next = simplify(f_next) + n_nodes_next = n_nodes(f_next) + + if print_info: + print("\n") + print(f"determined matrix E:") + print(gnsf["E"]) + print(f"reduced nonlinearity from {n_nodes_current} to {n_nodes_next} nodes") + + gnsf["phi_expr"] = f_next + check_reformulation(model, gnsf, print_info) + + ## determine constant term c + + n_nodes_current = n_nodes(gnsf["phi_expr"]) + for ii in range(casadi_length(gnsf["phi_expr"])): + fii = gnsf["phi_expr"][ii] + if fii.is_constant(): + # function value goes into c + fii_fun = Function("fii_fun", [x[1]], [fii]) + gnsf["c"][ii] = fii_fun(0).full() + else: + gnsf["c"][ii] = 0 + if print_info: + print(f"phi(", str(ii), ") is NOT constant") + print(fii) + print("-----------------------------------------------------") + gnsf["phi_expr"] = gnsf["phi_expr"] - gnsf["c"] + gnsf["phi_expr"] = simplify(gnsf["phi_expr"]) + n_nodes_next = n_nodes(gnsf["phi_expr"]) + + if print_info: + print("\n") + print(f"determined vector c:") + print(gnsf["c"]) + print(f"reduced nonlinearity from {n_nodes_current} to {n_nodes_next} nodes") + + check_reformulation(model, gnsf, print_info) + + ## determine nonlinearity & corresponding matrix C + ## Reduce dimension of phi + n_nodes_current = n_nodes(gnsf["phi_expr"]) + ind_non_zero = [] + for ii in range(casadi_length(gnsf["phi_expr"])): + fii = gnsf["phi_expr"][ii] + fii = simplify(fii) + if not fii.is_zero(): + ind_non_zero = list(set.union(set(ind_non_zero), set([ii]))) + gnsf["phi_expr"] = gnsf["phi_expr"][ind_non_zero] + + # C + gnsf["C"] = np.zeros((nx + nz, len(ind_non_zero))) + for ii in range(len(ind_non_zero)): + gnsf["C"][ind_non_zero[ii], ii] = 1 + gnsf = determine_input_nonlinearity_function(gnsf) + n_nodes_next = n_nodes(gnsf["phi_expr"]) + + if print_info: + print(" ") + print("determined matrix C:") + print(gnsf["C"]) + print( + "---------------------------------------------------------------------------------" + ) + print( + "------------- Success: Affine linear terms detected -----------------------------" + ) + print( + "---------------------------------------------------------------------------------" + ) + print( + f'reduced nonlinearity dimension n_out from {nx+nz} to {gnsf["n_out"]}' + ) + print(f"reduced nonlinearity from {n_nodes_current} to {n_nodes_next} nodes") + print(" ") + print("phi now reads as:") + print_casadi_expression(gnsf["phi_expr"]) + + ## determine input of nonlinearity function + check_reformulation(model, gnsf, print_info) + + gnsf["ny"] = casadi_length(gnsf["y"]) + gnsf["nuhat"] = casadi_length(gnsf["uhat"]) + + if print_info: + print( + "-----------------------------------------------------------------------------------" + ) + print(" ") + print( + f"reduced input ny of phi from ", + str(ny_old), + " to ", + str(gnsf["ny"]), + ) + print( + f"reduced input nuhat of phi from ", + str(nuhat_old), + " to ", + str(gnsf["nuhat"]), + ) + print( + "-----------------------------------------------------------------------------------" + ) + + # if print_info: + # print(f"gnsf: {gnsf}") + + return gnsf diff --git a/third_party/acados/acados_template/gnsf/detect_gnsf_structure.py b/third_party/acados/acados_template/gnsf/detect_gnsf_structure.py new file mode 100644 index 0000000000..24ffe643b8 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/detect_gnsf_structure.py @@ -0,0 +1,240 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# Author: Jonathan Frey: jonathanpaulfrey(at)gmail.com + +from casadi import Function, jacobian, SX, vertcat, horzcat + +from .determine_trivial_gnsf_transcription import determine_trivial_gnsf_transcription +from .detect_affine_terms_reduce_nonlinearity import ( + detect_affine_terms_reduce_nonlinearity, +) +from .reformulate_with_LOS import reformulate_with_LOS +from .reformulate_with_invertible_E_mat import reformulate_with_invertible_E_mat +from .structure_detection_print_summary import structure_detection_print_summary +from .check_reformulation import check_reformulation + + +def detect_gnsf_structure(acados_ocp, transcribe_opts=None): + + ## Description + # This function takes a CasADi implicit ODE or index-1 DAE model "model" + # consisting of a CasADi expression f_impl in the symbolic CasADi + # variables x, xdot, u, z, (and possibly parameters p), which are also part + # of the model, as well as a model name. + # It will create a struct "gnsf" containing all information needed to use + # it with the gnsf integrator in acados. + # Additionally it will create the struct "reordered_model" which contains + # the permuted state vector and permuted f_impl, in which additionally some + # functions, which were made part of the linear output system of the gnsf, + # have changed signs. + + # Options: transcribe_opts is a Matlab struct consisting of booleans: + # print_info: if extensive information on how the model is processed + # is printed to the console. + # generate_gnsf_model: if the neccessary C functions to simulate the gnsf + # model with the acados implementation of the GNSF exploiting + # integrator should be generated. + # generate_gnsf_model: if the neccessary C functions to simulate the + # reordered model with the acados implementation of the IRK + # integrator should be generated. + # check_E_invertibility: if the transcription method should check if the + # assumption that the main blocks of the matrix gnsf.E are invertible + # holds. If not, the method will try to reformulate the gnsf model + # with a different model, such that the assumption holds. + + # acados_root_dir = getenv('ACADOS_INSTALL_DIR') + + ## load transcribe_opts + if transcribe_opts is None: + print("WARNING: GNSF structure detection called without transcribe_opts") + print(" using default settings") + print("") + transcribe_opts = dict() + + if "print_info" in transcribe_opts: + print_info = transcribe_opts["print_info"] + else: + print_info = 1 + print("print_info option was not set - default is true") + + if "detect_LOS" in transcribe_opts: + detect_LOS = transcribe_opts["detect_LOS"] + else: + detect_LOS = 1 + if print_info: + print("detect_LOS option was not set - default is true") + + if "check_E_invertibility" in transcribe_opts: + check_E_invertibility = transcribe_opts["check_E_invertibility"] + else: + check_E_invertibility = 1 + if print_info: + print("check_E_invertibility option was not set - default is true") + + ## Reformulate implicit index-1 DAE into GNSF form + # (Generalized nonlinear static feedback) + gnsf = determine_trivial_gnsf_transcription(acados_ocp, print_info) + gnsf = detect_affine_terms_reduce_nonlinearity(gnsf, acados_ocp, print_info) + + if detect_LOS: + gnsf = reformulate_with_LOS(acados_ocp, gnsf, print_info) + + if check_E_invertibility: + gnsf = reformulate_with_invertible_E_mat(gnsf, acados_ocp, print_info) + + # detect purely linear model + if gnsf["nx1"] == 0 and gnsf["nz1"] == 0 and gnsf["nontrivial_f_LO"] == 0: + gnsf["purely_linear"] = 1 + else: + gnsf["purely_linear"] = 0 + + structure_detection_print_summary(gnsf, acados_ocp) + check_reformulation(acados_ocp.model, gnsf, print_info) + + ## copy relevant fields from gnsf to model + acados_ocp.model.get_matrices_fun = Function() + dummy = acados_ocp.model.x[0] + model_name = acados_ocp.model.name + + get_matrices_fun = Function( + f"{model_name}_gnsf_get_matrices_fun", + [dummy], + [ + gnsf["A"], + gnsf["B"], + gnsf["C"], + gnsf["E"], + gnsf["L_x"], + gnsf["L_xdot"], + gnsf["L_z"], + gnsf["L_u"], + gnsf["A_LO"], + gnsf["c"], + gnsf["E_LO"], + gnsf["B_LO"], + gnsf["nontrivial_f_LO"], + gnsf["purely_linear"], + gnsf["ipiv_x"] + 1, + gnsf["ipiv_z"] + 1, + gnsf["c_LO"], + ], + ) + + phi = gnsf["phi_expr"] + y = gnsf["y"] + uhat = gnsf["uhat"] + p = gnsf["p"] + + jac_phi_y = jacobian(phi, y) + jac_phi_uhat = jacobian(phi, uhat) + + phi_fun = Function(f"{model_name}_gnsf_phi_fun", [y, uhat, p], [phi]) + acados_ocp.model.phi_fun = phi_fun + acados_ocp.model.phi_fun_jac_y = Function( + f"{model_name}_gnsf_phi_fun_jac_y", [y, uhat, p], [phi, jac_phi_y] + ) + acados_ocp.model.phi_jac_y_uhat = Function( + f"{model_name}_gnsf_phi_jac_y_uhat", [y, uhat, p], [jac_phi_y, jac_phi_uhat] + ) + + x1 = acados_ocp.model.x[gnsf["idx_perm_x"][: gnsf["nx1"]]] + x1dot = acados_ocp.model.xdot[gnsf["idx_perm_x"][: gnsf["nx1"]]] + if gnsf["nz1"] > 0: + z1 = acados_ocp.model.z[gnsf["idx_perm_z"][: gnsf["nz1"]]] + else: + z1 = SX.sym("z1", 0, 0) + f_lo = gnsf["f_lo_expr"] + u = acados_ocp.model.u + acados_ocp.model.f_lo_fun_jac_x1k1uz = Function( + f"{model_name}_gnsf_f_lo_fun_jac_x1k1uz", + [x1, x1dot, z1, u, p], + [ + f_lo, + horzcat( + jacobian(f_lo, x1), + jacobian(f_lo, x1dot), + jacobian(f_lo, u), + jacobian(f_lo, z1), + ), + ], + ) + + acados_ocp.model.get_matrices_fun = get_matrices_fun + + size_gnsf_A = gnsf["A"].shape + acados_ocp.dims.gnsf_nx1 = size_gnsf_A[1] + acados_ocp.dims.gnsf_nz1 = size_gnsf_A[0] - size_gnsf_A[1] + acados_ocp.dims.gnsf_nuhat = max(phi_fun.size_in(1)) + acados_ocp.dims.gnsf_ny = max(phi_fun.size_in(0)) + acados_ocp.dims.gnsf_nout = max(phi_fun.size_out(0)) + + # # dim + # model['dim_gnsf_nx1'] = gnsf['nx1'] + # model['dim_gnsf_nx2'] = gnsf['nx2'] + # model['dim_gnsf_nz1'] = gnsf['nz1'] + # model['dim_gnsf_nz2'] = gnsf['nz2'] + # model['dim_gnsf_nuhat'] = gnsf['nuhat'] + # model['dim_gnsf_ny'] = gnsf['ny'] + # model['dim_gnsf_nout'] = gnsf['n_out'] + + # # sym + # model['sym_gnsf_y'] = gnsf['y'] + # model['sym_gnsf_uhat'] = gnsf['uhat'] + + # # data + # model['dyn_gnsf_A'] = gnsf['A'] + # model['dyn_gnsf_A_LO'] = gnsf['A_LO'] + # model['dyn_gnsf_B'] = gnsf['B'] + # model['dyn_gnsf_B_LO'] = gnsf['B_LO'] + # model['dyn_gnsf_E'] = gnsf['E'] + # model['dyn_gnsf_E_LO'] = gnsf['E_LO'] + # model['dyn_gnsf_C'] = gnsf['C'] + # model['dyn_gnsf_c'] = gnsf['c'] + # model['dyn_gnsf_c_LO'] = gnsf['c_LO'] + # model['dyn_gnsf_L_x'] = gnsf['L_x'] + # model['dyn_gnsf_L_xdot'] = gnsf['L_xdot'] + # model['dyn_gnsf_L_z'] = gnsf['L_z'] + # model['dyn_gnsf_L_u'] = gnsf['L_u'] + # model['dyn_gnsf_idx_perm_x'] = gnsf['idx_perm_x'] + # model['dyn_gnsf_ipiv_x'] = gnsf['ipiv_x'] + # model['dyn_gnsf_idx_perm_z'] = gnsf['idx_perm_z'] + # model['dyn_gnsf_ipiv_z'] = gnsf['ipiv_z'] + # model['dyn_gnsf_idx_perm_f'] = gnsf['idx_perm_f'] + # model['dyn_gnsf_ipiv_f'] = gnsf['ipiv_f'] + + # # flags + # model['dyn_gnsf_nontrivial_f_LO'] = gnsf['nontrivial_f_LO'] + # model['dyn_gnsf_purely_linear'] = gnsf['purely_linear'] + + # # casadi expr + # model['dyn_gnsf_expr_phi'] = gnsf['phi_expr'] + # model['dyn_gnsf_expr_f_lo'] = gnsf['f_lo_expr'] + + return acados_ocp diff --git a/third_party/acados/acados_template/gnsf/determine_input_nonlinearity_function.py b/third_party/acados/acados_template/gnsf/determine_input_nonlinearity_function.py new file mode 100644 index 0000000000..94aa001c79 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/determine_input_nonlinearity_function.py @@ -0,0 +1,110 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# Author: Jonathan Frey: jonathanpaulfrey(at)gmail.com + +from casadi import * +from ..utils import casadi_length, is_empty + + +def determine_input_nonlinearity_function(gnsf): + + ## Description + # this function takes a structure gnsf and updates the matrices L_x, + # L_xdot, L_z, L_u and CasADi vectors y, uhat of this structure as follows: + + # given a CasADi expression phi_expr, which may depend on the variables + # (x1, x1dot, z, u), this function determines a vector y (uhat) consisting + # of all components of (x1, x1dot, z) (respectively u) that enter phi_expr. + # Additionally matrices L_x, L_xdot, L_z, L_u are determined such that + # y = L_x * x + L_xdot * xdot + L_z * z + # uhat = L_u * u + # Furthermore the dimensions ny, nuhat, n_out are updated + + ## y + y = SX.sym('y', 0, 0) + # components of x1 + for ii in range(gnsf["nx1"]): + if which_depends(gnsf["phi_expr"], gnsf["x"][ii])[0]: + y = vertcat(y, gnsf["x"][ii]) + # else: + # x[ii] is not part of y + # components of x1dot + for ii in range(gnsf["nx1"]): + if which_depends(gnsf["phi_expr"], gnsf["xdot"][ii])[0]: + print(gnsf["phi_expr"], "depends on", gnsf["xdot"][ii]) + y = vertcat(y, gnsf["xdot"][ii]) + # else: + # xdot[ii] is not part of y + # components of z + for ii in range(gnsf["nz1"]): + if which_depends(gnsf["phi_expr"], gnsf["z"][ii])[0]: + y = vertcat(y, gnsf["z"][ii]) + # else: + # z[ii] is not part of y + ## uhat + uhat = SX.sym('uhat', 0, 0) + # components of u + for ii in range(gnsf["nu"]): + if which_depends(gnsf["phi_expr"], gnsf["u"][ii])[0]: + uhat = vertcat(uhat, gnsf["u"][ii]) + # else: + # u[ii] is not part of uhat + ## generate gnsf['phi_expr_fun'] + # linear input matrices + if is_empty(y): + gnsf["L_x"] = [] + gnsf["L_xdot"] = [] + gnsf["L_u"] = [] + gnsf["L_z"] = [] + else: + dummy = SX.sym("dummy_input", 0) + L_x_fun = Function( + "L_x_fun", [dummy], [jacobian(y, gnsf["x"][range(gnsf["nx1"])])] + ) + L_xdot_fun = Function( + "L_xdot_fun", [dummy], [jacobian(y, gnsf["xdot"][range(gnsf["nx1"])])] + ) + L_z_fun = Function( + "L_z_fun", [dummy], [jacobian(y, gnsf["z"][range(gnsf["nz1"])])] + ) + L_u_fun = Function("L_u_fun", [dummy], [jacobian(uhat, gnsf["u"])]) + + gnsf["L_x"] = L_x_fun(0).full() + gnsf["L_xdot"] = L_xdot_fun(0).full() + gnsf["L_u"] = L_u_fun(0).full() + gnsf["L_z"] = L_z_fun(0).full() + gnsf["y"] = y + gnsf["uhat"] = uhat + + gnsf["ny"] = casadi_length(y) + gnsf["nuhat"] = casadi_length(uhat) + gnsf["n_out"] = casadi_length(gnsf["phi_expr"]) + + return gnsf diff --git a/third_party/acados/acados_template/gnsf/determine_trivial_gnsf_transcription.py b/third_party/acados/acados_template/gnsf/determine_trivial_gnsf_transcription.py new file mode 100644 index 0000000000..23c2440537 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/determine_trivial_gnsf_transcription.py @@ -0,0 +1,155 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# + +from casadi import * +import numpy as np +from ..utils import casadi_length, idx_perm_to_ipiv +from .determine_input_nonlinearity_function import determine_input_nonlinearity_function +from .check_reformulation import check_reformulation + + +def determine_trivial_gnsf_transcription(acados_ocp, print_info): + ## Description + # this function takes a model of an implicit ODE/ index-1 DAE and sets up + # an equivalent model in the GNSF structure, with empty linear output + # system and trivial model matrices, i.e. A, B, E, c are zeros, and C is + # eye. - no structure is exploited + + model = acados_ocp.model + # initial print + print("*****************************************************************") + print(" ") + print(f"****** Restructuring {model.name} model ***********") + print(" ") + print("*****************************************************************") + + # load model + f_impl_expr = model.f_impl_expr + + model_name_prefix = model.name + + # x + x = model.x + nx = acados_ocp.dims.nx + # check type + if isinstance(x[0], SX): + isSX = True + else: + print("GNSF detection only works for SX CasADi type!!!") + import pdb + + pdb.set_trace() + # xdot + xdot = model.xdot + # u + nu = acados_ocp.dims.nu + if nu == 0: + u = SX.sym("u", 0, 0) + else: + u = model.u + + nz = acados_ocp.dims.nz + if nz == 0: + z = SX.sym("z", 0, 0) + else: + z = model.z + + p = model.p + nparam = acados_ocp.dims.np + + # avoid SX of size 0x1 + if casadi_length(u) == 0: + u = SX.sym("u", 0, 0) + nu = 0 + ## initialize gnsf struct + # dimensions + gnsf = {"nx": nx, "nu": nu, "nz": nz, "np": nparam} + gnsf["nx1"] = nx + gnsf["nx2"] = 0 + gnsf["nz1"] = nz + gnsf["nz2"] = 0 + gnsf["nuhat"] = nu + gnsf["ny"] = 2 * nx + nz + + gnsf["phi_expr"] = f_impl_expr + gnsf["A"] = np.zeros((nx + nz, nx)) + gnsf["B"] = np.zeros((nx + nz, nu)) + gnsf["E"] = np.zeros((nx + nz, nx + nz)) + gnsf["c"] = np.zeros((nx + nz, 1)) + gnsf["C"] = np.eye(nx + nz) + gnsf["name"] = model_name_prefix + + gnsf["x"] = x + gnsf["xdot"] = xdot + gnsf["z"] = z + gnsf["u"] = u + gnsf["p"] = p + + gnsf = determine_input_nonlinearity_function(gnsf) + + gnsf["A_LO"] = [] + gnsf["E_LO"] = [] + gnsf["B_LO"] = [] + gnsf["c_LO"] = [] + gnsf["f_lo_expr"] = [] + + # permutation + gnsf["idx_perm_x"] = range(nx) # matlab-style) + gnsf["ipiv_x"] = idx_perm_to_ipiv(gnsf["idx_perm_x"]) # blasfeo-style + gnsf["idx_perm_z"] = range(nz) + gnsf["ipiv_z"] = idx_perm_to_ipiv(gnsf["idx_perm_z"]) + gnsf["idx_perm_f"] = range((nx + nz)) + gnsf["ipiv_f"] = idx_perm_to_ipiv(gnsf["idx_perm_f"]) + + gnsf["nontrivial_f_LO"] = 0 + + check_reformulation(model, gnsf, print_info) + if print_info: + print(f"Success: Set up equivalent GNSF model with trivial matrices") + print(" ") + if print_info: + print( + "-----------------------------------------------------------------------------------" + ) + print(" ") + print( + "reduced input ny of phi from ", + str(2 * nx + nz), + " to ", + str(gnsf["ny"]), + ) + print( + "reduced input nuhat of phi from ", str(nu), " to ", str(gnsf["nuhat"]) + ) + print(" ") + print( + "-----------------------------------------------------------------------------------" + ) + return gnsf diff --git a/third_party/acados/acados_template/gnsf/matlab to python.md b/third_party/acados/acados_template/gnsf/matlab to python.md new file mode 100644 index 0000000000..53a0ed971e --- /dev/null +++ b/third_party/acados/acados_template/gnsf/matlab to python.md @@ -0,0 +1,43 @@ +# matlab to python + +% -> # + +; -> + +from casadi import * +-> +from casadi import * + + +print\('(.*)'\) +print('$1') + +print\(\['(.*)'\]\) +print(f'$1') + +keyboard +import pdb; pdb.set_trace() + + +range((([^))]*)) +range($1) + +\s*end +-> +nothing + + +if (.*) +if $1: + +else +else: + +num2str +str + +for ([a-z_]*) = +for $1 in + +length\( +len( \ No newline at end of file diff --git a/third_party/acados/acados_template/gnsf/reformulate_with_LOS.py b/third_party/acados/acados_template/gnsf/reformulate_with_LOS.py new file mode 100644 index 0000000000..297a56556c --- /dev/null +++ b/third_party/acados/acados_template/gnsf/reformulate_with_LOS.py @@ -0,0 +1,394 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# Author: Jonathan Frey: jonathanpaulfrey(at)gmail.com + +from .determine_input_nonlinearity_function import determine_input_nonlinearity_function +from .check_reformulation import check_reformulation +from casadi import * +from ..utils import casadi_length, idx_perm_to_ipiv, is_empty + + +def reformulate_with_LOS(acados_ocp, gnsf, print_info): + + ## Description: + # This function takes an intitial transcription of the implicit ODE model + # "model" into "gnsf" and reformulates "gnsf" with a linear output system + # (LOS), containing as many states of the model as possible. + # Therefore it might be that the state vector and the implicit function + # vector have to be reordered. This reordered model is part of the output, + # namely reordered_model. + + ## import CasADi and load models + model = acados_ocp.model + + # symbolics + x = gnsf["x"] + xdot = gnsf["xdot"] + u = gnsf["u"] + z = gnsf["z"] + + # dimensions + nx = gnsf["nx"] + nz = gnsf["nz"] + + # get model matrices + A = gnsf["A"] + B = gnsf["B"] + C = gnsf["C"] + E = gnsf["E"] + c = gnsf["c"] + + A_LO = gnsf["A_LO"] + + y = gnsf["y"] + + phi_old = gnsf["phi_expr"] + + if print_info: + print(" ") + print("=================================================================") + print(" ") + print("================ Detect Linear Output System ===============") + print(" ") + print("=================================================================") + print(" ") + ## build initial I_x1 and I_x2_candidates + # I_xrange( all components of x for which either xii or xdot_ii enters y): + # I_LOS_candidates: the remaining components + + I_nsf_components = set() + I_LOS_candidates = set() + + if gnsf["ny"] > 0: + for ii in range(nx): + if which_depends(y, x[ii])[0] or which_depends(y, xdot[ii])[0]: + # i.e. xii or xiidot are part of y, and enter phi_expr + if print_info: + print(f"x_{ii} is part of x1") + I_nsf_components = set.union(I_nsf_components, set([ii])) + else: + # i.e. neither xii nor xiidot are part of y, i.e. enter phi_expr + I_LOS_candidates = set.union(I_LOS_candidates, set([ii])) + if print_info: + print(" ") + for ii in range(nz): + if which_depends(y, z[ii])[0]: + # i.e. xii or xiidot are part of y, and enter phi_expr + if print_info: + print(f"z_{ii} is part of x1") + I_nsf_components = set.union(I_nsf_components, set([ii + nx])) + else: + # i.e. neither xii nor xiidot are part of y, i.e. enter phi_expr + I_LOS_candidates = set.union(I_LOS_candidates, set([ii + nx])) + else: + I_LOS_candidates = set(range((nx + nz))) + if print_info: + print(" ") + print(f"I_LOS_candidates {I_LOS_candidates}") + new_nsf_components = I_nsf_components + I_nsf_eq = set([]) + unsorted_dyn = set(range(nx + nz)) + xdot_z = vertcat(xdot, z) + + ## determine components of Linear Output System + # determine maximal index set I_x2 + # such that the components x(I_x2) can be written as a LOS + Eq_map = [] + while True: + ## find equations corresponding to new_nsf_components + for ii in new_nsf_components: + current_var = xdot_z[ii] + var_name = current_var.name + + # print( unsorted_dyn) + # print("np.nonzero(E[:,ii])[0]",np.nonzero(E[:,ii])[0]) + I_eq = set.intersection(set(np.nonzero(E[:, ii])[0]), unsorted_dyn) + if len(I_eq) == 1: + i_eq = I_eq.pop() + if print_info: + print(f"component {i_eq} is associated with state {ii}") + elif len(I_eq) > 1: # x_ii_dot occurs in more than 1 eq linearly + # find the equation with least linear dependencies on + # I_LOS_cancidates + number_of_eq = 0 + candidate_dependencies = np.zeros(len(I_eq), 1) + I_x2_candidates = set.intersection(I_LOS_candidates, set(range(nx))) + for eq in I_eq: + depending_candidates = set.union( + np.nonzero(E[eq, I_LOS_candidates])[0], + np.nonzero(A[eq, I_x2_candidates])[0], + ) + candidate_dependencies[number_of_eq] = +len(depending_candidates) + number_of_eq += 1 + number_of_eq = np.argmin(candidate_dependencies) + i_eq = I_eq[number_of_eq] + else: ## x_ii_dot does not occur linearly in any of the unsorted dynamics + for j in unsorted_dyn: + phi_eq_j = gnsf["phi_expr"][np.nonzero(C[j, :])[0]] + if which_depends(phi_eq_j, xdot_z(ii))[0]: + I_eq = set.union(I_eq, j) + if is_empty(I_eq): + I_eq = unsorted_dyn + # find the equation with least linear dependencies on I_LOS_cancidates + number_of_eq = 0 + candidate_dependencies = np.zeros(len(I_eq), 1) + I_x2_candidates = set.intersection(I_LOS_candidates, set(range(nx))) + for eq in I_eq: + depending_candidates = set.union( + np.nonzero(E[eq, I_LOS_candidates])[0], + np.nonzero(A[eq, I_x2_candidates])[0], + ) + candidate_dependencies[number_of_eq] = +len(depending_candidates) + number_of_eq += 1 + number_of_eq = np.argmin(candidate_dependencies) + i_eq = I_eq[number_of_eq] + ## add 1 * [xdot,z](ii) to both sides of i_eq + if print_info: + print( + "adding 1 * ", + var_name, + " to both sides of equation ", + i_eq, + ".", + ) + gnsf["E"][i_eq, ii] = 1 + i_phi = np.nonzero(gnsf["C"][i_eq, :]) + if is_empty(i_phi): + i_phi = len(gnsf["phi_expr"]) + 1 + gnsf["C"][i_eq, i_phi] = 1 # add column to C with 1 entry + gnsf["phi_expr"] = vertcat(gnsf["phi_expr"], 0) + gnsf["phi_expr"][i_phi] = ( + gnsf["phi_expr"](i_phi) + + gnsf["E"][i_eq, ii] / gnsf["C"][i_eq, i_phi] * xdot_z[ii] + ) + if print_info: + print( + "detected equation ", + i_eq, + " to correspond to variable ", + var_name, + ) + I_nsf_eq = set.union(I_nsf_eq, {i_eq}) + # remove i_eq from unsorted_dyn + unsorted_dyn.remove(i_eq) + Eq_map.append([ii, i_eq]) + + ## add components to I_x1 + for eq in I_nsf_eq: + I_linear_dependence = set.union( + set(np.nonzero(A[eq, :])[0]), set(np.nonzero(E[eq, :])[0]) + ) + I_nsf_components = set.union(I_linear_dependence, I_nsf_components) + # I_nsf_components = I_nsf_components[:] + + new_nsf_components = set.intersection(I_LOS_candidates, I_nsf_components) + if is_empty(new_nsf_components): + if print_info: + print("new_nsf_components is empty") + break + # remove new_nsf_components from candidates + I_LOS_candidates = set.difference(I_LOS_candidates, new_nsf_components) + if not is_empty(Eq_map): + # [~, new_eq_order] = sort(Eq_map(1,:)) + # I_nsf_eq = Eq_map(2, new_eq_order ) + for count, m in enumerate(Eq_map): + m.append(count) + sorted(Eq_map, key=lambda x: x[1]) + new_eq_order = [m[2] for m in Eq_map] + Eq_map = [Eq_map[i] for i in new_eq_order] + I_nsf_eq = [m[1] for m in Eq_map] + + else: + I_nsf_eq = [] + + I_LOS_components = I_LOS_candidates + I_LOS_eq = sorted(set.difference(set(range(nx + nz)), I_nsf_eq)) + I_nsf_eq = sorted(I_nsf_eq) + + I_x1 = set.intersection(I_nsf_components, set(range(nx))) + I_z1 = set.intersection(I_nsf_components, set(range(nx, nx + nz))) + I_z1 = set([i - nx for i in I_z1]) + + I_x2 = set.intersection(I_LOS_components, set(range(nx))) + I_z2 = set.intersection(I_LOS_components, set(range(nx, nx + nz))) + I_z2 = set([i - nx for i in I_z2]) + + if print_info: + print(f"I_x1 {I_x1}, I_x2 {I_x2}") + + ## permute x, xdot + if is_empty(I_x1): + x1 = [] + x1dot = [] + else: + x1 = x[list(I_x1)] + x1dot = xdot[list(I_x1)] + if is_empty(I_x2): + x2 = [] + x2dot = [] + else: + x2 = x[list(I_x2)] + x2dot = xdot[list(I_x2)] + if is_empty(I_z1): + z1 = [] + else: + z1 = z(I_z1) + if is_empty(I_z2): + z2 = [] + else: + z2 = z[list(I_z2)] + + I_x1 = sorted(I_x1) + I_x2 = sorted(I_x2) + I_z1 = sorted(I_z1) + I_z2 = sorted(I_z2) + gnsf["xdot"] = vertcat(x1dot, x2dot) + gnsf["x"] = vertcat(x1, x2) + gnsf["z"] = vertcat(z1, z2) + gnsf["nx1"] = len(I_x1) + gnsf["nx2"] = len(I_x2) + gnsf["nz1"] = len(I_z1) + gnsf["nz2"] = len(I_z2) + + # store permutations + gnsf["idx_perm_x"] = I_x1 + I_x2 + gnsf["ipiv_x"] = idx_perm_to_ipiv(gnsf["idx_perm_x"]) + gnsf["idx_perm_z"] = I_z1 + I_z2 + gnsf["ipiv_z"] = idx_perm_to_ipiv(gnsf["idx_perm_z"]) + gnsf["idx_perm_f"] = I_nsf_eq + I_LOS_eq + gnsf["ipiv_f"] = idx_perm_to_ipiv(gnsf["idx_perm_f"]) + + f_LO = SX.sym("f_LO", 0, 0) + + ## rewrite I_LOS_eq as LOS + if gnsf["n_out"] == 0: + C_phi = np.zeros(gnsf["nx"] + gnsf["nz"], 1) + else: + C_phi = C @ phi_old + if gnsf["nx1"] == 0: + Ax1 = np.zeros(gnsf["nx"] + gnsf["nz"], 1) + else: + Ax1 = A[:, sorted(I_x1)] @ x1 + if gnsf["nx1"] + gnsf["nz1"] == 0: + lhs_nsf = np.zeros(gnsf["nx"] + gnsf["nz"], 1) + else: + lhs_nsf = E[:, sorted(I_nsf_components)] @ vertcat(x1, z1) + n_LO = len(I_LOS_eq) + B_LO = np.zeros((n_LO, gnsf["nu"])) + A_LO = np.zeros((gnsf["nx2"] + gnsf["nz2"], gnsf["nx2"])) + E_LO = np.zeros((n_LO, n_LO)) + c_LO = np.zeros((n_LO, 1)) + + I_LOS_eq = list(I_LOS_eq) + for eq in I_LOS_eq: + i_LO = I_LOS_eq.index(eq) + f_LO = vertcat(f_LO, Ax1[eq] + C_phi[eq] - lhs_nsf[eq]) + print(f"eq {eq} I_LOS_components {I_LOS_components}, i_LO {i_LO}, f_LO {f_LO}") + E_LO[i_LO, :] = E[eq, sorted(I_LOS_components)] + A_LO[i_LO, :] = A[eq, I_x2] + c_LO[i_LO, :] = c[eq] + B_LO[i_LO, :] = B[eq, :] + if casadi_length(f_LO) == 0: + f_LO = SX.zeros((gnsf["nx2"] + gnsf["nz2"], 1)) + f_LO = simplify(f_LO) + gnsf["A_LO"] = A_LO + gnsf["E_LO"] = E_LO + gnsf["B_LO"] = B_LO + gnsf["c_LO"] = c_LO + gnsf["f_lo_expr"] = f_LO + + ## remove I_LOS_eq from NSF type system + gnsf["A"] = gnsf["A"][np.ix_(sorted(I_nsf_eq), sorted(I_x1))] + gnsf["B"] = gnsf["B"][sorted(I_nsf_eq), :] + gnsf["C"] = gnsf["C"][sorted(I_nsf_eq), :] + gnsf["E"] = gnsf["E"][np.ix_(sorted(I_nsf_eq), sorted(I_nsf_components))] + gnsf["c"] = gnsf["c"][sorted(I_nsf_eq), :] + + ## reduce phi, C + I_nonzero = [] + for ii in range(gnsf["C"].shape[1]): # n_colums of C: + print(f"ii {ii}") + if not all(gnsf["C"][:, ii] == 0): # if column ~= 0 + I_nonzero.append(ii) + gnsf["C"] = gnsf["C"][:, I_nonzero] + gnsf["phi_expr"] = gnsf["phi_expr"][I_nonzero] + + gnsf = determine_input_nonlinearity_function(gnsf) + + check_reformulation(model, gnsf, print_info) + + gnsf["nontrivial_f_LO"] = 0 + if not is_empty(gnsf["f_lo_expr"]): + for ii in range(casadi_length(gnsf["f_lo_expr"])): + fii = gnsf["f_lo_expr"][ii] + if not fii.is_zero(): + gnsf["nontrivial_f_LO"] = 1 + if not gnsf["nontrivial_f_LO"] and print_info: + print("f_LO is fully trivial (== 0)") + check_reformulation(model, gnsf, print_info) + + if print_info: + print("") + print( + "---------------------------------------------------------------------------------" + ) + print( + "------------- Success: Linear Output System (LOS) detected ----------------------" + ) + print( + "---------------------------------------------------------------------------------" + ) + print("") + print( + "==>> moved ", + gnsf["nx2"], + "differential states and ", + gnsf["nz2"], + " algebraic variables to the Linear Output System", + ) + print( + "==>> recuced output dimension of phi from ", + casadi_length(phi_old), + " to ", + casadi_length(gnsf["phi_expr"]), + ) + print(" ") + print("Matrices defining the LOS read as") + print(" ") + print("E_LO =") + print(gnsf["E_LO"]) + print("A_LO =") + print(gnsf["A_LO"]) + print("B_LO =") + print(gnsf["B_LO"]) + print("c_LO =") + print(gnsf["c_LO"]) + + return gnsf diff --git a/third_party/acados/acados_template/gnsf/reformulate_with_invertible_E_mat.py b/third_party/acados/acados_template/gnsf/reformulate_with_invertible_E_mat.py new file mode 100644 index 0000000000..21ab8ebfd5 --- /dev/null +++ b/third_party/acados/acados_template/gnsf/reformulate_with_invertible_E_mat.py @@ -0,0 +1,167 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# Author: Jonathan Frey: jonathanpaulfrey(at)gmail.com + +from casadi import * +from .determine_input_nonlinearity_function import determine_input_nonlinearity_function +from .check_reformulation import check_reformulation + + +def reformulate_with_invertible_E_mat(gnsf, model, print_info): + ## Description + # this function checks that the necessary condition to apply the gnsf + # structure exploiting integrator to a model, namely that the matrices E11, + # E22 are invertible holds. + # if this is not the case, it will make these matrices invertible and add: + # corresponding terms, to the term C * phi, such that the obtained model is + # still equivalent + + # check invertibility of E11, E22 and reformulate if needed: + ind_11 = range(gnsf["nx1"]) + ind_22 = range(gnsf["nx1"], gnsf["nx1"] + gnsf["nz1"]) + + if print_info: + print(" ") + print("----------------------------------------------------") + print("checking rank of E11 and E22") + print("----------------------------------------------------") + ## check if E11, E22 are invertible: + z_check = False + if gnsf["nz1"] > 0: + z_check = ( + np.linalg.matrix_rank(gnsf["E"][np.ix_(ind_22, ind_22)]) != gnsf["nz1"] + ) + + if ( + np.linalg.matrix_rank(gnsf["E"][np.ix_(ind_11, ind_11)]) != gnsf["nx1"] + or z_check + ): + # print warning (always) + print(f"the rank of E11 or E22 is not full after the reformulation") + print("") + print( + f"the script will try to reformulate the model with an invertible matrix instead" + ) + print( + f"NOTE: this feature is based on a heuristic, it should be used with care!!!" + ) + + ## load models + xdot = gnsf["xdot"] + z = gnsf["z"] + + # # GNSF + # get dimensions + nx1 = gnsf["nx1"] + x1dot = xdot[range(nx1)] + + k = vertcat(x1dot, z) + for i in [1, 2]: + if i == 1: + ind = range(gnsf["nx1"]) + else: + ind = range(gnsf["nx1"], gnsf["nx1"] + gnsf["nz1"]) + mat = gnsf["E"][np.ix_(ind, ind)] + import pdb + + pdb.set_trace() + while np.linalg.matrix_rank(mat) < len(ind): + # import pdb; pdb.set_trace() + if print_info: + print(" ") + print(f"the rank of E", str(i), str(i), " is not full") + print( + f"the algorithm will try to reformulate the model with an invertible matrix instead" + ) + print( + f"NOTE: this feature is not super stable and might need more testing!!!!!!" + ) + for sub_max in ind: + sub_ind = range(min(ind), sub_max) + # regard the submatrix mat(sub_ind, sub_ind) + sub_mat = gnsf["E"][sub_ind, sub_ind] + if np.linalg.matrix_rank(sub_mat) < len(sub_ind): + # reformulate the model by adding a 1 to last diagonal + # element and changing rhs respectively. + gnsf["E"][sub_max, sub_max] = gnsf["E"][sub_max, sub_max] + 1 + # this means adding the term 1 * k(sub_max) to the sub_max + # row of the l.h.s + if len(np.nonzero(gnsf["C"][sub_max, :])[0]) == 0: + # if isempty(find(gnsf['C'](sub_max,:), 1)): + # add new nonlinearity entry + gnsf["C"][sub_max, gnsf["n_out"] + 1] = 1 + gnsf["phi_expr"] = vertcat(gnsf["phi_expr"], k[sub_max]) + else: + ind_f = np.nonzero(gnsf["C"][sub_max, :])[0] + if len(ind_f) != 1: + raise Exception("C is assumed to be a selection matrix") + else: + ind_f = ind_f[0] + # add term to corresponding nonlinearity entry + # note: herbey we assume that C is a selection matrix, + # i.e. gnsf['phi_expr'](ind_f) is only entering one equation + + gnsf["phi_expr"][ind_f] = ( + gnsf["phi_expr"][ind_f] + + k[sub_max] / gnsf["C"][sub_max, ind_f] + ) + gnsf = determine_input_nonlinearity_function(gnsf) + check_reformulation(model, gnsf, print_info) + print("successfully reformulated the model with invertible matrices E11, E22") + else: + if print_info: + print(" ") + print( + "the rank of both E11 and E22 is naturally full after the reformulation " + ) + print("==> model reformulation finished") + print(" ") + if (gnsf['nx2'] > 0 or gnsf['nz2'] > 0) and det(gnsf["E_LO"]) == 0: + print( + "_______________________________________________________________________________________________________" + ) + print(" ") + print("TAKE CARE ") + print("E_LO matrix is NOT regular after automatic transcription!") + print("->> this means the model CANNOT be used with the gnsf integrator") + print( + "->> it probably means that one entry (of xdot or z) that was moved to the linear output type system" + ) + print(" does not appear in the model at all (zero column in E_LO)") + print(" OR: the columns of E_LO are linearly dependent ") + print(" ") + print( + " SOLUTIONs: a) go through your model & check equations the method wanted to move to LOS" + ) + print(" b) deactivate the detect_LOS option") + print( + "_______________________________________________________________________________________________________" + ) + return gnsf diff --git a/third_party/acados/acados_template/gnsf/structure_detection_print_summary.py b/third_party/acados/acados_template/gnsf/structure_detection_print_summary.py new file mode 100644 index 0000000000..db2d18758e --- /dev/null +++ b/third_party/acados/acados_template/gnsf/structure_detection_print_summary.py @@ -0,0 +1,174 @@ +# +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; +# +# Author: Jonathan Frey: jonathanpaulfrey(at)gmail.com + +from casadi import n_nodes +import numpy as np + + +def structure_detection_print_summary(gnsf, acados_ocp): + + ## Description + # this function prints the most important info after determining a GNSF + # reformulation of the implicit model "initial_model" into "gnsf", which is + # equivalent to the "reordered_model". + model = acados_ocp.model + # # GNSF + # get dimensions + nx = gnsf["nx"] + nu = gnsf["nu"] + nz = gnsf["nz"] + + nx1 = gnsf["nx1"] + nx2 = gnsf["nx2"] + + nz1 = gnsf["nz1"] + nz2 = gnsf["nz2"] + + # np = gnsf['np'] + n_out = gnsf["n_out"] + ny = gnsf["ny"] + nuhat = gnsf["nuhat"] + + # + f_impl_expr = model.f_impl_expr + n_nodes_initial = n_nodes(model.f_impl_expr) + # x_old = model.x + # f_impl_old = model.f_impl_expr + + x = gnsf["x"] + z = gnsf["z"] + + phi_current = gnsf["phi_expr"] + + ## PRINT SUMMARY -- STRUCHTRE DETECTION + print(" ") + print( + "*********************************************************************************************" + ) + print(" ") + print( + "****************** SUCCESS: GNSF STRUCTURE DETECTION COMPLETE !!! ***************" + ) + print(" ") + print( + "*********************************************************************************************" + ) + print(" ") + print( + f"========================= STRUCTURE DETECTION SUMMARY ====================================" + ) + print(" ") + print("-------- Nonlinear Static Feedback type system --------") + print(" ") + print(" successfully transcribed dynamic system model into GNSF structure ") + print(" ") + print( + "reduced dimension of nonlinearity phi from ", + str(nx + nz), + " to ", + str(gnsf["n_out"]), + ) + print(" ") + print( + "reduced input dimension of nonlinearity phi from ", + 2 * nx + nz + nu, + " to ", + gnsf["ny"] + gnsf["nuhat"], + ) + print(" ") + print(f"reduced number of nodes in CasADi expression of nonlinearity phi from {n_nodes_initial} to {n_nodes(phi_current)}\n") + print("----------- Linear Output System (LOS) ---------------") + if nx2 + nz2 > 0: + print(" ") + print(f"introduced Linear Output System of size ", str(nx2 + nz2)) + print(" ") + if nx2 > 0: + print("consisting of the states:") + print(" ") + print(x[range(nx1, nx)]) + print(" ") + if nz2 > 0: + print("and algebraic variables:") + print(" ") + print(z[range(nz1, nz)]) + print(" ") + if gnsf["purely_linear"] == 1: + print(" ") + print("Model is fully linear!") + print(" ") + if not all(gnsf["idx_perm_x"] == np.array(range(nx))): + print(" ") + print( + "--------------------------------------------------------------------------------------------------" + ) + print( + "NOTE: permuted differential state vector x, such that x_gnsf = x(idx_perm_x) with idx_perm_x =" + ) + print(" ") + print(gnsf["idx_perm_x"]) + if nz != 0 and not all(gnsf["idx_perm_z"] == np.array(range(nz))): + print(" ") + print( + "--------------------------------------------------------------------------------------------------" + ) + print( + "NOTE: permuted algebraic state vector z, such that z_gnsf = z(idx_perm_z) with idx_perm_z =" + ) + print(" ") + print(gnsf["idx_perm_z"]) + if not all(gnsf["idx_perm_f"] == np.array(range(nx + nz))): + print(" ") + print( + "--------------------------------------------------------------------------------------------------" + ) + print( + "NOTE: permuted rhs expression vector f, such that f_gnsf = f(idx_perm_f) with idx_perm_f =" + ) + print(" ") + print(gnsf["idx_perm_f"]) + ## print GNSF dimensions + print( + "--------------------------------------------------------------------------------------------------------" + ) + print(" ") + print("The dimensions of the GNSF reformulated model read as:") + print(" ") + # T_dim = table(nx, nu, nz, np, nx1, nz1, n_out, ny, nuhat) + # print( T_dim ) + print(f"nx ", {nx}) + print(f"nu ", {nu}) + print(f"nz ", {nz}) + # print(f"np ", {np}) + print(f"nx1 ", {nx1}) + print(f"nz1 ", {nz1}) + print(f"n_out ", {n_out}) + print(f"ny ", {ny}) + print(f"nuhat ", {nuhat}) diff --git a/third_party/acados/acados_template/simulink_default_opts.json b/third_party/acados/acados_template/simulink_default_opts.json index 70c939cb88..5d178fef85 100644 --- a/third_party/acados/acados_template/simulink_default_opts.json +++ b/third_party/acados/acados_template/simulink_default_opts.json @@ -4,7 +4,9 @@ "utraj": 0, "xtraj": 0, "solver_status": 1, + "cost_value": 0, "KKT_residual": 1, + "KKT_residuals": 0, "x1": 1, "CPU_time": 1, "CPU_time_sim": 0, @@ -29,6 +31,8 @@ "ug": 1, "lh": 1, "uh": 1, + "lh_e": 1, + "uh_e": 1, "cost_W_0": 0, "cost_W": 0, "cost_W_e": 0, diff --git a/third_party/acados/acados_template/utils.py b/third_party/acados/acados_template/utils.py index 8f44f61e7e..d6f6c02f84 100644 --- a/third_party/acados/acados_template/utils.py +++ b/third_party/acados/acados_template/utils.py @@ -1,9 +1,6 @@ # -*- coding: future_fstrings -*- # -# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, -# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, -# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, -# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl +# Copyright (c) The acados authors. # # This file is part of acados. # @@ -38,10 +35,17 @@ import shutil import numpy as np from casadi import SX, MX, DM, Function, CasadiMeta -ALLOWED_CASADI_VERSIONS = ('3.5.5', '3.5.4', '3.5.3', '3.5.2', '3.5.1', '3.4.5', '3.4.0') +ALLOWED_CASADI_VERSIONS = ('3.5.6', '3.5.5', '3.5.4', '3.5.3', '3.5.2', '3.5.1', '3.4.5', '3.4.0') TERA_VERSION = "0.0.34" +PLATFORM2TERA = { + "linux": "linux", + "darwin": "osx", + "win32": "windows" +} + + def get_acados_path(): ACADOS_PATH = os.environ.get('ACADOS_SOURCE_DIR') if not ACADOS_PATH: @@ -72,20 +76,17 @@ def get_tera_exec_path(): return TERA_PATH -platform2tera = { - "linux": "linux", - "darwin": "osx", - "win32": "windows" -} - - -def casadi_version_warning(casadi_version): - msg = 'Warning: Please note that the following versions of CasADi are ' - msg += 'officially supported: {}.\n '.format(" or ".join(ALLOWED_CASADI_VERSIONS)) - msg += 'If there is an incompatibility with the CasADi generated code, ' - msg += 'please consider changing your CasADi version.\n' - msg += 'Version {} currently in use.'.format(casadi_version) - print(msg) +def check_casadi_version(): + casadi_version = CasadiMeta.version() + if casadi_version in ALLOWED_CASADI_VERSIONS: + return + else: + msg = 'Warning: Please note that the following versions of CasADi are ' + msg += 'officially supported: {}.\n '.format(" or ".join(ALLOWED_CASADI_VERSIONS)) + msg += 'If there is an incompatibility with the CasADi generated code, ' + msg += 'please consider changing your CasADi version.\n' + msg += 'Version {} currently in use.'.format(casadi_version) + print(msg) def is_column(x): @@ -118,11 +119,16 @@ def is_empty(x): return True else: return False - elif x == None or x == []: + elif x == None: return True + elif isinstance(x, (set, list)): + if len(x)==0: + return True + else: + return False else: raise Exception("is_empty expects one of the following types: casadi.MX, casadi.SX, " - + "None, numpy array empty list. Got: " + str(type(x))) + + "None, numpy array empty list, set. Got: " + str(type(x))) def casadi_length(x): @@ -155,6 +161,14 @@ def make_model_consistent(model): return model +def get_lib_ext(): + lib_ext = '.so' + if sys.platform == 'darwin': + lib_ext = '.dylib' + elif os.name == 'nt': + lib_ext = '' + + return lib_ext def get_tera(): tera_path = get_tera_exec_path() @@ -165,7 +179,7 @@ def get_tera(): repo_url = "https://github.com/acados/tera_renderer/releases" url = "{}/download/v{}/t_renderer-v{}-{}".format( - repo_url, TERA_VERSION, TERA_VERSION, platform2tera[sys.platform]) + repo_url, TERA_VERSION, TERA_VERSION, PLATFORM2TERA[sys.platform]) manual_install = 'For manual installation follow these instructions:\n' manual_install += '1 Download binaries from {}\n'.format(url) @@ -200,18 +214,19 @@ def get_tera(): sys.exit(1) -def render_template(in_file, out_file, template_dir, json_path): +def render_template(in_file, out_file, output_dir, json_path, template_glob=None): + + acados_path = os.path.dirname(os.path.abspath(__file__)) + if template_glob is None: + template_glob = os.path.join(acados_path, 'c_templates_tera', '**', '*') cwd = os.getcwd() - if not os.path.exists(template_dir): - os.mkdir(template_dir) - os.chdir(template_dir) + + if not os.path.exists(output_dir): + os.makedirs(output_dir) + os.chdir(output_dir) tera_path = get_tera() - # setting up loader and environment - acados_path = os.path.dirname(os.path.abspath(__file__)) - template_glob = os.path.join(acados_path, 'c_templates_tera', '*') - # call tera as system cmd os_cmd = f"{tera_path} '{template_glob}' '{in_file}' '{json_path}' '{out_file}'" # Windows cmd.exe can not cope with '...', so use "..." instead: @@ -220,21 +235,24 @@ def render_template(in_file, out_file, template_dir, json_path): status = os.system(os_cmd) if (status != 0): - raise Exception(f'Rendering of {in_file} failed!\n\nAttempted to execute OS command:\n{os_cmd}\n\nExiting.\n') + raise Exception(f'Rendering of {in_file} failed!\n\nAttempted to execute OS command:\n{os_cmd}\n\n') os.chdir(cwd) ## Conversion functions -def np_array_to_list(np_array): - if isinstance(np_array, (np.ndarray)): - return np_array.tolist() - elif isinstance(np_array, (SX)): - return DM(np_array).full() - elif isinstance(np_array, (DM)): - return np_array.full() +def make_object_json_dumpable(input): + if isinstance(input, (np.ndarray)): + return input.tolist() + elif isinstance(input, (SX)): + return input.serialize() + elif isinstance(input, (MX)): + # NOTE: MX expressions can not be serialized, only Functions. + return input.__str__() + elif isinstance(input, (DM)): + return input.full() else: - raise(Exception(f"Cannot convert to list type {type(np_array)}")) + raise TypeError(f"Cannot make input of type {type(input)} dumpable.") def format_class_dict(d): @@ -251,7 +269,7 @@ def format_class_dict(d): return out -def get_ocp_nlp_layout(): +def get_ocp_nlp_layout() -> dict: python_interface_path = get_python_interface_path() abs_path = os.path.join(python_interface_path, 'acados_layout.json') with open(abs_path, 'r') as f: @@ -259,62 +277,12 @@ def get_ocp_nlp_layout(): return ocp_nlp_layout -def ocp_check_against_layout(ocp_nlp, ocp_dims): - """ - Check dimensions against layout - Parameters - --------- - ocp_nlp : dict - dictionary loaded from JSON to be post-processed. - - ocp_dims : instance of AcadosOcpDims - """ - - ocp_nlp_layout = get_ocp_nlp_layout() - - ocp_check_against_layout_recursion(ocp_nlp, ocp_dims, ocp_nlp_layout) - return - - -def ocp_check_against_layout_recursion(ocp_nlp, ocp_dims, layout): - - for key, item in ocp_nlp.items(): - - try: - layout_of_key = layout[key] - except KeyError: - raise Exception("ocp_check_against_layout_recursion: field" \ - " '{0}' is not in layout but in OCP description.".format(key)) - - if isinstance(item, dict): - ocp_check_against_layout_recursion(item, ocp_dims, layout_of_key) - - if 'ndarray' in layout_of_key: - if isinstance(item, int) or isinstance(item, float): - item = np.array([item]) - if isinstance(item, (list, np.ndarray)) and (layout_of_key[0] != 'str'): - dim_layout = [] - dim_names = layout_of_key[1] - - for dim_name in dim_names: - dim_layout.append(ocp_dims[dim_name]) - - dims = tuple(dim_layout) - - item = np.array(item) - item_dims = item.shape - if len(item_dims) != len(dims): - raise Exception('Mismatching dimensions for field {0}. ' \ - 'Expected {1} dimensional array, got {2} dimensional array.' \ - .format(key, len(dims), len(item_dims))) - - if np.prod(item_dims) != 0 or np.prod(dims) != 0: - if dims != item_dims: - raise Exception('acados -- mismatching dimensions for field {0}. ' \ - 'Provided data has dimensions {1}, ' \ - 'while associated dimensions {2} are {3}' \ - .format(key, item_dims, dim_names, dims)) - return +def get_default_simulink_opts() -> dict: + python_interface_path = get_python_interface_path() + abs_path = os.path.join(python_interface_path, 'simulink_default_opts.json') + with open(abs_path, 'r') as f: + simulink_opts = json.load(f) + return simulink_opts def J_to_idx(J): @@ -324,9 +292,9 @@ def J_to_idx(J): this_idx = np.nonzero(J[i,:])[0] if len(this_idx) != 1: raise Exception('Invalid J matrix structure detected, ' \ - 'must contain one nonzero element per row. Exiting.') + 'must contain one nonzero element per row.') if this_idx.size > 0 and J[i,this_idx[0]] != 1: - raise Exception('J matrices can only contain 1s. Exiting.') + raise Exception('J matrices can only contain 1s.') idx[i] = this_idx[0] return idx @@ -342,7 +310,7 @@ def J_to_idx_slack(J): idx[i_idx] = i i_idx = i_idx + 1 elif len(this_idx) > 1: - raise Exception('J_to_idx_slack: Invalid J matrix. Exiting. ' \ + raise Exception('J_to_idx_slack: Invalid J matrix. ' \ 'Found more than one nonzero in row ' + str(i)) if this_idx.size > 0 and J[i,this_idx[0]] != 1: raise Exception('J_to_idx_slack: J matrices can only contain 1s, ' \ @@ -376,13 +344,13 @@ def acados_dae_model_json_dump(model): # dump json_file = model_name + '_acados_dae.json' with open(json_file, 'w') as f: - json.dump(dae_dict, f, default=np_array_to_list, indent=4, sort_keys=True) + json.dump(dae_dict, f, default=make_object_json_dumpable, indent=4, sort_keys=True) print("dumped ", model_name, " dae to file:", json_file, "\n") -def set_up_imported_gnsf_model(acados_formulation): +def set_up_imported_gnsf_model(acados_ocp): - gnsf = acados_formulation.gnsf_model + gnsf = acados_ocp.gnsf_model # check CasADi version # dump_casadi_version = gnsf['casadi_version'] @@ -402,39 +370,66 @@ def set_up_imported_gnsf_model(acados_formulation): # obtain gnsf dimensions size_gnsf_A = get_matrices_fun.size_out(0) - acados_formulation.dims.gnsf_nx1 = size_gnsf_A[1] - acados_formulation.dims.gnsf_nz1 = size_gnsf_A[0] - size_gnsf_A[1] - acados_formulation.dims.gnsf_nuhat = max(phi_fun.size_in(1)) - acados_formulation.dims.gnsf_ny = max(phi_fun.size_in(0)) - acados_formulation.dims.gnsf_nout = max(phi_fun.size_out(0)) + acados_ocp.dims.gnsf_nx1 = size_gnsf_A[1] + acados_ocp.dims.gnsf_nz1 = size_gnsf_A[0] - size_gnsf_A[1] + acados_ocp.dims.gnsf_nuhat = max(phi_fun.size_in(1)) + acados_ocp.dims.gnsf_ny = max(phi_fun.size_in(0)) + acados_ocp.dims.gnsf_nout = max(phi_fun.size_out(0)) # save gnsf functions in model - acados_formulation.model.phi_fun = phi_fun - acados_formulation.model.phi_fun_jac_y = phi_fun_jac_y - acados_formulation.model.phi_jac_y_uhat = phi_jac_y_uhat - acados_formulation.model.get_matrices_fun = get_matrices_fun + acados_ocp.model.phi_fun = phi_fun + acados_ocp.model.phi_fun_jac_y = phi_fun_jac_y + acados_ocp.model.phi_jac_y_uhat = phi_jac_y_uhat + acados_ocp.model.get_matrices_fun = get_matrices_fun # get_matrices_fun = Function([model_name,'_gnsf_get_matrices_fun'], {dummy},... # {A, B, C, E, L_x, L_xdot, L_z, L_u, A_LO, c, E_LO, B_LO,... # nontrivial_f_LO, purely_linear, ipiv_x, ipiv_z, c_LO}); get_matrices_out = get_matrices_fun(0) - acados_formulation.model.gnsf['nontrivial_f_LO'] = int(get_matrices_out[12]) - acados_formulation.model.gnsf['purely_linear'] = int(get_matrices_out[13]) + acados_ocp.model.gnsf['nontrivial_f_LO'] = int(get_matrices_out[12]) + acados_ocp.model.gnsf['purely_linear'] = int(get_matrices_out[13]) if "f_lo_fun_jac_x1k1uz" in gnsf: f_lo_fun_jac_x1k1uz = Function.deserialize(gnsf['f_lo_fun_jac_x1k1uz']) - acados_formulation.model.f_lo_fun_jac_x1k1uz = f_lo_fun_jac_x1k1uz + acados_ocp.model.f_lo_fun_jac_x1k1uz = f_lo_fun_jac_x1k1uz else: - dummy_var_x1 = SX.sym('dummy_var_x1', acados_formulation.dims.gnsf_nx1) - dummy_var_x1dot = SX.sym('dummy_var_x1dot', acados_formulation.dims.gnsf_nx1) - dummy_var_z1 = SX.sym('dummy_var_z1', acados_formulation.dims.gnsf_nz1) - dummy_var_u = SX.sym('dummy_var_z1', acados_formulation.dims.nu) - dummy_var_p = SX.sym('dummy_var_z1', acados_formulation.dims.np) + dummy_var_x1 = SX.sym('dummy_var_x1', acados_ocp.dims.gnsf_nx1) + dummy_var_x1dot = SX.sym('dummy_var_x1dot', acados_ocp.dims.gnsf_nx1) + dummy_var_z1 = SX.sym('dummy_var_z1', acados_ocp.dims.gnsf_nz1) + dummy_var_u = SX.sym('dummy_var_z1', acados_ocp.dims.nu) + dummy_var_p = SX.sym('dummy_var_z1', acados_ocp.dims.np) empty_var = SX.sym('empty_var', 0, 0) empty_fun = Function('empty_fun', \ [dummy_var_x1, dummy_var_x1dot, dummy_var_z1, dummy_var_u, dummy_var_p], [empty_var]) - acados_formulation.model.f_lo_fun_jac_x1k1uz = empty_fun + acados_ocp.model.f_lo_fun_jac_x1k1uz = empty_fun - del acados_formulation.gnsf_model + del acados_ocp.gnsf_model + + +def idx_perm_to_ipiv(idx_perm): + n = len(idx_perm) + vec = list(range(n)) + ipiv = np.zeros(n) + + print(n, idx_perm) + # import pdb; pdb.set_trace() + for ii in range(n): + idx0 = idx_perm[ii] + for jj in range(ii,n): + if vec[jj]==idx0: + idx1 = jj + break + tmp = vec[ii] + vec[ii] = vec[idx1] + vec[idx1] = tmp + ipiv[ii] = idx1 + + ipiv = ipiv-1 # C 0-based indexing + return ipiv + + +def print_casadi_expression(f): + for ii in range(casadi_length(f)): + print(f[ii,:]) diff --git a/third_party/acados/acados_template/zoro_description.py b/third_party/acados/acados_template/zoro_description.py new file mode 100644 index 0000000000..4d795c1502 --- /dev/null +++ b/third_party/acados/acados_template/zoro_description.py @@ -0,0 +1,78 @@ +# Copyright (c) The acados authors. +# +# This file is part of acados. +# +# The 2-Clause BSD License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE.; + +from dataclasses import dataclass, field +import numpy as np + + +@dataclass +class ZoroDescription: + """ + Zero-Order Robust Optimization scheme. + + For advanced users. + """ + backoff_scaling_gamma: float = 1.0 + fdbk_K_mat: np.ndarray = None + unc_jac_G_mat: np.ndarray = None # default: an identity matrix + P0_mat: np.ndarray = None + W_mat: np.ndarray = None + idx_lbx_t: list = field(default_factory=list) + idx_ubx_t: list = field(default_factory=list) + idx_lbx_e_t: list = field(default_factory=list) + idx_ubx_e_t: list = field(default_factory=list) + idx_lbu_t: list = field(default_factory=list) + idx_ubu_t: list = field(default_factory=list) + idx_lg_t: list = field(default_factory=list) + idx_ug_t: list = field(default_factory=list) + idx_lg_e_t: list = field(default_factory=list) + idx_ug_e_t: list = field(default_factory=list) + idx_lh_t: list = field(default_factory=list) + idx_uh_t: list = field(default_factory=list) + idx_lh_e_t: list = field(default_factory=list) + idx_uh_e_t: list = field(default_factory=list) + +def process_zoro_description(zoro_description: ZoroDescription): + zoro_description.nw, _ = zoro_description.W_mat.shape + if zoro_description.unc_jac_G_mat is None: + zoro_description.unc_jac_G_mat = np.eye(zoro_description.nw) + zoro_description.nlbx_t = len(zoro_description.idx_lbx_t) + zoro_description.nubx_t = len(zoro_description.idx_ubx_t) + zoro_description.nlbx_e_t = len(zoro_description.idx_lbx_e_t) + zoro_description.nubx_e_t = len(zoro_description.idx_ubx_e_t) + zoro_description.nlbu_t = len(zoro_description.idx_lbu_t) + zoro_description.nubu_t = len(zoro_description.idx_ubu_t) + zoro_description.nlg_t = len(zoro_description.idx_lg_t) + zoro_description.nug_t = len(zoro_description.idx_ug_t) + zoro_description.nlg_e_t = len(zoro_description.idx_lg_e_t) + zoro_description.nug_e_t = len(zoro_description.idx_ug_e_t) + zoro_description.nlh_t = len(zoro_description.idx_lh_t) + zoro_description.nuh_t = len(zoro_description.idx_uh_t) + zoro_description.nlh_e_t = len(zoro_description.idx_lh_e_t) + zoro_description.nuh_e_t = len(zoro_description.idx_uh_e_t) + return zoro_description.__dict__ diff --git a/third_party/acados/build.sh b/third_party/acados/build.sh index 574a577b4d..b45c167b16 100755 --- a/third_party/acados/build.sh +++ b/third_party/acados/build.sh @@ -23,8 +23,8 @@ if [ ! -d acados_repo/ ]; then fi cd acados_repo git fetch --all -git checkout 8ea8827fafb1b23b4c7da1c4cf650de1cbd73584 -git submodule update --recursive --init +git checkout 8af9b0ad180940ef611884574a0b27a43504311d # v0.2.2 +git submodule update --depth=1 --recursive --init # build mkdir -p build @@ -50,7 +50,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then cargo build --verbose --release --target aarch64-apple-darwin cargo build --verbose --release --target x86_64-apple-darwin lipo -create -output target/release/t_renderer target/x86_64-apple-darwin/release/t_renderer target/aarch64-apple-darwin/release/t_renderer -else +else cargo build --verbose --release fi cp target/release/t_renderer $INSTALL_DIR/ diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_common.h b/third_party/acados/include/acados/dense_qp/dense_qp_common.h index f3809c4294..2a9a974f99 100644 --- a/third_party/acados/include/acados/dense_qp/dense_qp_common.h +++ b/third_party/acados/include/acados/dense_qp/dense_qp_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_daqp.h b/third_party/acados/include/acados/dense_qp/dense_qp_daqp.h new file mode 100644 index 0000000000..b262089b4f --- /dev/null +++ b/third_party/acados/include/acados/dense_qp/dense_qp_daqp.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) The acados authors. + * + * This file is part of acados. + * + * The 2-Clause BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.; + */ + + +#ifndef ACADOS_DENSE_QP_DENSE_QP_DAQP_H_ +#define ACADOS_DENSE_QP_DENSE_QP_DAQP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// blasfeo +#include "blasfeo/include/blasfeo_common.h" + +// daqp +#include "daqp/include/types.h" + +// acados +#include "acados/dense_qp/dense_qp_common.h" +#include "acados/utils/types.h" + + +typedef struct dense_qp_daqp_opts_ +{ + DAQPSettings* daqp_opts; + int warm_start; +} dense_qp_daqp_opts; + + +typedef struct dense_qp_daqp_memory_ +{ + double* lb_tmp; + double* ub_tmp; + int* idxb; + int* idxv_to_idxb; + int* idxs; + int* idxdaqp_to_idxs; + + double* Zl; + double* Zu; + double* zl; + double* zu; + double* d_ls; + double* d_us; + + double time_qp_solver_call; + int iter; + DAQPWorkspace * daqp_work; + +} dense_qp_daqp_memory; + +// opts +acados_size_t dense_qp_daqp_opts_calculate_size(void *config, dense_qp_dims *dims); +// +void *dense_qp_daqp_opts_assign(void *config, dense_qp_dims *dims, void *raw_memory); +// +void dense_qp_daqp_opts_initialize_default(void *config, dense_qp_dims *dims, void *opts_); +// +void dense_qp_daqp_opts_update(void *config, dense_qp_dims *dims, void *opts_); +// +// memory +acados_size_t dense_qp_daqp_workspace_calculate_size(void *config, dense_qp_dims *dims, void *opts_); +// +void *dense_qp_daqp_workspace_assign(void *config, dense_qp_dims *dims, void *raw_memory); +// +acados_size_t dense_qp_daqp_memory_calculate_size(void *config, dense_qp_dims *dims, void *opts_); +// +void *dense_qp_daqp_memory_assign(void *config, dense_qp_dims *dims, void *opts_, void *raw_memory); +// +// functions +int dense_qp_daqp(void *config, dense_qp_in *qp_in, dense_qp_out *qp_out, void *opts_, void *memory_, void *work_); +// +void dense_qp_daqp_eval_sens(void *config_, void *qp_in, void *qp_out, void *opts_, void *mem_, void *work_); +// +void dense_qp_daqp_memory_reset(void *config_, void *qp_in, void *qp_out, void *opts_, void *mem_, void *work_); +// +void dense_qp_daqp_config_initialize_default(void *config_); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // ACADOS_DENSE_QP_DENSE_QP_DAQP_H_ diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_hpipm.h b/third_party/acados/include/acados/dense_qp/dense_qp_hpipm.h index 20eedc26a2..136279d666 100644 --- a/third_party/acados/include/acados/dense_qp/dense_qp_hpipm.h +++ b/third_party/acados/include/acados/dense_qp/dense_qp_hpipm.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_ooqp.h b/third_party/acados/include/acados/dense_qp/dense_qp_ooqp.h index 646f11f06f..d051cb15f7 100644 --- a/third_party/acados/include/acados/dense_qp/dense_qp_ooqp.h +++ b/third_party/acados/include/acados/dense_qp/dense_qp_ooqp.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_qore.h b/third_party/acados/include/acados/dense_qp/dense_qp_qore.h index 52606fac5d..392e472918 100644 --- a/third_party/acados/include/acados/dense_qp/dense_qp_qore.h +++ b/third_party/acados/include/acados/dense_qp/dense_qp_qore.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/dense_qp/dense_qp_qpoases.h b/third_party/acados/include/acados/dense_qp/dense_qp_qpoases.h index 9f0bb1af68..0e13d3ef64 100644 --- a/third_party/acados/include/acados/dense_qp/dense_qp_qpoases.h +++ b/third_party/acados/include/acados/dense_qp/dense_qp_qpoases.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_common.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_common.h index 60d835fc58..ba97db9768 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_common.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -419,6 +416,9 @@ void ocp_nlp_embed_initial_value(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp void ocp_nlp_update_variables_sqp(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_in *in, ocp_nlp_out *out, ocp_nlp_opts *opts, ocp_nlp_memory *mem, ocp_nlp_workspace *work, double alpha); // +int ocp_nlp_precompute_common(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_in *in, + ocp_nlp_out *out, ocp_nlp_opts *opts, ocp_nlp_memory *mem, ocp_nlp_workspace *work); +// double ocp_nlp_line_search(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_in *in, ocp_nlp_out *out, ocp_nlp_opts *opts, ocp_nlp_memory *mem, ocp_nlp_workspace *work, int check_early_termination); diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgh.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgh.h index 7f7a30faf3..9dbf16f6dc 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgh.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgh.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -82,9 +79,6 @@ acados_size_t ocp_nlp_constraints_bgh_dims_calculate_size(void *config); // void *ocp_nlp_constraints_bgh_dims_assign(void *config, void *raw_memory); // -void ocp_nlp_constraints_bgh_dims_initialize(void *config, void *dims, int nx, int nu, int nz, int nbx, - int nbu, int ng, int nh, int dummy0, int ns); -// void ocp_nlp_constraints_bgh_dims_get(void *config_, void *dims_, const char *field, int* value); // void ocp_nlp_constraints_bgh_dims_set(void *config_, void *dims_, @@ -116,6 +110,9 @@ void *ocp_nlp_constraints_bgh_model_assign(void *config, void *dims, void *raw_m int ocp_nlp_constraints_bgh_model_set(void *config_, void *dims_, void *model_, const char *field, void *value); +// +void ocp_nlp_constraints_bgh_model_get(void *config_, void *dims_, + void *model_, const char *field, void *value); /************************************************ diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgp.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgp.h index beeec78411..eb05edf7a6 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgp.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_bgp.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -63,7 +60,7 @@ typedef struct int nbu; int nbx; int ng; // number of general linear constraints - int nphi; // dimension of convex outer part + int nphi; // dimension of convex outer part int ns; // nsbu + nsbx + nsg + nsphi int nsbu; // number of softened input bounds int nsbx; // number of softened state bounds @@ -81,9 +78,6 @@ acados_size_t ocp_nlp_constraints_bgp_dims_calculate_size(void *config); // void *ocp_nlp_constraints_bgp_dims_assign(void *config, void *raw_memory); // -void ocp_nlp_constraints_bgp_dims_initialize(void *config, void *dims, int nx, int nu, int nz, - int nbx, int nbu, int ng, int nphi, int nq, int ns); -// void ocp_nlp_constraints_bgp_dims_get(void *config_, void *dims_, const char *field, int* value); @@ -109,6 +103,9 @@ void *ocp_nlp_constraints_bgp_assign(void *config, void *dims, void *raw_memory) // int ocp_nlp_constraints_bgp_model_set(void *config_, void *dims_, void *model_, const char *field, void *value); +// +void ocp_nlp_constraints_bgp_model_get(void *config_, void *dims_, + void *model_, const char *field, void *value); /* options */ diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_common.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_common.h index 7cadecab46..bb73c468de 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_common.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_constraints_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -60,11 +57,10 @@ typedef struct { acados_size_t (*dims_calculate_size)(void *config); void *(*dims_assign)(void *config, void *raw_memory); - void (*dims_initialize)(void *config, void *dims, int nx, int nu, int nz, int nbx, int nbu, int ng, - int nh, int nq, int ns); acados_size_t (*model_calculate_size)(void *config, void *dims); void *(*model_assign)(void *config, void *dims, void *raw_memory); int (*model_set)(void *config_, void *dims_, void *model_, const char *field, void *value); + void (*model_get)(void *config_, void *dims_, void *model_, const char *field, void *value); acados_size_t (*opts_calculate_size)(void *config, void *dims); void *(*opts_assign)(void *config, void *dims, void *raw_memory); void (*opts_initialize_default)(void *config, void *dims, void *opts); diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_common.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_common.h index c9fbbfb404..eb40564036 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_common.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -33,8 +30,8 @@ /// -/// \defgroup ocp_nlp_cost ocp_nlp_cost -/// +/// \defgroup ocp_nlp_cost ocp_nlp_cost +/// /// \addtogroup ocp_nlp_cost ocp_nlp_cost /// @{ @@ -62,7 +59,6 @@ typedef struct { acados_size_t (*dims_calculate_size)(void *config); void *(*dims_assign)(void *config, void *raw_memory); - void (*dims_initialize)(void *config, void *dims, int nx, int nu, int ny, int ns, int nz); void (*dims_set)(void *config_, void *dims_, const char *field, int *value); void (*dims_get)(void *config_, void *dims_, const char *field, int *value); acados_size_t (*model_calculate_size)(void *config, void *dims); @@ -91,6 +87,8 @@ typedef struct // computes the cost function value (intended for globalization) void (*compute_fun)(void *config_, void *dims, void *model_, void *opts_, void *mem_, void *work_); void (*config_initialize_default)(void *config); + void (*precompute)(void *config_, void *dims_, void *model_, void *opts_, void *memory_, void *work_); + } ocp_nlp_cost_config; // @@ -105,5 +103,5 @@ ocp_nlp_cost_config *ocp_nlp_cost_config_assign(void *raw_memory); #endif #endif // ACADOS_OCP_NLP_OCP_NLP_COST_COMMON_H_ -/// @} -/// @} +/// @} +/// @} diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_conl.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_conl.h new file mode 100644 index 0000000000..2eb3f5d127 --- /dev/null +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_conl.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) The acados authors. + * + * This file is part of acados. + * + * The 2-Clause BSD License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.; + */ + + +/// \addtogroup ocp_nlp +/// @{ +/// \addtogroup ocp_nlp_cost ocp_nlp_cost +/// @{ +/// \addtogroup ocp_nlp_cost_conl ocp_nlp_cost_conl +/// \brief This module implements convex-over-nonlinear costs of the form +/// \f$\min_{x,u,z} \psi(y(x,u,z,p) - y_{\text{ref}}, p)\f$, + + +#ifndef ACADOS_OCP_NLP_OCP_NLP_COST_CONL_H_ +#define ACADOS_OCP_NLP_OCP_NLP_COST_CONL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// blasfeo +#include "blasfeo/include/blasfeo_common.h" + +// acados +#include "acados/ocp_nlp/ocp_nlp_cost_common.h" +#include "acados/utils/external_function_generic.h" +#include "acados/utils/types.h" + + + +/************************************************ + * dims + ************************************************/ + +typedef struct +{ + int nx; // number of states + int nz; // number of algebraic variables + int nu; // number of inputs + int ny; // number of outputs + int ns; // number of slacks +} ocp_nlp_cost_conl_dims; + +// +acados_size_t ocp_nlp_cost_conl_dims_calculate_size(void *config); +// +void *ocp_nlp_cost_conl_dims_assign(void *config, void *raw_memory); +// +void ocp_nlp_cost_conl_dims_initialize(void *config, void *dims, int nx, int nu, int ny, int ns, int nz); +// +void ocp_nlp_cost_conl_dims_set(void *config_, void *dims_, const char *field, int* value); +// +void ocp_nlp_cost_conl_dims_get(void *config_, void *dims_, const char *field, int* value); + + + +/************************************************ + * model + ************************************************/ + +typedef struct +{ + // slack penalty has the form z^T * s + .5 * s^T * Z * s + external_function_generic *conl_cost_fun; + external_function_generic *conl_cost_fun_jac_hess; + struct blasfeo_dvec y_ref; + struct blasfeo_dvec Z; // diagonal Hessian of slacks as vector + struct blasfeo_dvec z; // gradient of slacks as vector + double scaling; +} ocp_nlp_cost_conl_model; + +// +acados_size_t ocp_nlp_cost_conl_model_calculate_size(void *config, void *dims); +// +void *ocp_nlp_cost_conl_model_assign(void *config, void *dims, void *raw_memory); +// +int ocp_nlp_cost_conl_model_set(void *config_, void *dims_, void *model_, const char *field, void *value_); + + + +/************************************************ + * options + ************************************************/ + +typedef struct +{ + bool gauss_newton_hess; // dummy options, we always use a gauss-newton hessian +} ocp_nlp_cost_conl_opts; + +// +acados_size_t ocp_nlp_cost_conl_opts_calculate_size(void *config, void *dims); +// +void *ocp_nlp_cost_conl_opts_assign(void *config, void *dims, void *raw_memory); +// +void ocp_nlp_cost_conl_opts_initialize_default(void *config, void *dims, void *opts); +// +void ocp_nlp_cost_conl_opts_update(void *config, void *dims, void *opts); +// +void ocp_nlp_cost_conl_opts_set(void *config, void *opts, const char *field, void *value); + + + +/************************************************ + * memory + ************************************************/ +typedef struct +{ + struct blasfeo_dvec grad; // gradient of cost function + struct blasfeo_dvec *ux; // pointer to ux in nlp_out + struct blasfeo_dvec *tmp_ux; // pointer to ux in tmp_nlp_out + struct blasfeo_dmat *RSQrq; // pointer to RSQrq in qp_in + struct blasfeo_dvec *Z; // pointer to Z in qp_in + struct blasfeo_dvec *z_alg; ///< pointer to z in sim_out + struct blasfeo_dmat *dzdux_tran; ///< pointer to sensitivity of a wrt ux in sim_out + double fun; ///< value of the cost function +} ocp_nlp_cost_conl_memory; + +// +acados_size_t ocp_nlp_cost_conl_memory_calculate_size(void *config, void *dims, void *opts); +// +void *ocp_nlp_cost_conl_memory_assign(void *config, void *dims, void *opts, void *raw_memory); +// +double *ocp_nlp_cost_conl_memory_get_fun_ptr(void *memory_); +// +struct blasfeo_dvec *ocp_nlp_cost_conl_memory_get_grad_ptr(void *memory_); +// +void ocp_nlp_cost_conl_memory_set_RSQrq_ptr(struct blasfeo_dmat *RSQrq, void *memory); +// +void ocp_nlp_cost_conl_memory_set_Z_ptr(struct blasfeo_dvec *Z, void *memory); +// +void ocp_nlp_cost_conl_memory_set_ux_ptr(struct blasfeo_dvec *ux, void *memory_); +// +void ocp_nlp_cost_conl_memory_set_tmp_ux_ptr(struct blasfeo_dvec *tmp_ux, void *memory_); +// +void ocp_nlp_cost_conl_memory_set_z_alg_ptr(struct blasfeo_dvec *z_alg, void *memory_); +// +void ocp_nlp_cost_conl_memory_set_dzdux_tran_ptr(struct blasfeo_dmat *dzdux_tran, void *memory_); + +/************************************************ + * workspace + ************************************************/ + +typedef struct +{ + struct blasfeo_dmat W; // hessian of outer loss function + struct blasfeo_dmat W_chol; // cholesky factor of hessian of outer loss function + struct blasfeo_dmat Jt_ux; // jacobian of inner residual function + struct blasfeo_dmat Jt_ux_tilde; // jacobian of inner residual function plus gradient contribution of algebraic variables + struct blasfeo_dmat Jt_z; // jacobian of inner residual function wrt algebraic variables + struct blasfeo_dmat tmp_nv_ny; + struct blasfeo_dvec tmp_ny; + struct blasfeo_dvec tmp_2ns; +} ocp_nlp_cost_conl_workspace; + +// +acados_size_t ocp_nlp_cost_conl_workspace_calculate_size(void *config, void *dims, void *opts); + +/************************************************ + * functions + ************************************************/ + +// +void ocp_nlp_cost_conl_precompute(void *config_, void *dims_, void *model_, void *opts_, void *memory_, void *work_); +// +void ocp_nlp_cost_conl_config_initialize_default(void *config); +// +void ocp_nlp_cost_conl_initialize(void *config_, void *dims, void *model_, void *opts_, void *mem_, void *work_); +// +void ocp_nlp_cost_conl_update_qp_matrices(void *config_, void *dims, void *model_, void *opts_, void *memory_, void *work_); +// +void ocp_nlp_cost_conl_compute_fun(void *config_, void *dims, void *model_, void *opts_, void *memory_, void *work_); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // ACADOS_OCP_NLP_OCP_NLP_COST_CONL_H_ +/// @} +/// @} +/// @} diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_external.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_external.h index f2196dbee7..78958270de 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_external.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_external.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -54,6 +51,7 @@ extern "C" { typedef struct { int nx; // number of states + int nz; // number of algebraic variables int nu; // number of inputs int ns; // number of slacks } ocp_nlp_cost_external_dims; @@ -63,9 +61,6 @@ acados_size_t ocp_nlp_cost_external_dims_calculate_size(void *config); // void *ocp_nlp_cost_external_dims_assign(void *config, void *raw_memory); // -void ocp_nlp_cost_external_dims_initialize(void *config, void *dims, int nx, - int nu, int ny, int ns, int nz); -// void ocp_nlp_cost_external_dims_set(void *config_, void *dims_, const char *field, int* value); // void ocp_nlp_cost_external_dims_get(void *config_, void *dims_, const char *field, int* value); @@ -122,7 +117,7 @@ typedef struct { struct blasfeo_dvec grad; // gradient of cost function struct blasfeo_dvec *ux; // pointer to ux in nlp_out - struct blasfeo_dvec *tmp_ux; // pointer to tmp_ux in nlp_out + struct blasfeo_dvec *tmp_ux; // pointer to tmp_ux in nlp_out struct blasfeo_dmat *RSQrq; // pointer to RSQrq in qp_in struct blasfeo_dvec *Z; // pointer to Z in qp_in struct blasfeo_dvec *z_alg; ///< pointer to z in sim_out @@ -157,7 +152,10 @@ void ocp_nlp_cost_external_memory_set_dzdux_tran_ptr(struct blasfeo_dmat *dzdux_ typedef struct { - struct blasfeo_dmat tmp_nv_nv; + struct blasfeo_dmat tmp_nunx_nunx; + struct blasfeo_dmat tmp_nz_nz; + struct blasfeo_dmat tmp_nz_nunx; + struct blasfeo_dvec tmp_nunxnz; struct blasfeo_dvec tmp_2ns; // temporary vector of dimension 2*ns } ocp_nlp_cost_external_workspace; @@ -168,6 +166,8 @@ acados_size_t ocp_nlp_cost_external_workspace_calculate_size(void *config, void * functions ************************************************/ +// +void ocp_nlp_cost_external_precompute(void *config_, void *dims_, void *model_, void *opts_, void *memory_, void *work_); // void ocp_nlp_cost_external_config_initialize_default(void *config); // diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_ls.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_ls.h index 3cf759504a..801e9a5b87 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_ls.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_ls.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -82,30 +79,14 @@ typedef struct acados_size_t ocp_nlp_cost_ls_dims_calculate_size(void *config); -/// Assign memory pointed to by raw_memory to ocp_nlp-cost_ls dims struct +/// Assign memory pointed to by raw_memory to ocp_nlp-cost_ls dims struct /// -/// \param[in] config structure containing configuration of ocp_nlp_cost +/// \param[in] config structure containing configuration of ocp_nlp_cost /// module -/// \param[in] raw_memory pointer to memory location +/// \param[in] raw_memory pointer to memory location /// \param[out] [] /// \return dims void *ocp_nlp_cost_ls_dims_assign(void *config, void *raw_memory); - - -/// Initialize the dimensions struct of the -/// ocp_nlp-cost_ls component -/// -/// \param[in] config structure containing configuration ocp_nlp-cost_ls component -/// \param[in] nx number of states -/// \param[in] nu number of inputs -/// \param[in] ny number of residuals -/// \param[in] ns number of slacks -/// \param[in] nz number of algebraic variables -/// \param[out] dims -/// \return size -void ocp_nlp_cost_ls_dims_initialize(void *config, void *dims, int nx, - int nu, int ny, int ns, int nz); - // void ocp_nlp_cost_ls_dims_set(void *config_, void *dims_, const char *field, int* value); // @@ -117,7 +98,7 @@ void ocp_nlp_cost_ls_dims_get(void *config_, void *dims_, const char *field, int //////////////////////////////////////////////////////////////////////////////// -/// structure containing the data describing the linear least-square cost +/// structure containing the data describing the linear least-square cost typedef struct { // slack penalty has the form z^T * s + .5 * s^T * Z * s @@ -128,6 +109,8 @@ typedef struct struct blasfeo_dvec Z; ///< diagonal Hessian of slacks as vector (lower and upper) struct blasfeo_dvec z; ///< gradient of slacks as vector (lower and upper) double scaling; + int W_changed; ///< flag indicating whether W has changed and needs to be refactorized + int Cyt_or_scaling_changed; ///< flag indicating whether Cyt or scaling has changed and Hessian needs to be recomputed } ocp_nlp_cost_ls_model; // @@ -170,7 +153,7 @@ void ocp_nlp_cost_ls_opts_set(void *config, void *opts, const char *field, void -/// structure containing the memory associated with cost_ls component +/// structure containing the memory associated with cost_ls component /// of the ocp_nlp module typedef struct { @@ -237,7 +220,8 @@ acados_size_t ocp_nlp_cost_ls_workspace_calculate_size(void *config, void *dims, //////////////////////////////////////////////////////////////////////////////// - +// computations that are done once when solver is created +void ocp_nlp_cost_ls_precompute(void *config_, void *dims_, void *model_, void *opts_, void *memory_, void *work_); // void ocp_nlp_cost_ls_config_initialize_default(void *config); // diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_nls.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_nls.h index aafb6b3540..5ec68cf580 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_nls.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_cost_nls.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -38,8 +35,7 @@ /// @{ /// \addtogroup ocp_nlp_cost_nls ocp_nlp_cost_nls /// \brief This module implements nonlinear-least squares costs of the form -/// \f$\min_{x,u} \| r(x,u) - y_{\text{ref}} \|_W^2\f$. -/// @{ +/// \f$\min_{x,u,z} \| y(x,u,z,p) - y_{\text{ref}} \|_W^2\f$, #ifndef ACADOS_OCP_NLP_OCP_NLP_COST_NLS_H_ #define ACADOS_OCP_NLP_OCP_NLP_COST_NLS_H_ @@ -65,6 +61,7 @@ extern "C" { typedef struct { int nx; // number of states + int nz; // number of algebraic variables int nu; // number of inputs int ny; // number of outputs int ns; // number of slacks @@ -75,8 +72,6 @@ acados_size_t ocp_nlp_cost_nls_dims_calculate_size(void *config); // void *ocp_nlp_cost_nls_dims_assign(void *config, void *raw_memory); // -void ocp_nlp_cost_nls_dims_initialize(void *config, void *dims, int nx, int nu, int ny, int ns, int nz); -// void ocp_nlp_cost_nls_dims_set(void *config_, void *dims_, const char *field, int* value); // void ocp_nlp_cost_nls_dims_get(void *config_, void *dims_, const char *field, int* value); @@ -99,6 +94,7 @@ typedef struct struct blasfeo_dvec Z; // diagonal Hessian of slacks as vector struct blasfeo_dvec z; // gradient of slacks as vector double scaling; + int W_changed; ///< flag indicating whether W has changed and needs to be refactorized } ocp_nlp_cost_nls_model; // @@ -144,11 +140,11 @@ typedef struct struct blasfeo_dvec grad; // gradient of cost function struct blasfeo_dvec *ux; // pointer to ux in nlp_out struct blasfeo_dvec *tmp_ux; // pointer to ux in tmp_nlp_out - struct blasfeo_dvec *z_alg; ///< pointer to z in sim_out - struct blasfeo_dmat *dzdux_tran; ///< pointer to sensitivity of a wrt ux in sim_out struct blasfeo_dmat *RSQrq; // pointer to RSQrq in qp_in struct blasfeo_dvec *Z; // pointer to Z in qp_in - double fun; ///< value of the cost function + struct blasfeo_dvec *z_alg; ///< pointer to z in sim_out + struct blasfeo_dmat *dzdux_tran; ///< pointer to sensitivity of a wrt ux in sim_out + double fun; ///< value of the cost function } ocp_nlp_cost_nls_memory; // @@ -180,8 +176,11 @@ typedef struct { struct blasfeo_dmat tmp_nv_ny; struct blasfeo_dmat tmp_nv_nv; + struct blasfeo_dmat Vz; + struct blasfeo_dmat Cyt_tilde; struct blasfeo_dvec tmp_ny; - struct blasfeo_dvec tmp_2ns; // temporary vector of dimension ny + struct blasfeo_dvec tmp_2ns; + struct blasfeo_dvec tmp_nz; } ocp_nlp_cost_nls_workspace; // @@ -191,6 +190,8 @@ acados_size_t ocp_nlp_cost_nls_workspace_calculate_size(void *config, void *dims * functions ************************************************/ +// +void ocp_nlp_cost_nls_precompute(void *config_, void *dims_, void *model_, void *opts_, void *memory_, void *work_); // void ocp_nlp_cost_nls_config_initialize_default(void *config); // diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_common.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_common.h index f2128a8574..43fe71b12f 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_common.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -68,7 +65,6 @@ typedef struct /* dims */ acados_size_t (*dims_calculate_size)(void *config); void *(*dims_assign)(void *config, void *raw_memory); - void (*dims_initialize)(void *config, void *dims, int nx, int nu, int nx1, int nu1, int nz); void (*dims_set)(void *config_, void *dims_, const char *field, int *value); void (*dims_get)(void *config_, void *dims_, const char *field, int* value); /* model */ diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_cont.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_cont.h index 59a2df4f47..3afdc9f4ed 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_cont.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_cont.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -75,10 +72,6 @@ typedef struct acados_size_t ocp_nlp_dynamics_cont_dims_calculate_size(void *config); // void *ocp_nlp_dynamics_cont_dims_assign(void *config, void *raw_memory); -// -void ocp_nlp_dynamics_cont_dims_initialize(void *config, void *dims, int nx, int nu, int nx1, - int nu1, int nz); - // void ocp_nlp_dynamics_cont_dims_set(void *config_, void *dims_, const char *field, int* value); diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_disc.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_disc.h index 8b2a6177bf..6ea26a7010 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_disc.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_dynamics_disc.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -68,10 +65,6 @@ typedef struct acados_size_t ocp_nlp_dynamics_disc_dims_calculate_size(void *config); // void *ocp_nlp_dynamics_disc_dims_assign(void *config, void *raw_memory); -// -void ocp_nlp_dynamics_disc_dims_initialize(void *config, void *dims, int nx, int nu, int nx1, - int nu1, int nz); - // void ocp_nlp_dynamics_disc_dims_set(void *config_, void *dims_, const char *dim, int* value); diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_common.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_common.h index cd26788a56..9388f3fd24 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_common.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_convexify.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_convexify.h index df31361680..cb523525e1 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_convexify.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_convexify.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_mirror.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_mirror.h index f6bd7dcafd..84a023cb69 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_mirror.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_mirror.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_noreg.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_noreg.h index c085e00d5d..b571f3bac1 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_noreg.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_noreg.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project.h index 104c297207..682ea206dc 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project_reduc_hess.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project_reduc_hess.h index e0b854bc1a..7e12952c15 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project_reduc_hess.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_reg_project_reduc_hess.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp.h index 74cfb042e3..fdb96417f9 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp_rti.h b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp_rti.h index af22c06a17..364d0f4717 100644 --- a/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp_rti.h +++ b/third_party/acados/include/acados/ocp_nlp/ocp_nlp_sqp_rti.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -145,12 +142,6 @@ acados_size_t ocp_nlp_sqp_rti_workspace_calculate_size(void *config_, void *dims /************************************************ * functions ************************************************/ - -void ocp_nlp_sqp_rti_preparation_step(void *config_, void *dims_, - void *nlp_in_, void *nlp_out_, void *opts, void *mem_, void *work_); -// -void ocp_nlp_sqp_rti_feedback_step(void *config_, void *dims_, - void *nlp_in_, void *nlp_out_, void *opts_, void *mem_, void *work_); // int ocp_nlp_sqp_rti(void *config_, void *dims_, void *nlp_in_, void *nlp_out_, void *opts_, void *mem_, void *work_); diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_common.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_common.h index caf6caf2f0..d1a45635e4 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_common.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_common_frontend.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_common_frontend.h index 50b80850c6..f65f602c15 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_common_frontend.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_common_frontend.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_full_condensing.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_full_condensing.h index 14ac97bbf4..d23e658b48 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_full_condensing.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_full_condensing.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_hpipm.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_hpipm.h index 91690e458d..261606b842 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_hpipm.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_hpipm.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_hpmpc.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_hpmpc.h index de6ce501b1..8db53a279d 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_hpmpc.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_hpmpc.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_ooqp.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_ooqp.h index 1a3b7b2fa2..a535503f21 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_ooqp.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_ooqp.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_osqp.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_osqp.h index 4ae391a9ff..51df1b1cd6 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_osqp.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_osqp.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_partial_condensing.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_partial_condensing.h index b95a11114e..844f6048fe 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_partial_condensing.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_partial_condensing.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_qpdunes.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_qpdunes.h index ad4d094516..3b875caeb5 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_qpdunes.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_qpdunes.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/ocp_qp/ocp_qp_xcond_solver.h b/third_party/acados/include/acados/ocp_qp/ocp_qp_xcond_solver.h index d4b30e007b..a78bc65bb9 100644 --- a/third_party/acados/include/acados/ocp_qp/ocp_qp_xcond_solver.h +++ b/third_party/acados/include/acados/ocp_qp/ocp_qp_xcond_solver.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -84,6 +81,7 @@ typedef struct acados_size_t (*dims_calculate_size)(void *config, int N); ocp_qp_xcond_solver_dims *(*dims_assign)(void *config, int N, void *raw_memory); void (*dims_set)(void *config_, ocp_qp_xcond_solver_dims *dims, int stage, const char *field, int* value); + void (*dims_get)(void *config_, ocp_qp_xcond_solver_dims *dims, int stage, const char *field, int* value); acados_size_t (*opts_calculate_size)(void *config, ocp_qp_xcond_solver_dims *dims); void *(*opts_assign)(void *config, ocp_qp_xcond_solver_dims *dims, void *raw_memory); void (*opts_initialize_default)(void *config, ocp_qp_xcond_solver_dims *dims, void *opts); diff --git a/third_party/acados/include/acados/sim/sim_collocation_utils.h b/third_party/acados/include/acados/sim/sim_collocation_utils.h index 40a0b1c0cc..045d165cbc 100644 --- a/third_party/acados/include/acados/sim/sim_collocation_utils.h +++ b/third_party/acados/include/acados/sim/sim_collocation_utils.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/sim/sim_common.h b/third_party/acados/include/acados/sim/sim_common.h index 1838d76f81..c4bbd6ed2b 100644 --- a/third_party/acados/include/acados/sim/sim_common.h +++ b/third_party/acados/include/acados/sim/sim_common.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -149,6 +146,8 @@ typedef struct bool jac_reuse; // Newton_scheme *scheme; + double newton_tol; // optinally used in implicit integrators + // workspace void *work; diff --git a/third_party/acados/include/acados/sim/sim_erk_integrator.h b/third_party/acados/include/acados/sim/sim_erk_integrator.h index 24a00c7077..fd46cb4d99 100644 --- a/third_party/acados/include/acados/sim/sim_erk_integrator.h +++ b/third_party/acados/include/acados/sim/sim_erk_integrator.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/sim/sim_gnsf.h b/third_party/acados/include/acados/sim/sim_gnsf.h index 5524b384e0..404532a732 100644 --- a/third_party/acados/include/acados/sim/sim_gnsf.h +++ b/third_party/acados/include/acados/sim/sim_gnsf.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -46,12 +43,12 @@ extern "C" { #include "acados/sim/sim_common.h" #include "blasfeo/include/blasfeo_common.h" -#include "blasfeo/include/blasfeo_d_aux.h" -#include "blasfeo/include/blasfeo_d_aux_ext_dep.h" -#include "blasfeo/include/blasfeo_d_blas.h" -#include "blasfeo/include/blasfeo_d_kernel.h" -#include "blasfeo/include/blasfeo_i_aux_ext_dep.h" -#include "blasfeo/include/blasfeo_target.h" +// #include "blasfeo/include/blasfeo_d_aux.h" +// #include "blasfeo/include/blasfeo_d_aux_ext_dep.h" +// #include "blasfeo/include/blasfeo_d_blas.h" +// #include "blasfeo/include/blasfeo_d_kernel.h" +// #include "blasfeo/include/blasfeo_i_aux_ext_dep.h" +// #include "blasfeo/include/blasfeo_target.h" /* GNSF - Generalized Nonlinear Static Feedback Model diff --git a/third_party/acados/include/acados/sim/sim_irk_integrator.h b/third_party/acados/include/acados/sim/sim_irk_integrator.h index 6851bacb3a..5090aa0bb5 100644 --- a/third_party/acados/include/acados/sim/sim_irk_integrator.h +++ b/third_party/acados/include/acados/sim/sim_irk_integrator.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/sim/sim_lifted_irk_integrator.h b/third_party/acados/include/acados/sim/sim_lifted_irk_integrator.h index 9ec2d97bed..e60bb80ebf 100644 --- a/third_party/acados/include/acados/sim/sim_lifted_irk_integrator.h +++ b/third_party/acados/include/acados/sim/sim_lifted_irk_integrator.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/utils/external_function_generic.h b/third_party/acados/include/acados/utils/external_function_generic.h index 021363f26e..1e68dc155d 100644 --- a/third_party/acados/include/acados/utils/external_function_generic.h +++ b/third_party/acados/include/acados/utils/external_function_generic.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -137,8 +134,8 @@ typedef struct int (*casadi_work)(int *, int *, int *, int *); const int *(*casadi_sparsity_in)(int); const int *(*casadi_sparsity_out)(int); - int (*casadi_n_in)(); - int (*casadi_n_out)(); + int (*casadi_n_in)(void); + int (*casadi_n_out)(void); double **args; double **res; double *w; @@ -195,8 +192,8 @@ typedef struct int (*casadi_work)(int *, int *, int *, int *); const int *(*casadi_sparsity_in)(int); const int *(*casadi_sparsity_out)(int); - int (*casadi_n_in)(); - int (*casadi_n_out)(); + int (*casadi_n_in)(void); + int (*casadi_n_out)(void); double **args; double **res; double *w; diff --git a/third_party/acados/include/acados/utils/math.h b/third_party/acados/include/acados/utils/math.h index fe1da875f6..7156a82084 100644 --- a/third_party/acados/include/acados/utils/math.h +++ b/third_party/acados/include/acados/utils/math.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -42,6 +39,7 @@ extern "C" { #if defined(__MABX2__) double fmax(double a, double b); +int isnan(double x); #endif #define MIN(a,b) (((a)<(b))?(a):(b)) diff --git a/third_party/acados/include/acados/utils/mem.h b/third_party/acados/include/acados/utils/mem.h index 7b9efc5ed8..681a371e36 100644 --- a/third_party/acados/include/acados/utils/mem.h +++ b/third_party/acados/include/acados/utils/mem.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/utils/print.h b/third_party/acados/include/acados/utils/print.h index f8568afb26..824d3cee22 100644 --- a/third_party/acados/include/acados/utils/print.h +++ b/third_party/acados/include/acados/utils/print.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/utils/strsep.h b/third_party/acados/include/acados/utils/strsep.h index 02f1835593..62bdfb4891 100644 --- a/third_party/acados/include/acados/utils/strsep.h +++ b/third_party/acados/include/acados/utils/strsep.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/utils/timing.h b/third_party/acados/include/acados/utils/timing.h index fe561d3891..b0955932da 100644 --- a/third_party/acados/include/acados/utils/timing.h +++ b/third_party/acados/include/acados/utils/timing.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados/utils/types.h b/third_party/acados/include/acados/utils/types.h index d3da0a86b7..a27ef9e552 100644 --- a/third_party/acados/include/acados/utils/types.h +++ b/third_party/acados/include/acados/utils/types.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -78,7 +75,7 @@ typedef int (*casadi_function_t)(const double** arg, double** res, int* iw, doub enum return_values { ACADOS_SUCCESS, - ACADOS_FAILURE, + ACADOS_NAN_DETECTED, ACADOS_MAXITER, ACADOS_MINSTEP, ACADOS_QP_FAILURE, diff --git a/third_party/acados/include/acados_c/condensing_interface.h b/third_party/acados/include/acados_c/condensing_interface.h index 51fe827127..b4302078d6 100644 --- a/third_party/acados/include/acados_c/condensing_interface.h +++ b/third_party/acados/include/acados_c/condensing_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados_c/dense_qp_interface.h b/third_party/acados/include/acados_c/dense_qp_interface.h index 4ecc77381d..b3af4bf682 100644 --- a/third_party/acados/include/acados_c/dense_qp_interface.h +++ b/third_party/acados/include/acados_c/dense_qp_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -41,7 +38,7 @@ extern "C" { #include "acados/dense_qp/dense_qp_common.h" -typedef enum { DENSE_QP_HPIPM, DENSE_QP_QORE, DENSE_QP_QPOASES, DENSE_QP_OOQP } dense_qp_solver_t; +typedef enum { DENSE_QP_HPIPM, DENSE_QP_QORE, DENSE_QP_QPOASES, DENSE_QP_OOQP, DENSE_QP_DAQP } dense_qp_solver_t; typedef struct { diff --git a/third_party/acados/include/acados_c/external_function_interface.h b/third_party/acados/include/acados_c/external_function_interface.h index 6838975071..d4f52db850 100644 --- a/third_party/acados/include/acados_c/external_function_interface.h +++ b/third_party/acados/include/acados_c/external_function_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/acados_c/ocp_nlp_interface.h b/third_party/acados/include/acados_c/ocp_nlp_interface.h index 50bc0cf1af..dd3e596f8b 100644 --- a/third_party/acados/include/acados_c/ocp_nlp_interface.h +++ b/third_party/acados/include/acados_c/ocp_nlp_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -66,6 +63,7 @@ typedef enum { LINEAR_LS, NONLINEAR_LS, + CONVEX_OVER_NONLINEAR, EXTERNAL, INVALID_COST, } ocp_nlp_cost_t; @@ -246,6 +244,10 @@ ACADOS_SYMBOL_EXPORT int ocp_nlp_cost_model_set(ocp_nlp_config *config, ocp_nlp_ ACADOS_SYMBOL_EXPORT int ocp_nlp_constraints_model_set(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_in *in, int stage, const char *field, void *value); +/// +ACADOS_SYMBOL_EXPORT void ocp_nlp_constraints_model_get(ocp_nlp_config *config, ocp_nlp_dims *dims, + ocp_nlp_in *in, int stage, const char *field, void *value); + /* out */ /// Constructs an output struct for the non-linear program. @@ -297,7 +299,7 @@ ACADOS_SYMBOL_EXPORT void ocp_nlp_constraint_dims_get_from_attr(ocp_nlp_config * ACADOS_SYMBOL_EXPORT void ocp_nlp_cost_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, int stage, const char *field, int *dims_out); -void ocp_nlp_dynamics_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, +ACADOS_SYMBOL_EXPORT void ocp_nlp_qp_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out, int stage, const char *field, int *dims_out); /* opts */ @@ -386,8 +388,6 @@ ACADOS_SYMBOL_EXPORT int ocp_nlp_precompute(ocp_nlp_solver *solver, ocp_nlp_in * /// \param nlp_out The output struct. ACADOS_SYMBOL_EXPORT void ocp_nlp_eval_cost(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in, ocp_nlp_out *nlp_out); -// -void ocp_nlp_eval_residuals(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in, ocp_nlp_out *nlp_out); /// Computes the residuals. /// diff --git a/third_party/acados/include/acados_c/ocp_qp_interface.h b/third_party/acados/include/acados_c/ocp_qp_interface.h index 2582f142da..3dc3f1a532 100644 --- a/third_party/acados/include/acados_c/ocp_qp_interface.h +++ b/third_party/acados/include/acados_c/ocp_qp_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * @@ -87,6 +84,11 @@ typedef enum { #else FULL_CONDENSING_QPOASES_NOT_AVAILABLE, #endif +#ifdef ACADOS_WITH_DAQP + FULL_CONDENSING_DAQP, +#else + FULL_CONDENSING_DAQP_NOT_AVAILABLE, +#endif #ifdef ACADOS_WITH_QORE FULL_CONDENSING_QORE, #else diff --git a/third_party/acados/include/acados_c/sim_interface.h b/third_party/acados/include/acados_c/sim_interface.h index 5dce6f153a..09a05d6995 100644 --- a/third_party/acados/include/acados_c/sim_interface.h +++ b/third_party/acados/include/acados_c/sim_interface.h @@ -1,8 +1,5 @@ /* - * Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren, - * Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor, - * Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan, - * Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl + * Copyright (c) The acados authors. * * This file is part of acados. * diff --git a/third_party/acados/include/blasfeo/include/blasfeo_d_blas_api.h b/third_party/acados/include/blasfeo/include/blasfeo_d_blas_api.h index ff9e9d4c16..2eab1e4094 100644 --- a/third_party/acados/include/blasfeo/include/blasfeo_d_blas_api.h +++ b/third_party/acados/include/blasfeo/include/blasfeo_d_blas_api.h @@ -50,18 +50,20 @@ #define BLASFEO_CBLAS_ENUM #ifdef FORTRAN_BLAS_API #ifndef CBLAS_H -enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102}; +enum CBLAS_LAYOUT {CblasRowMajor=101, CblasColMajor=102}; enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113}; enum CBLAS_UPLO {CblasUpper=121, CblasLower=122}; enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132}; enum CBLAS_SIDE {CblasLeft=141, CblasRight=142}; +#define CBLAS_ORDER CBLAS_LAYOUT /* this for backward compatibility with CBLAS_ORDER */ #endif // CBLAS_H #else // FORTRAN_BLAS_API -enum BLASFEO_CBLAS_ORDER {BlasfeoCblasRowMajor=101, BlasfeoCblasColMajor=102}; +enum BLASFEO_CBLAS_LAYOUT {BlasfeoCblasRowMajor=101, BlasfeoCblasColMajor=102}; enum BLASFEO_CBLAS_TRANSPOSE {BlasfeoCblasNoTrans=111, BlasfeoCblasTrans=112, BlasfeoCblasConjTrans=113}; enum BLASFEO_CBLAS_UPLO {BlasfeoCblasUpper=121, BlasfeoCblasLower=122}; enum BLASFEO_CBLAS_DIAG {BlasfeoCblasNonUnit=131, BlasfeoCblasUnit=132}; enum BLASFEO_CBLAS_SIDE {BlasfeoCblasLeft=141, BlasfeoCblasRight=142}; +#define BLASFEO_CBLAS_ORDER BLASFEO_CBLAS_LAYOUT /* this for backward compatibility with BLASFEO_CBLAS_ORDER */ #endif // FORTRAN_BLAS_API #endif // BLASFEO_CBLAS_ENUM #endif // CBLAS_API @@ -151,15 +153,19 @@ void cblas_dswap(const int N, double *X, const int incX, double *Y, const int in // void cblas_dcopy(const int N, const double *X, const int incX, double *Y, const int incY); +// CBLAS 2 +// +void cblas_dgemv(const enum CBLAS_LAYOUT layout, const enum CBLAS_TRANSPOSE TransA, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); + // CBLAS 3 // -void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); +void cblas_dgemm(const enum CBLAS_LAYOUT layout, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); // -void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); +void cblas_dsyrk(const enum CBLAS_LAYOUT layout, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); // -void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); +void cblas_dtrmm(const enum CBLAS_LAYOUT layout, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); // -void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); +void cblas_dtrsm(const enum CBLAS_LAYOUT layout, const enum CBLAS_SIDE Side, const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); @@ -240,15 +246,19 @@ void blasfeo_cblas_dswap(const int N, double *X, const int incX, double *Y, cons // void blasfeo_cblas_dcopy(const int N, const double *X, const int incX, double *Y, const int incY); +// CBLAS 2 +// +void blasfeo_cblas_dgemv(const enum BLASFEO_CBLAS_LAYOUT layout, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const int M, const int N, const double alpha, const double *A, const int lda, const double *X, const int incX, const double beta, double *Y, const int incY); + // CBLAS 3 // -void blasfeo_cblas_dgemm(const enum BLASFEO_CBLAS_ORDER Order, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); +void blasfeo_cblas_dgemm(const enum BLASFEO_CBLAS_LAYOUT layout, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const double alpha, const double *A, const int lda, const double *B, const int ldb, const double beta, double *C, const int ldc); // -void blasfeo_cblas_dsyrk(const enum BLASFEO_CBLAS_ORDER Order, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); +void blasfeo_cblas_dsyrk(const enum BLASFEO_CBLAS_LAYOUT layout, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE Trans, const int N, const int K, const double alpha, const double *A, const int lda, const double beta, double *C, const int ldc); // -void blasfeo_cblas_dtrmm(const enum BLASFEO_CBLAS_ORDER Order, const enum BLASFEO_CBLAS_SIDE Side, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); +void blasfeo_cblas_dtrmm(const enum BLASFEO_CBLAS_LAYOUT layout, const enum BLASFEO_CBLAS_SIDE Side, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); // -void blasfeo_cblas_dtrsm(const enum BLASFEO_CBLAS_ORDER Order, const enum BLASFEO_CBLAS_SIDE Side, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); +void blasfeo_cblas_dtrsm(const enum BLASFEO_CBLAS_LAYOUT layout, const enum BLASFEO_CBLAS_SIDE Side, const enum BLASFEO_CBLAS_UPLO Uplo, const enum BLASFEO_CBLAS_TRANSPOSE TransA, const enum BLASFEO_CBLAS_DIAG Diag, const int M, const int N, const double alpha, const double *A, const int lda, double *B, const int ldb); diff --git a/third_party/acados/include/blasfeo/include/blasfeo_target.h b/third_party/acados/include/blasfeo/include/blasfeo_target.h index 4ff4f307b3..51f617a649 100644 --- a/third_party/acados/include/blasfeo/include/blasfeo_target.h +++ b/third_party/acados/include/blasfeo/include/blasfeo_target.h @@ -1,13 +1,13 @@ -#ifndef TARGET_ARMV8A_ARM_CORTEX_A57 -#define TARGET_ARMV8A_ARM_CORTEX_A57 +#ifndef TARGET_X64_INTEL_HASWELL +#define TARGET_X64_INTEL_HASWELL #endif #ifndef TARGET_NEED_FEATURE_AVX2 -/* #undef TARGET_NEED_FEATURE_AVX2 */ +#define TARGET_NEED_FEATURE_AVX2 1 #endif #ifndef TARGET_NEED_FEATURE_FMA -/* #undef TARGET_NEED_FEATURE_FMA */ +#define TARGET_NEED_FEATURE_FMA 1 #endif #ifndef TARGET_NEED_FEATURE_SSE3 @@ -27,11 +27,11 @@ #endif #ifndef TARGET_NEED_FEATURE_VFPv4 -#define TARGET_NEED_FEATURE_VFPv4 1 +/* #undef TARGET_NEED_FEATURE_VFPv4 */ #endif #ifndef TARGET_NEED_FEATURE_NEONv2 -#define TARGET_NEED_FEATURE_NEONv2 1 +/* #undef TARGET_NEED_FEATURE_NEONv2 */ #endif #ifndef LA_HIGH_PERFORMANCE diff --git a/third_party/acados/larch64/lib/libacados.so b/third_party/acados/larch64/lib/libacados.so index 35f83d4159..9a28b4c9d6 100644 Binary files a/third_party/acados/larch64/lib/libacados.so and b/third_party/acados/larch64/lib/libacados.so differ diff --git a/third_party/acados/larch64/lib/libblasfeo.so b/third_party/acados/larch64/lib/libblasfeo.so index 6b0e26de79..b97ed876e2 100644 Binary files a/third_party/acados/larch64/lib/libblasfeo.so and b/third_party/acados/larch64/lib/libblasfeo.so differ diff --git a/third_party/acados/larch64/lib/libhpipm.so b/third_party/acados/larch64/lib/libhpipm.so index bebd5e8911..cd4b1f1b5b 100644 Binary files a/third_party/acados/larch64/lib/libhpipm.so and b/third_party/acados/larch64/lib/libhpipm.so differ diff --git a/third_party/acados/larch64/lib/libqpOASES_e.so.3.1 b/third_party/acados/larch64/lib/libqpOASES_e.so.3.1 index 0611c8a939..19e7a69bd5 100644 Binary files a/third_party/acados/larch64/lib/libqpOASES_e.so.3.1 and b/third_party/acados/larch64/lib/libqpOASES_e.so.3.1 differ diff --git a/third_party/acados/larch64/t_renderer b/third_party/acados/larch64/t_renderer index b4ff8bc319..b6f70bde06 100755 Binary files a/third_party/acados/larch64/t_renderer and b/third_party/acados/larch64/t_renderer differ diff --git a/third_party/acados/x86_64/lib/libacados.so b/third_party/acados/x86_64/lib/libacados.so index b8a6280d68..ae5fc363f2 100644 Binary files a/third_party/acados/x86_64/lib/libacados.so and b/third_party/acados/x86_64/lib/libacados.so differ diff --git a/third_party/acados/x86_64/lib/libblasfeo.so b/third_party/acados/x86_64/lib/libblasfeo.so index e4a19caf13..676ff67e98 100644 Binary files a/third_party/acados/x86_64/lib/libblasfeo.so and b/third_party/acados/x86_64/lib/libblasfeo.so differ diff --git a/third_party/acados/x86_64/lib/libhpipm.so b/third_party/acados/x86_64/lib/libhpipm.so index 428c76a117..8d026b1185 100644 Binary files a/third_party/acados/x86_64/lib/libhpipm.so and b/third_party/acados/x86_64/lib/libhpipm.so differ diff --git a/third_party/acados/x86_64/lib/libqpOASES_e.so.3.1 b/third_party/acados/x86_64/lib/libqpOASES_e.so.3.1 index cf3604688c..c0c8b66650 100644 Binary files a/third_party/acados/x86_64/lib/libqpOASES_e.so.3.1 and b/third_party/acados/x86_64/lib/libqpOASES_e.so.3.1 differ diff --git a/third_party/acados/x86_64/t_renderer b/third_party/acados/x86_64/t_renderer index 5ced89c28d..d84fc762c8 100755 Binary files a/third_party/acados/x86_64/t_renderer and b/third_party/acados/x86_64/t_renderer differ diff --git a/third_party/cluster/.gitignore b/third_party/cluster/.gitignore deleted file mode 100644 index 9daeafb986..0000000000 --- a/third_party/cluster/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/third_party/cluster/LICENSE b/third_party/cluster/LICENSE deleted file mode 100644 index ab8b4db7d7..0000000000 --- a/third_party/cluster/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright: - * fastcluster_dm.cpp & fastcluster_R_dm.cpp: - © 2011 Daniel Müllner - * fastcluster.(h|cpp) & demo.cpp & plotresult.r: - © 2018 Christoph Dalitz -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/cluster/README b/third_party/cluster/README deleted file mode 100644 index acb18bc72b..0000000000 --- a/third_party/cluster/README +++ /dev/null @@ -1,79 +0,0 @@ -C++ interface to fast hierarchical clustering algorithms -======================================================== - -This is a simplified C++ interface to fast implementations of hierarchical -clustering by Daniel Müllner. The original library with interfaces to R -and Python is described in: - -Daniel Müllner: "fastcluster: Fast Hierarchical, Agglomerative Clustering -Routines for R and Python." Journal of Statistical Software 53 (2013), -no. 9, pp. 1–18, http://www.jstatsoft.org/v53/i09/ - - -Usage of the library --------------------- - -For using the library, the following source files are needed: - -fastcluster_dm.cpp, fastcluster_R_dm.cpp - original code by Daniel Müllner - these are included by fastcluster.cpp via #include, and therefore - need not be compiled to object code - -fastcluster.[h|cpp] - simplified C++ interface - fastcluster.cpp is the only file that must be compiled - -The library provides the clustering function *hclust_fast* for -creating the dendrogram information in an encoding as used by the -R function *hclust*. For a description of the parameters, see fastcluster.h. -Its parameter *method* can be one of - -HCLUST_METHOD_SINGLE - single link with the minimum spanning tree algorithm (Rohlf, 1973) - -HHCLUST_METHOD_COMPLETE - complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) - -HCLUST_METHOD_AVERAGE - complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) - -HCLUST_METHOD_MEDIAN - median link with the generic algorithm (Müllner, 2011) - -For splitting the dendrogram into clusters, the two functions *cutree_k* -and *cutree_cdist* are provided. - -Note that output parameters must be allocated beforehand, e.g. - int* merge = new int[2*(npoints-1)]; -For a complete usage example, see lines 135-142 of demo.cpp. - - -Demonstration program ---------------------- - -A simple demo is implemented in demo.cpp, which can be compiled and run with - - make - ./hclust-demo -m complete lines.csv - -It creates two clusters of line segments such that the segment angle between -line segments of different clusters have a maximum (cosine) dissimilarity. -For visualizing the result, plotresult.r can be used as follows -(requires R to be installed): - - ./hclust-demo -m complete lines.csv | Rscript plotresult.r - - -Authors & Copyright -------------------- - -Daniel Müllner, 2011, -Christoph Dalitz, 2018, - - -License -------- - -This code is provided under a BSD-style license. -See the file LICENSE for details. diff --git a/third_party/cluster/SConscript b/third_party/cluster/SConscript deleted file mode 100644 index 97eb4300d4..0000000000 --- a/third_party/cluster/SConscript +++ /dev/null @@ -1,8 +0,0 @@ -Import('env') - -fc = env.SharedLibrary("fastcluster", "fastcluster.cpp") - -# TODO: how do I gate on test -#env.Program("test", ["test.cpp"], LIBS=[fc]) -#valgrind --leak-check=full ./test - diff --git a/third_party/cluster/__init__.py b/third_party/cluster/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/third_party/cluster/fastcluster.cpp b/third_party/cluster/fastcluster.cpp deleted file mode 100644 index d2b557d6f5..0000000000 --- a/third_party/cluster/fastcluster.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// -// C++ standalone verion of fastcluster by Daniel Müllner -// -// Copyright: Christoph Dalitz, 2018 -// Daniel Müllner, 2011 -// License: BSD style license -// (see the file LICENSE for details) -// - - -#include -#include -#include - - -extern "C" { -#include "fastcluster.h" -} - -// Code by Daniel Müllner -// workaround to make it usable as a standalone version (without R) -bool fc_isnan(double x) { return false; } -#include "fastcluster_dm.cpp" -#include "fastcluster_R_dm.cpp" - -extern "C" { -// -// Assigns cluster labels (0, ..., nclust-1) to the n points such -// that the cluster result is split into nclust clusters. -// -// Input arguments: -// n = number of observables -// merge = clustering result in R format -// nclust = number of clusters -// Output arguments: -// labels = allocated integer array of size n for result -// - void cutree_k(int n, const int* merge, int nclust, int* labels) { - - int k,m1,m2,j,l; - - if (nclust > n || nclust < 2) { - for (j=0; j last_merge(n, 0); - for (k=1; k<=(n-nclust); k++) { - // (m1,m2) = merge[k,] - m1 = merge[k-1]; - m2 = merge[n-1+k-1]; - if (m1 < 0 && m2 < 0) { // both single observables - last_merge[-m1-1] = last_merge[-m2-1] = k; - } - else if (m1 < 0 || m2 < 0) { // one is a cluster - if(m1 < 0) { j = -m1; m1 = m2; } else j = -m2; - // merging single observable and cluster - for(l = 0; l < n; l++) - if (last_merge[l] == m1) - last_merge[l] = k; - last_merge[j-1] = k; - } - else { // both cluster - for(l=0; l < n; l++) { - if( last_merge[l] == m1 || last_merge[l] == m2 ) - last_merge[l] = k; - } - } - } - - // assign cluster labels - int label = 0; - std::vector z(n,-1); - for (j=0; j= cdist - // - // Input arguments: - // n = number of observables - // merge = clustering result in R format - // height = cluster distance at each merge step - // cdist = cutoff cluster distance - // Output arguments: - // labels = allocated integer array of size n for result - // - void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels) { - - int k; - - for (k=0; k<(n-1); k++) { - if (height[k] >= cdist) { - break; - } - } - cutree_k(n, merge, n-k, labels); - } - - - // - // Hierarchical clustering with one of Daniel Muellner's fast algorithms - // - // Input arguments: - // n = number of observables - // distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing - // the upper triangle (without diagonal elements) of the distance - // matrix, e.g. for n=4: - // d00 d01 d02 d03 - // d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 - // d20 d21 d22 d23 - // d30 d31 d32 d33 - // method = cluster metric (see enum method_code) - // Output arguments: - // merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. - // Result follows R hclust convention: - // - observabe indices start with one - // - merge[i][] contains the merged nodes in step i - // - merge[i][j] is negative when the node is an atom - // height = allocated (n-1) array with distances at each merge step - // Return code: - // 0 = ok - // 1 = invalid method - // - int hclust_fast(int n, double* distmat, int method, int* merge, double* height) { - - // call appropriate culstering function - cluster_result Z2(n-1); - if (method == HCLUST_METHOD_SINGLE) { - // single link - MST_linkage_core(n, distmat, Z2); - } - else if (method == HCLUST_METHOD_COMPLETE) { - // complete link - NN_chain_core(n, distmat, NULL, Z2); - } - else if (method == HCLUST_METHOD_AVERAGE) { - // best average distance - double* members = new double[n]; - for (int i=0; i(n, distmat, members, Z2); - delete[] members; - } - else if (method == HCLUST_METHOD_MEDIAN) { - // best median distance (beware: O(n^3)) - generic_linkage(n, distmat, NULL, Z2); - } - else if (method == HCLUST_METHOD_CENTROID) { - // best centroid distance (beware: O(n^3)) - double* members = new double[n]; - for (int i=0; i(n, distmat, members, Z2); - delete[] members; - } - else { - return 1; - } - - int* order = new int[n]; - if (method == HCLUST_METHOD_MEDIAN || method == HCLUST_METHOD_CENTROID) { - generate_R_dendrogram(merge, height, order, Z2, n); - } else { - generate_R_dendrogram(merge, height, order, Z2, n); - } - delete[] order; // only needed for visualization - - return 0; - } - - - // Build condensed distance matrix - // Input arguments: - // n = number of observables - // m = dimension of observable - // Output arguments: - // out = allocated integer array of size n * (n - 1) / 2 for result - void hclust_pdist(int n, int m, double* pts, double* out) { - int ii = 0; - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n; j++) { - // Compute euclidian distance - double d = 0; - for (int k = 0; k < m; k ++) { - double error = pts[i * m + k] - pts[j * m + k]; - d += (error * error); - } - out[ii] = d;//sqrt(d); - ii++; - } - } - } - - void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx) { - double* pdist = new double[n * (n - 1) / 2]; - int* merge = new int[2 * (n - 1)]; - double* height = new double[n - 1]; - - hclust_pdist(n, m, pts, pdist); - hclust_fast(n, pdist, HCLUST_METHOD_CENTROID, merge, height); - cutree_cdist(n, merge, height, dist, idx); - - delete[] pdist; - delete[] merge; - delete[] height; - } -} diff --git a/third_party/cluster/fastcluster.h b/third_party/cluster/fastcluster.h deleted file mode 100644 index 56c63b6a5e..0000000000 --- a/third_party/cluster/fastcluster.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// C++ standalone verion of fastcluster by Daniel Muellner -// -// Copyright: Daniel Muellner, 2011 -// Christoph Dalitz, 2018 -// License: BSD style license -// (see the file LICENSE for details) -// - -#ifndef fastclustercpp_H -#define fastclustercpp_H - -// -// Assigns cluster labels (0, ..., nclust-1) to the n points such -// that the cluster result is split into nclust clusters. -// -// Input arguments: -// n = number of observables -// merge = clustering result in R format -// nclust = number of clusters -// Output arguments: -// labels = allocated integer array of size n for result -// -void cutree_k(int n, const int* merge, int nclust, int* labels); - -// -// Assigns cluster labels (0, ..., nclust-1) to the n points such -// that the hierarchical clsutering is stopped at cluster distance cdist -// -// Input arguments: -// n = number of observables -// merge = clustering result in R format -// height = cluster distance at each merge step -// cdist = cutoff cluster distance -// Output arguments: -// labels = allocated integer array of size n for result -// -void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels); - -// -// Hierarchical clustering with one of Daniel Muellner's fast algorithms -// -// Input arguments: -// n = number of observables -// distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing -// the upper triangle (without diagonal elements) of the distance -// matrix, e.g. for n=4: -// d00 d01 d02 d03 -// d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 -// d20 d21 d22 d23 -// d30 d31 d32 d33 -// method = cluster metric (see enum method_code) -// Output arguments: -// merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. -// Result follows R hclust convention: -// - observabe indices start with one -// - merge[i][] contains the merged nodes in step i -// - merge[i][j] is negative when the node is an atom -// height = allocated (n-1) array with distances at each merge step -// Return code: -// 0 = ok -// 1 = invalid method -// -int hclust_fast(int n, double* distmat, int method, int* merge, double* height); -enum hclust_fast_methods { - HCLUST_METHOD_SINGLE = 0, - HCLUST_METHOD_COMPLETE = 1, - HCLUST_METHOD_AVERAGE = 2, - HCLUST_METHOD_MEDIAN = 3, - HCLUST_METHOD_CENTROID = 5, -}; - -void hclust_pdist(int n, int m, double* pts, double* out); -void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx); - - -#endif diff --git a/third_party/cluster/fastcluster_R_dm.cpp b/third_party/cluster/fastcluster_R_dm.cpp deleted file mode 100644 index cbe126c15e..0000000000 --- a/third_party/cluster/fastcluster_R_dm.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// Excerpt from fastcluster_R.cpp -// -// Copyright: Daniel Müllner, 2011 -// - -struct pos_node { - t_index pos; - int node; -}; - -void order_nodes(const int N, const int * const merge, const t_index * const node_size, int * const order) { - /* Parameters: - N : number of data points - merge : (N-1)×2 array which specifies the node indices which are - merged in each step of the clustering procedure. - Negative entries -1...-N point to singleton nodes, while - positive entries 1...(N-1) point to nodes which are themselves - parents of other nodes. - node_size : array of node sizes - makes it easier - order : output array of size N - - Runtime: Θ(N) - */ - auto_array_ptr queue(N/2); - - int parent; - int child; - t_index pos = 0; - - queue[0].pos = 0; - queue[0].node = N-2; - t_index idx = 1; - - do { - --idx; - pos = queue[idx].pos; - parent = queue[idx].node; - - // First child - child = merge[parent]; - if (child<0) { // singleton node, write this into the 'order' array. - order[pos] = -child; - ++pos; - } - else { /* compound node: put it on top of the queue and decompose it - in a later iteration. */ - queue[idx].pos = pos; - queue[idx].node = child-1; // convert index-1 based to index-0 based - ++idx; - pos += node_size[child-1]; - } - // Second child - child = merge[parent+N-1]; - if (child<0) { - order[pos] = -child; - } - else { - queue[idx].pos = pos; - queue[idx].node = child-1; - ++idx; - } - } while (idx>0); -} - -#define size_(r_) ( ((r_ -void generate_R_dendrogram(int * const merge, double * const height, int * const order, cluster_result & Z2, const int N) { - // The array "nodes" is a union-find data structure for the cluster - // identites (only needed for unsorted cluster_result input). - union_find nodes(sorted ? 0 : N); - if (!sorted) { - std::stable_sort(Z2[0], Z2[N-1]); - } - - t_index node1, node2; - auto_array_ptr node_size(N-1); - - for (t_index i=0; inode1; - node2 = Z2[i]->node2; - } - else { - node1 = nodes.Find(Z2[i]->node1); - node2 = nodes.Find(Z2[i]->node2); - // Merge the nodes in the union-find data structure by making them - // children of a new node. - nodes.Union(node1, node2); - } - // Sort the nodes in the output array. - if (node1>node2) { - t_index tmp = node1; - node1 = node2; - node2 = tmp; - } - /* Conversion between labeling conventions. - Input: singleton nodes 0,...,N-1 - compound nodes N,...,2N-2 - Output: singleton nodes -1,...,-N - compound nodes 1,...,N - */ - merge[i] = (node1(node1)-1 - : static_cast(node1)-N+1; - merge[i+N-1] = (node2(node2)-1 - : static_cast(node2)-N+1; - height[i] = Z2[i]->dist; - node_size[i] = size_(node1) + size_(node2); - } - - order_nodes(N, merge, node_size, order); -} diff --git a/third_party/cluster/fastcluster_dm.cpp b/third_party/cluster/fastcluster_dm.cpp deleted file mode 100644 index ee6670c204..0000000000 --- a/third_party/cluster/fastcluster_dm.cpp +++ /dev/null @@ -1,1794 +0,0 @@ -/* - fastcluster: Fast hierarchical clustering routines for R and Python - - Copyright © 2011 Daniel Müllner - - - This library implements various fast algorithms for hierarchical, - agglomerative clustering methods: - - (1) Algorithms for the "stored matrix approach": the input is the array of - pairwise dissimilarities. - - MST_linkage_core: single linkage clustering with the "minimum spanning - tree algorithm (Rohlfs) - - NN_chain_core: nearest-neighbor-chain algorithm, suitable for single, - complete, average, weighted and Ward linkage (Murtagh) - - generic_linkage: generic algorithm, suitable for all distance update - formulas (Müllner) - - (2) Algorithms for the "stored data approach": the input are points in a - vector space. - - MST_linkage_core_vector: single linkage clustering for vector data - - generic_linkage_vector: generic algorithm for vector data, suitable for - the Ward, centroid and median methods. - - generic_linkage_vector_alternative: alternative scheme for updating the - nearest neighbors. This method seems faster than "generic_linkage_vector" - for the centroid and median methods but slower for the Ward method. - - All these implementation treat infinity values correctly. They throw an - exception if a NaN distance value occurs. -*/ - -// Older versions of Microsoft Visual Studio do not have the fenv header. -#ifdef _MSC_VER -#if (_MSC_VER == 1500 || _MSC_VER == 1600) -#define NO_INCLUDE_FENV -#endif -#endif -// NaN detection via fenv might not work on systems with software -// floating-point emulation (bug report for Debian armel). -#ifdef __SOFTFP__ -#define NO_INCLUDE_FENV -#endif -#ifdef NO_INCLUDE_FENV -#pragma message("Do not use fenv header.") -#else -//#pragma message("Use fenv header. If there is a warning about unknown #pragma STDC FENV_ACCESS, this can be ignored.") -//#pragma STDC FENV_ACCESS on -#include -#endif - -#include // for std::pow, std::sqrt -#include // for std::ptrdiff_t -#include // for std::numeric_limits<...>::infinity() -#include // for std::fill_n -#include // for std::runtime_error -#include // for std::string - -#include // also for DBL_MAX, DBL_MIN -#ifndef DBL_MANT_DIG -#error The constant DBL_MANT_DIG could not be defined. -#endif -#define T_FLOAT_MANT_DIG DBL_MANT_DIG - -#ifndef LONG_MAX -#include -#endif -#ifndef LONG_MAX -#error The constant LONG_MAX could not be defined. -#endif -#ifndef INT_MAX -#error The constant INT_MAX could not be defined. -#endif - -#ifndef INT32_MAX -#ifdef _MSC_VER -#if _MSC_VER >= 1600 -#define __STDC_LIMIT_MACROS -#include -#else -typedef __int32 int_fast32_t; -typedef __int64 int64_t; -#endif -#else -#define __STDC_LIMIT_MACROS -#include -#endif -#endif - -#define FILL_N std::fill_n -#ifdef _MSC_VER -#if _MSC_VER < 1600 -#undef FILL_N -#define FILL_N stdext::unchecked_fill_n -#endif -#endif - -// Suppress warnings about (potentially) uninitialized variables. -#ifdef _MSC_VER - #pragma warning (disable:4700) -#endif - -#ifndef HAVE_DIAGNOSTIC -#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6)) -#define HAVE_DIAGNOSTIC 1 -#endif -#endif - -#ifndef HAVE_VISIBILITY -#if __GNUC__ >= 4 -#define HAVE_VISIBILITY 1 -#endif -#endif - -/* Since the public interface is given by the Python respectively R interface, - * we do not want other symbols than the interface initalization routines to be - * visible in the shared object file. The "visibility" switch is a GCC concept. - * Hiding symbols keeps the relocation table small and decreases startup time. - * See http://gcc.gnu.org/wiki/Visibility - */ -#if HAVE_VISIBILITY -#pragma GCC visibility push(hidden) -#endif - -typedef int_fast32_t t_index; -#ifndef INT32_MAX -#define MAX_INDEX 0x7fffffffL -#else -#define MAX_INDEX INT32_MAX -#endif -#if (LONG_MAX < MAX_INDEX) -#error The integer format "t_index" must not have a greater range than "long int". -#endif -#if (INT_MAX > MAX_INDEX) -#error The integer format "int" must not have a greater range than "t_index". -#endif -typedef double t_float; - -/* Method codes. - - These codes must agree with the METHODS array in fastcluster.R and the - dictionary mthidx in fastcluster.py. -*/ -enum method_codes { - // non-Euclidean methods - METHOD_METR_SINGLE = 0, - METHOD_METR_COMPLETE = 1, - METHOD_METR_AVERAGE = 2, - METHOD_METR_WEIGHTED = 3, - METHOD_METR_WARD = 4, - METHOD_METR_WARD_D = METHOD_METR_WARD, - METHOD_METR_CENTROID = 5, - METHOD_METR_MEDIAN = 6, - METHOD_METR_WARD_D2 = 7, - - MIN_METHOD_CODE = 0, - MAX_METHOD_CODE = 7 -}; - -enum method_codes_vector { - // Euclidean methods - METHOD_VECTOR_SINGLE = 0, - METHOD_VECTOR_WARD = 1, - METHOD_VECTOR_CENTROID = 2, - METHOD_VECTOR_MEDIAN = 3, - - MIN_METHOD_VECTOR_CODE = 0, - MAX_METHOD_VECTOR_CODE = 3 -}; - -// self-destructing array pointer -template -class auto_array_ptr{ -private: - type * ptr; - auto_array_ptr(auto_array_ptr const &); // non construction-copyable - auto_array_ptr& operator=(auto_array_ptr const &); // non copyable -public: - auto_array_ptr() - : ptr(NULL) - { } - template - auto_array_ptr(index const size) - : ptr(new type[size]) - { } - template - auto_array_ptr(index const size, value const val) - : ptr(new type[size]) - { - FILL_N(ptr, size, val); - } - ~auto_array_ptr() { - delete [] ptr; } - void free() { - delete [] ptr; - ptr = NULL; - } - template - void init(index const size) { - ptr = new type [size]; - } - template - void init(index const size, value const val) { - init(size); - FILL_N(ptr, size, val); - } - inline operator type *() const { return ptr; } -}; - -struct node { - t_index node1, node2; - t_float dist; -}; - -inline bool operator< (const node a, const node b) { - return (a.dist < b.dist); -} - -class cluster_result { -private: - auto_array_ptr Z; - t_index pos; - -public: - cluster_result(const t_index size) - : Z(size) - , pos(0) - {} - - void append(const t_index node1, const t_index node2, const t_float dist) { - Z[pos].node1 = node1; - Z[pos].node2 = node2; - Z[pos].dist = dist; - ++pos; - } - - node * operator[] (const t_index idx) const { return Z + idx; } - - /* Define several methods to postprocess the distances. All these functions - are monotone, so they do not change the sorted order of distances. */ - - void sqrt() const { - for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { - ZZ->dist = std::sqrt(ZZ->dist); - } - } - - void sqrt(const t_float) const { // ignore the argument - sqrt(); - } - - void sqrtdouble(const t_float) const { // ignore the argument - for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { - ZZ->dist = std::sqrt(2*ZZ->dist); - } - } - - #ifdef R_pow - #define my_pow R_pow - #else - #define my_pow std::pow - #endif - - void power(const t_float p) const { - t_float const q = 1/p; - for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { - ZZ->dist = my_pow(ZZ->dist,q); - } - } - - void plusone(const t_float) const { // ignore the argument - for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { - ZZ->dist += 1; - } - } - - void divide(const t_float denom) const { - for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { - ZZ->dist /= denom; - } - } -}; - -class doubly_linked_list { - /* - Class for a doubly linked list. Initially, the list is the integer range - [0, size]. We provide a forward iterator and a method to delete an index - from the list. - - Typical use: for (i=L.start; L succ; - -private: - auto_array_ptr pred; - // Not necessarily private, we just do not need it in this instance. - -public: - doubly_linked_list(const t_index size) - // Initialize to the given size. - : start(0) - , succ(size+1) - , pred(size+1) - { - for (t_index i=0; i(2*N-3-(r_))*(r_)>>1)+(c_)-1] ) -// Z is an ((N-1)x4)-array -#define Z_(_r, _c) (Z[(_r)*4 + (_c)]) - -/* - Lookup function for a union-find data structure. - - The function finds the root of idx by going iteratively through all - parent elements until a root is found. An element i is a root if - nodes[i] is zero. To make subsequent searches faster, the entry for - idx and all its parents is updated with the root element. - */ -class union_find { -private: - auto_array_ptr parent; - t_index nextparent; - -public: - union_find(const t_index size) - : parent(size>0 ? 2*size-1 : 0, 0) - , nextparent(size) - { } - - t_index Find (t_index idx) const { - if (parent[idx] != 0 ) { // a → b - t_index p = idx; - idx = parent[idx]; - if (parent[idx] != 0 ) { // a → b → c - do { - idx = parent[idx]; - } while (parent[idx] != 0); - do { - t_index tmp = parent[p]; - parent[p] = idx; - p = tmp; - } while (parent[p] != idx); - } - } - return idx; - } - - void Union (const t_index node1, const t_index node2) { - parent[node1] = parent[node2] = nextparent++; - } -}; - -class nan_error{}; -#ifdef FE_INVALID -class fenv_error{}; -#endif - -static void MST_linkage_core(const t_index N, const t_float * const D, - cluster_result & Z2) { -/* - N: integer, number of data points - D: condensed distance matrix N*(N-1)/2 - Z2: output data structure - - The basis of this algorithm is an algorithm by Rohlf: - - F. James Rohlf, Hierarchical clustering using the minimum spanning tree, - The Computer Journal, vol. 16, 1973, p. 93–95. -*/ - t_index i; - t_index idx2; - doubly_linked_list active_nodes(N); - auto_array_ptr d(N); - - t_index prev_node; - t_float min; - - // first iteration - idx2 = 1; - min = std::numeric_limits::infinity(); - for (i=1; i tmp) - d[i] = tmp; - else if (fc_isnan(tmp)) - throw (nan_error()); -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - if (d[i] < min) { - min = d[i]; - idx2 = i; - } - } - Z2.append(prev_node, idx2, min); - } -} - -/* Functions for the update of the dissimilarity array */ - -inline static void f_single( t_float * const b, const t_float a ) { - if (*b > a) *b = a; -} -inline static void f_complete( t_float * const b, const t_float a ) { - if (*b < a) *b = a; -} -inline static void f_average( t_float * const b, const t_float a, const t_float s, const t_float t) { - *b = s*a + t*(*b); - #ifndef FE_INVALID -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (fc_isnan(*b)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - #endif -} -inline static void f_weighted( t_float * const b, const t_float a) { - *b = (a+*b)*.5; - #ifndef FE_INVALID -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (fc_isnan(*b)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - #endif -} -inline static void f_ward( t_float * const b, const t_float a, const t_float c, const t_float s, const t_float t, const t_float v) { - *b = ( (v+s)*a - v*c + (v+t)*(*b) ) / (s+t+v); - //*b = a+(*b)-(t*a+s*(*b)+v*c)/(s+t+v); - #ifndef FE_INVALID -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (fc_isnan(*b)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - #endif -} -inline static void f_centroid( t_float * const b, const t_float a, const t_float stc, const t_float s, const t_float t) { - *b = s*a - stc + t*(*b); - #ifndef FE_INVALID - if (fc_isnan(*b)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - #endif -} -inline static void f_median( t_float * const b, const t_float a, const t_float c_4) { - *b = (a+(*b))*.5 - c_4; - #ifndef FE_INVALID -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (fc_isnan(*b)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - #endif -} - -template -static void NN_chain_core(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { -/* - N: integer - D: condensed distance matrix N*(N-1)/2 - Z2: output data structure - - This is the NN-chain algorithm, described on page 86 in the following book: - - Fionn Murtagh, Multidimensional Clustering Algorithms, - Vienna, Würzburg: Physica-Verlag, 1985. -*/ - t_index i; - - auto_array_ptr NN_chain(N); - t_index NN_chain_tip = 0; - - t_index idx1, idx2; - - t_float size1, size2; - doubly_linked_list active_nodes(N); - - t_float min; - - for (t_float const * DD=D; DD!=D+(static_cast(N)*(N-1)>>1); - ++DD) { -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif - if (fc_isnan(*DD)) { - throw(nan_error()); - } -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - } - - #ifdef FE_INVALID - if (feclearexcept(FE_INVALID)) throw fenv_error(); - #endif - - for (t_index j=0; jidx2) { - t_index tmp = idx1; - idx1 = idx2; - idx2 = tmp; - } - - if (method==METHOD_METR_AVERAGE || - method==METHOD_METR_WARD) { - size1 = static_cast(members[idx1]); - size2 = static_cast(members[idx2]); - members[idx2] += members[idx1]; - } - - // Remove the smaller index from the valid indices (active_nodes). - active_nodes.remove(idx1); - - switch (method) { - case METHOD_METR_SINGLE: - /* - Single linkage. - - Characteristic: new distances are never longer than the old distances. - */ - // Update the distance matrix in the range [start, idx1). - for (i=active_nodes.start; i(members[i]); - for (i=active_nodes.start; i(members[i]) ); - // Update the distance matrix in the range (idx1, idx2). - for (; i(members[i]) ); - // Update the distance matrix in the range (idx2, N). - for (i=active_nodes.succ[idx2]; i(members[i]) ); - break; - - default: - throw std::runtime_error(std::string("Invalid method.")); - } - } - #ifdef FE_INVALID - if (fetestexcept(FE_INVALID)) throw fenv_error(); - #endif -} - -class binary_min_heap { - /* - Class for a binary min-heap. The data resides in an array A. The elements of - A are not changed but two lists I and R of indices are generated which point - to elements of A and backwards. - - The heap tree structure is - - H[2*i+1] H[2*i+2] - \ / - \ / - ≤ ≤ - \ / - \ / - H[i] - - where the children must be less or equal than their parent. Thus, H[0] - contains the minimum. The lists I and R are made such that H[i] = A[I[i]] - and R[I[i]] = i. - - This implementation is not designed to handle NaN values. - */ -private: - t_float * const A; - t_index size; - auto_array_ptr I; - auto_array_ptr R; - - // no default constructor - binary_min_heap(); - // noncopyable - binary_min_heap(binary_min_heap const &); - binary_min_heap & operator=(binary_min_heap const &); - -public: - binary_min_heap(t_float * const A_, const t_index size_) - : A(A_), size(size_), I(size), R(size) - { // Allocate memory and initialize the lists I and R to the identity. This - // does not make it a heap. Call heapify afterwards! - for (t_index i=0; i>1); idx>0; ) { - --idx; - update_geq_(idx); - } - } - - inline t_index argmin() const { - // Return the minimal element. - return I[0]; - } - - void heap_pop() { - // Remove the minimal element from the heap. - --size; - I[0] = I[size]; - R[I[0]] = 0; - update_geq_(0); - } - - void remove(t_index idx) { - // Remove an element from the heap. - --size; - R[I[size]] = R[idx]; - I[R[idx]] = I[size]; - if ( H(size)<=A[idx] ) { - update_leq_(R[idx]); - } - else { - update_geq_(R[idx]); - } - } - - void replace ( const t_index idxold, const t_index idxnew, - const t_float val) { - R[idxnew] = R[idxold]; - I[R[idxnew]] = idxnew; - if (val<=A[idxold]) - update_leq(idxnew, val); - else - update_geq(idxnew, val); - } - - void update ( const t_index idx, const t_float val ) const { - // Update the element A[i] with val and re-arrange the indices to preserve - // the heap condition. - if (val<=A[idx]) - update_leq(idx, val); - else - update_geq(idx, val); - } - - void update_leq ( const t_index idx, const t_float val ) const { - // Use this when the new value is not more than the old value. - A[idx] = val; - update_leq_(R[idx]); - } - - void update_geq ( const t_index idx, const t_float val ) const { - // Use this when the new value is not less than the old value. - A[idx] = val; - update_geq_(R[idx]); - } - -private: - void update_leq_ (t_index i) const { - t_index j; - for ( ; (i>0) && ( H(i)>1) ); i=j) - heap_swap(i,j); - } - - void update_geq_ (t_index i) const { - t_index j; - for ( ; (j=2*i+1)=H(i) ) { - ++j; - if ( j>=size || H(j)>=H(i) ) break; - } - else if ( j+1 -static void generic_linkage(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { - /* - N: integer, number of data points - D: condensed distance matrix N*(N-1)/2 - Z2: output data structure - */ - - const t_index N_1 = N-1; - t_index i, j; // loop variables - t_index idx1, idx2; // row and column indices - - auto_array_ptr n_nghbr(N_1); // array of nearest neighbors - auto_array_ptr mindist(N_1); // distances to the nearest neighbors - auto_array_ptr row_repr(N); // row_repr[i]: node number that the - // i-th row represents - doubly_linked_list active_nodes(N); - binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for - // the distance to the nearest neighbor of each point - t_index node1, node2; // node numbers in the output - t_float size1, size2; // and their cardinalities - - t_float min; // minimum and row index for nearest-neighbor search - t_index idx; - - for (i=0; ii} D(i,j) for i in range(N-1) - t_float const * DD = D; - for (i=0; i::infinity(); - for (idx=j=i+1; ji} D(i,j) - - Normally, we have equality. However, this minimum may become invalid due - to the updates in the distance matrix. The rules are: - - 1) If mindist[i] is equal to D(i, n_nghbr[i]), this is the correct - minimum and n_nghbr[i] is a nearest neighbor. - - 2) If mindist[i] is smaller than D(i, n_nghbr[i]), this might not be the - correct minimum. The minimum needs to be recomputed. - - 3) mindist[i] is never bigger than the true minimum. Hence, we never - miss the true minimum if we take the smallest mindist entry, - re-compute the value if necessary (thus maybe increasing it) and - looking for the now smallest mindist entry until a valid minimal - entry is found. This step is done in the lines below. - - The update process for D below takes care that these rules are - fulfilled. This makes sure that the minima in the rows D(i,i+1:)of D are - re-calculated when necessary but re-calculation is avoided whenever - possible. - - The re-calculation of the minima makes the worst-case runtime of this - algorithm cubic in N. We avoid this whenever possible, and in most cases - the runtime appears to be quadratic. - */ - idx1 = nn_distances.argmin(); - if (method != METHOD_METR_SINGLE) { - while ( mindist[idx1] < D_(idx1, n_nghbr[idx1]) ) { - // Recompute the minimum mindist[idx1] and n_nghbr[idx1]. - n_nghbr[idx1] = j = active_nodes.succ[idx1]; // exists, maximally N-1 - min = D_(idx1,j); - for (j=active_nodes.succ[j]; j(members[idx1]); - size2 = static_cast(members[idx2]); - members[idx2] += members[idx1]; - } - Z2.append(node1, node2, mindist[idx1]); - - // Remove idx1 from the list of active indices (active_nodes). - active_nodes.remove(idx1); - // Index idx2 now represents the new (merged) node with label N+i. - row_repr[idx2] = N+i; - - // Update the distance matrix - switch (method) { - case METHOD_METR_SINGLE: - /* - Single linkage. - - Characteristic: new distances are never longer than the old distances. - */ - // Update the distance matrix in the range [start, idx1). - for (j=active_nodes.start; j(members[j]) ); - if (n_nghbr[j] == idx1) - n_nghbr[j] = idx2; - } - // Update the distance matrix in the range (idx1, idx2). - for (; j(members[j]) ); - if (D_(j, idx2) < mindist[j]) { - nn_distances.update_leq(j, D_(j, idx2)); - n_nghbr[j] = idx2; - } - } - // Update the distance matrix in the range (idx2, N). - if (idx2(members[j]) ); - min = D_(idx2,j); - for (j=active_nodes.succ[j]; j(members[j]) ); - if (D_(idx2,j) < min) { - min = D_(idx2,j); - n_nghbr[idx2] = j; - } - } - nn_distances.update(idx2, min); - } - break; - - case METHOD_METR_CENTROID: { - /* - Centroid linkage. - - Shorter and longer distances can occur, not bigger than max(d1,d2) - but maybe smaller than min(d1,d2). - */ - // Update the distance matrix in the range [start, idx1). - t_float s = size1/(size1+size2); - t_float t = size2/(size1+size2); - t_float stc = s*t*mindist[idx1]; - for (j=active_nodes.start; j -static void MST_linkage_core_vector(const t_index N, - t_dissimilarity & dist, - cluster_result & Z2) { -/* - N: integer, number of data points - dist: function pointer to the metric - Z2: output data structure - - The basis of this algorithm is an algorithm by Rohlf: - - F. James Rohlf, Hierarchical clustering using the minimum spanning tree, - The Computer Journal, vol. 16, 1973, p. 93–95. -*/ - t_index i; - t_index idx2; - doubly_linked_list active_nodes(N); - auto_array_ptr d(N); - - t_index prev_node; - t_float min; - - // first iteration - idx2 = 1; - min = std::numeric_limits::infinity(); - for (i=1; i tmp) - d[i] = tmp; - else if (fc_isnan(tmp)) - throw (nan_error()); -#if HAVE_DIAGNOSTIC -#pragma GCC diagnostic pop -#endif - if (d[i] < min) { - min = d[i]; - idx2 = i; - } - } - Z2.append(prev_node, idx2, min); - } -} - -template -static void generic_linkage_vector(const t_index N, - t_dissimilarity & dist, - cluster_result & Z2) { - /* - N: integer, number of data points - dist: function pointer to the metric - Z2: output data structure - - This algorithm is valid for the distance update methods - "Ward", "centroid" and "median" only! - */ - const t_index N_1 = N-1; - t_index i, j; // loop variables - t_index idx1, idx2; // row and column indices - - auto_array_ptr n_nghbr(N_1); // array of nearest neighbors - auto_array_ptr mindist(N_1); // distances to the nearest neighbors - auto_array_ptr row_repr(N); // row_repr[i]: node number that the - // i-th row represents - doubly_linked_list active_nodes(N); - binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for - // the distance to the nearest neighbor of each point - t_index node1, node2; // node numbers in the output - t_float min; // minimum and row index for nearest-neighbor search - - for (i=0; ii} D(i,j) for i in range(N-1) - for (i=0; i::infinity(); - t_index idx; - for (idx=j=i+1; j(i,j); - } - if (tmp(idx1,j); - for (j=active_nodes.succ[j]; j(idx1,j); - if (tmp(j, idx2); - if (tmp < mindist[j]) { - nn_distances.update_leq(j, tmp); - n_nghbr[j] = idx2; - } - else if (n_nghbr[j] == idx2) - n_nghbr[j] = idx1; // invalidate - } - // Find the nearest neighbor for idx2. - if (idx2(idx2,j); - for (j=active_nodes.succ[j]; j(idx2, j); - if (tmp < min) { - min = tmp; - n_nghbr[idx2] = j; - } - } - nn_distances.update(idx2, min); - } - } - } -} - -template -static void generic_linkage_vector_alternative(const t_index N, - t_dissimilarity & dist, - cluster_result & Z2) { - /* - N: integer, number of data points - dist: function pointer to the metric - Z2: output data structure - - This algorithm is valid for the distance update methods - "Ward", "centroid" and "median" only! - */ - const t_index N_1 = N-1; - t_index i, j=0; // loop variables - t_index idx1, idx2; // row and column indices - - auto_array_ptr n_nghbr(2*N-2); // array of nearest neighbors - auto_array_ptr mindist(2*N-2); // distances to the nearest neighbors - - doubly_linked_list active_nodes(N+N_1); - binary_min_heap nn_distances(&*mindist, N_1, 2*N-2, 1); // minimum heap - // structure for the distance to the nearest neighbor of each point - - t_float min; // minimum for nearest-neighbor searches - - // Initialize the minimal distances: - // Find the nearest neighbor of each point. - // n_nghbr[i] = argmin_{j>i} D(i,j) for i in range(N-1) - for (i=1; i::infinity(); - t_index idx; - for (idx=j=0; j(i,j); - } - if (tmp - -extern "C" { -#include "fastcluster.h" -} - - -int main(int argc, const char* argv[]) { - const int n = 11; - const int m = 3; - double* pts = new double[n*m]{59.26000137, -9.35999966, -5.42500019, - 91.61999817, -0.31999999, -2.75, - 31.38000031, 0.40000001, -0.2, - 89.57999725, -8.07999992, -18.04999924, - 53.42000122, 0.63999999, -0.175, - 31.38000031, 0.47999999, -0.2, - 36.33999939, 0.16, -0.2, - 53.33999939, 0.95999998, -0.175, - 59.26000137, -9.76000023, -5.44999981, - 33.93999977, 0.40000001, -0.22499999, - 106.74000092, -5.76000023, -18.04999924}; - - int * idx = new int[n]; - int * correct_idx = new int[n]{0, 1, 2, 3, 4, 2, 5, 4, 0, 5, 6}; - - cluster_points_centroid(n, m, pts, 2.5 * 2.5, idx); - - for (int i = 0; i < n; i++) { - assert(idx[i] == correct_idx[i]); - } - - delete[] idx; - delete[] correct_idx; - delete[] pts; -} diff --git a/tools/bodyteleop/web.py b/tools/bodyteleop/web.py index e39756964f..ed94cb6d83 100644 --- a/tools/bodyteleop/web.py +++ b/tools/bodyteleop/web.py @@ -6,11 +6,16 @@ import ssl import uuid import time -from common.basedir import BASEDIR +# aiortc and its dependencies have lots of internal warnings :( +import warnings +warnings.resetwarnings() +warnings.simplefilter("always") + from aiohttp import web from aiortc import RTCPeerConnection, RTCSessionDescription import cereal.messaging as messaging +from common.basedir import BASEDIR from tools.bodyteleop.bodyav import BodyMic, WebClientSpeaker, force_codec, play_sound, MediaBlackhole, EncodedBodyVideo logger = logging.getLogger("pc") diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index d726872718..cdc809f2b4 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -27,8 +27,8 @@ assets_src = "assets/assets.qrc" cabana_env.Command(assets, assets_src, f"rcc $SOURCES -o $TARGET") cabana_env.Depends(assets, Glob('/assets/*', exclude=[assets, assets_src, "assets/assets.o"])) -prev_moc_path = cabana_env['QT_MOCHPREFIX'] -cabana_env['QT_MOCHPREFIX'] = os.path.dirname(prev_moc_path) + '/cabana/moc_' +prev_moc_path = cabana_env['QT3_MOCHPREFIX'] +cabana_env['QT3_MOCHPREFIX'] = os.path.dirname(prev_moc_path) + '/cabana/moc_' cabana_lib = cabana_env.Library("cabana_lib", ['mainwin.cc', 'streams/pandastream.cc', 'streams/devicestream.cc', 'streams/livestream.cc', 'streams/abstractstream.cc', 'streams/replaystream.cc', 'binaryview.cc', 'historylog.cc', 'videowidget.cc', 'signalview.cc', 'dbc/dbc.cc', 'dbc/dbcfile.cc', 'dbc/dbcmanager.cc', 'chart/chartswidget.cc', 'chart/chart.cc', 'chart/signalselector.cc', 'chart/tiplabel.cc', 'chart/sparkline.cc', diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 7ba2e87110..08e8b54b73 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -764,6 +764,7 @@ QXYSeries *ChartView::createSeries(SeriesType type, QColor color) { chart()->legend()->setMarkerShape(QLegend::MarkerShapeFromSeries); } else { series = new QScatterSeries(this); + static_cast(series)->setBorderColor(color); chart()->legend()->setMarkerShape(QLegend::MarkerShapeCircle); } series->setColor(color); diff --git a/tools/cabana/streams/pandastream.cc b/tools/cabana/streams/pandastream.cc index 275ed84f43..e19b2450bd 100644 --- a/tools/cabana/streams/pandastream.cc +++ b/tools/cabana/streams/pandastream.cc @@ -7,6 +7,20 @@ #include "selfdrive/ui/qt/util.h" +// TODO: remove clearLayout +static void clearLayout(QLayout* layout) { + while (layout->count() > 0) { + QLayoutItem* item = layout->takeAt(0); + if (QWidget* widget = item->widget()) { + widget->deleteLater(); + } + if (QLayout* childLayout = item->layout()) { + clearLayout(childLayout); + } + delete item; + } +} + PandaStream::PandaStream(QObject *parent, PandaStreamConfig config_) : config(config_), LiveStream(parent) { if (config.serial.isEmpty()) { auto serials = Panda::list(); diff --git a/tools/gpstest/rpc_server.py b/tools/gpstest/rpc_server.py index 178e8b2c3c..be8dbb61b8 100644 --- a/tools/gpstest/rpc_server.py +++ b/tools/gpstest/rpc_server.py @@ -128,7 +128,7 @@ class RemoteCheckerService(rpyc.Service): if pos_geo is None or len(pos_geo) == 0: continue - match = all(abs(g-s) < DELTA for g,s in zip(pos_geo[:2], [slat, slon])) + match = all(abs(g-s) < DELTA for g,s in zip(pos_geo[:2], [slat, slon], strict=True)) match &= abs(pos_geo[2] - salt) < ALT_DELTA if match: match_cnt += 1 diff --git a/tools/gpstest/test_gps.py b/tools/gpstest/test_gps.py index 2c08c105a1..5043e484fd 100644 --- a/tools/gpstest/test_gps.py +++ b/tools/gpstest/test_gps.py @@ -30,7 +30,7 @@ def create_backup(pigeon): pigeon.send(b"\xB5\x62\x09\x14\x04\x00\x00\x00\x00\x00\x21\xEC") try: if not pigeon.wait_for_ack(ack=pd.UBLOX_SOS_ACK, nack=pd.UBLOX_SOS_NACK): - assert False, "Could not store almanac" + raise RuntimeError("Could not store almanac") except TimeoutError: pass diff --git a/update_requirements.sh b/tools/install_python_dependencies.sh similarity index 71% rename from update_requirements.sh rename to tools/install_python_dependencies.sh index c9b49486e5..ffa9a6efef 100755 --- a/update_requirements.sh +++ b/tools/install_python_dependencies.sh @@ -2,7 +2,8 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -cd $DIR +ROOT=$DIR/../ +cd $ROOT RC_FILE="${HOME}/.$(basename ${SHELL})rc" if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then @@ -32,7 +33,7 @@ fi export MAKEFLAGS="-j$(nproc)" -PYENV_PYTHON_VERSION=$(cat .python-version) +PYENV_PYTHON_VERSION=$(cat $ROOT/.python-version) if ! pyenv prefix ${PYENV_PYTHON_VERSION} &> /dev/null; then # no pyenv update on mac if [ "$(uname)" == "Linux" ]; then @@ -49,33 +50,22 @@ pip install pip==23.2.1 pip install poetry==1.5.1 poetry config virtualenvs.prefer-active-python true --local +poetry config virtualenvs.in-project true --local -if [[ -n "$XX" ]] || [[ "$(basename "$(dirname "$(pwd)")")" == "xx" ]]; then - XX=true -fi - -POETRY_INSTALL_ARGS="--no-cache --no-root" - -if [ -n "$XX" ]; then - echo "WARNING: using xx dependency group, installing globally" - poetry config virtualenvs.create false --local - POETRY_INSTALL_ARGS="$POETRY_INSTALL_ARGS --with xx --sync" -else - echo "PYTHONPATH=${PWD}" > .env - poetry self add poetry-dotenv-plugin@^0.1.0 -fi +echo "PYTHONPATH=${PWD}" > $ROOT/.env +poetry self add poetry-dotenv-plugin@^0.1.0 echo "pip packages install..." -poetry install $POETRY_INSTALL_ARGS +poetry install --no-cache --no-root pyenv rehash -[ -n "$XX" ] || [ -n "$POETRY_VIRTUALENVS_CREATE" ] && RUN="" || RUN="poetry run" +[ -n "$POETRY_VIRTUALENVS_CREATE" ] && RUN="" || RUN="poetry run" if [ "$(uname)" != "Darwin" ]; then echo "pre-commit hooks install..." shopt -s nullglob for f in .pre-commit-config.yaml */.pre-commit-config.yaml; do - if [ -e "$DIR/$(dirname $f)/.git" ]; then + if [ -e "$ROOT/$(dirname $f)/.git" ]; then $RUN pre-commit install -c "$f" fi done diff --git a/tools/lib/framereader.py b/tools/lib/framereader.py index d9920ab128..b4845b9f0d 100644 --- a/tools/lib/framereader.py +++ b/tools/lib/framereader.py @@ -70,8 +70,8 @@ def ffprobe(fn, fmt=None): try: ffprobe_output = subprocess.check_output(cmd) - except subprocess.CalledProcessError: - raise DataUnreadableError(fn) + except subprocess.CalledProcessError as e: + raise DataUnreadableError(fn) from e return json.loads(ffprobe_output) @@ -80,14 +80,14 @@ def vidindex(fn, typ): vidindex_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "vidindex") vidindex = os.path.join(vidindex_dir, "vidindex") - subprocess.check_call(["make"], cwd=vidindex_dir, stdout=open("/dev/null", "w")) + subprocess.check_call(["make"], cwd=vidindex_dir, stdout=subprocess.DEVNULL) with tempfile.NamedTemporaryFile() as prefix_f, \ tempfile.NamedTemporaryFile() as index_f: try: subprocess.check_call([vidindex, typ, fn, prefix_f.name, index_f.name]) - except subprocess.CalledProcessError: - raise DataUnreadableError(f"vidindex failed on file {fn}") + except subprocess.CalledProcessError as e: + raise DataUnreadableError(f"vidindex failed on file {fn}") from e with open(index_f.name, "rb") as f: index = f.read() with open(prefix_f.name, "rb") as f: @@ -237,25 +237,23 @@ def decompress_video_data(rawdat, vid_fmt, w, h, pix_fmt): threads = os.getenv("FFMPEG_THREADS", "0") cuda = os.getenv("FFMPEG_CUDA", "0") == "1" - proc = subprocess.Popen( - ["ffmpeg", - "-threads", threads, - "-hwaccel", "none" if not cuda else "cuda", - "-c:v", "hevc", - "-vsync", "0", - "-f", vid_fmt, - "-flags2", "showall", - "-i", "pipe:0", - "-threads", threads, - "-f", "rawvideo", - "-pix_fmt", pix_fmt, - "pipe:1"], - stdin=tmpf, stdout=subprocess.PIPE, stderr=open("/dev/null")) - - # dat = proc.communicate()[0] - dat = proc.stdout.read() - if proc.wait() != 0: - raise DataUnreadableError("ffmpeg failed") + args = ["ffmpeg", + "-threads", threads, + "-hwaccel", "none" if not cuda else "cuda", + "-c:v", "hevc", + "-vsync", "0", + "-f", vid_fmt, + "-flags2", "showall", + "-i", "pipe:0", + "-threads", threads, + "-f", "rawvideo", + "-pix_fmt", pix_fmt, + "pipe:1"] + with subprocess.Popen(args, stdin=tmpf, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as proc: + # dat = proc.communicate()[0] + dat = proc.stdout.read() + if proc.wait() != 0: + raise DataUnreadableError("ffmpeg failed") if pix_fmt == "rgb24": ret = np.frombuffer(dat, dtype=np.uint8).reshape(-1, h, w, 3) @@ -418,7 +416,7 @@ class VideoStreamDecompressor: elif self.pix_fmt == "yuv444p": ret = np.frombuffer(dat, dtype=np.uint8).reshape((3, self.h, self.w)) else: - assert False + raise RuntimeError(f"unknown pix_fmt: {self.pix_fmt}") yield ret result_code = self.proc.wait() diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index 46c648ef12..8f1e5b9f80 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -98,7 +98,7 @@ class LogReader: for e in ents: _ents.append(e) except capnp.KjException: - warnings.warn("Corrupted events detected", RuntimeWarning) + warnings.warn("Corrupted events detected", RuntimeWarning, stacklevel=1) self._ents = list(sorted(_ents, key=lambda x: x.logMonoTime) if sort_by_time else _ents) self._ts = [x.logMonoTime for x in self._ents] diff --git a/tools/mac_setup.sh b/tools/mac_setup.sh index 765cdd5a30..45bdf90383 100755 --- a/tools/mac_setup.sh +++ b/tools/mac_setup.sh @@ -77,7 +77,7 @@ if [ -z "$OPENPILOT_ENV" ] && [ -n "$RC_FILE" ] && [ -z "$CI" ]; then fi # install python dependencies -$ROOT/update_requirements.sh +$DIR/install_python_dependencies.sh eval "$(pyenv init --path)" echo "[ ] installed python dependencies t=$SECONDS" diff --git a/tools/replay/lib/ui_helpers.py b/tools/replay/lib/ui_helpers.py index 1c18298969..4ab8efab61 100644 --- a/tools/replay/lib/ui_helpers.py +++ b/tools/replay/lib/ui_helpers.py @@ -161,7 +161,7 @@ def init_plots(arr, name_to_arr_idx, plot_xlims, plot_ylims, plot_names, plot_co idxs.append(name_to_arr_idx[item]) plot_select.append(i) axs[i].set_title(", ".join(f"{nm} ({cl})" - for (nm, cl) in zip(pl_list, plot_colors[i])), fontsize=10) + for (nm, cl) in zip(pl_list, plot_colors[i], strict=False)), fontsize=10) axs[i].tick_params(axis="x", colors="white") axs[i].tick_params(axis="y", colors="white") axs[i].title.set_color("white") @@ -205,11 +205,11 @@ def plot_model(m, img, calibration, top_down): px, py_bottom = to_topdown_pt(x - x_std, y) top_down[1][int(round(px - 4)):int(round(px + 4)), py_top:py_bottom] = find_color(top_down[0], YELLOW) - for path, prob, _ in zip(m.laneLines, m.laneLineProbs, m.laneLineStds): + for path, prob, _ in zip(m.laneLines, m.laneLineProbs, m.laneLineStds, strict=True): color = (0, int(255 * prob), 0) draw_path(path, color, img, calibration, top_down, YELLOW) - for edge, std in zip(m.roadEdges, m.roadEdgeStds): + for edge, std in zip(m.roadEdges, m.roadEdgeStds, strict=True): prob = max(1 - std, 0) color = (int(255 * prob), 0, 0) draw_path(edge, color, img, calibration, top_down, RED) diff --git a/tools/replay/logreader.cc b/tools/replay/logreader.cc index 9a5df2eeed..74aebceae5 100644 --- a/tools/replay/logreader.cc +++ b/tools/replay/logreader.cc @@ -29,8 +29,7 @@ Event::Event(const kj::ArrayPtr &amsg, bool frame) : reader(a LogReader::LogReader(size_t memory_pool_block_size) { #ifdef HAS_MEMORY_RESOURCE const size_t buf_size = sizeof(Event) * memory_pool_block_size; - pool_buffer_ = ::operator new(buf_size); - mbr_ = new std::pmr::monotonic_buffer_resource(pool_buffer_, buf_size); + mbr_ = std::make_unique(buf_size); #endif events.reserve(memory_pool_block_size); } @@ -39,11 +38,6 @@ LogReader::~LogReader() { for (Event *e : events) { delete e; } - -#ifdef HAS_MEMORY_RESOURCE - delete mbr_; - ::operator delete(pool_buffer_); -#endif } bool LogReader::load(const std::string &url, std::atomic *abort, @@ -69,7 +63,7 @@ bool LogReader::parse(const std::set &allow, std::atomic words((const capnp::word *)raw_.data(), raw_.size() / sizeof(capnp::word)); while (words.size() > 0 && !(abort && *abort)) { #ifdef HAS_MEMORY_RESOURCE - Event *evt = new (mbr_) Event(words); + Event *evt = new (mbr_.get()) Event(words); #else Event *evt = new Event(words); #endif @@ -85,7 +79,7 @@ bool LogReader::parse(const std::set &allow, std::atomicwhich == cereal::Event::WIDE_ROAD_ENCODE_IDX) { #ifdef HAS_MEMORY_RESOURCE - Event *frame_evt = new (mbr_) Event(words, true); + Event *frame_evt = new (mbr_.get()) Event(words, true); #else Event *frame_evt = new Event(words, true); #endif diff --git a/tools/replay/logreader.h b/tools/replay/logreader.h index 010839af22..1aa8c98b45 100644 --- a/tools/replay/logreader.h +++ b/tools/replay/logreader.h @@ -61,7 +61,6 @@ private: bool parse(const std::set &allow, std::atomic *abort); std::string raw_; #ifdef HAS_MEMORY_RESOURCE - std::pmr::monotonic_buffer_resource *mbr_ = nullptr; - void *pool_buffer_ = nullptr; + std::unique_ptr mbr_; #endif }; diff --git a/tools/replay/main.cc b/tools/replay/main.cc index 78be2acd0b..98a0bb3333 100644 --- a/tools/replay/main.cc +++ b/tools/replay/main.cc @@ -6,6 +6,11 @@ #include "tools/replay/replay.h" int main(int argc, char *argv[]) { +#ifdef __APPLE__ + // With all sockets opened, we might hit the default limit of 256 on macOS + util::set_file_descriptor_limit(1024); +#endif + QCoreApplication app(argc, argv); const QStringList base_blacklist = {"uiDebug", "userFlag"}; diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 74817584cd..9029213af5 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -18,7 +18,7 @@ Replay::Replay(QString route, QStringList allow, QStringList block, QStringList for (const auto &it : services) { uint16_t which = event_struct.getFieldByName(it.name).getProto().getDiscriminantValue(); if ((which == cereal::Event::Which::UI_DEBUG || which == cereal::Event::Which::USER_FLAG) && - !(flags & REPLAY_FLAG_ALL_SERVICES) && + !(flags & REPLAY_FLAG_ALL_SERVICES) && !allow.contains(it.name)) { continue; } @@ -307,7 +307,8 @@ void Replay::mergeSegments(const SegmentMap::iterator &begin, const SegmentMap:: updateEvents([&]() { events_.swap(new_events_); segments_merged_ = segments_need_merge; - return true; + // Do not wake up the stream thread if the current segment has not been merged. + return isSegmentMerged(current_segment_) || (segments_.count(current_segment_) == 0); }); } } diff --git a/tools/replay/tests/test_replay.cc b/tools/replay/tests/test_replay.cc index b1e0735167..441bac0cbd 100644 --- a/tools/replay/tests/test_replay.cc +++ b/tools/replay/tests/test_replay.cc @@ -43,13 +43,6 @@ TEST_CASE("httpMultiPartDownload") { REQUIRE(sha256(content) == TEST_RLOG_CHECKSUM); } -int random_int(int min, int max) { - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(min, max); - return dist(rng); -} - TEST_CASE("FileReader") { auto enable_local_cache = GENERATE(true, false); std::string cache_file = cacheFilePath(TEST_RLOG_URL); @@ -154,7 +147,7 @@ TEST_CASE("Route") { // helper class for unit tests class TestReplay : public Replay { public: - TestReplay(const QString &route, uint8_t flags = REPLAY_FLAG_NO_FILE_CACHE) : Replay(route, {}, {}, {}, nullptr, flags) {} + TestReplay(const QString &route, uint32_t flags = REPLAY_FLAG_NO_FILE_CACHE | REPLAY_FLAG_NO_VIPC) : Replay(route, {}, {}, {}, nullptr, flags) {} void test_seek(); void testSeekTo(int seek_to); }; @@ -198,7 +191,7 @@ void TestReplay::test_seek() { QEventLoop loop; std::thread thread = std::thread([&]() { for (int i = 0; i < 10; ++i) { - testSeekTo(random_int(0, 1 * 60)); + testSeekTo(util::random_int(0, 2 * 60)); } loop.quit(); }); diff --git a/tools/sim/lib/can.py b/tools/sim/lib/can.py index fba4dc0e58..d0b5888392 100755 --- a/tools/sim/lib/can.py +++ b/tools/sim/lib/can.py @@ -11,19 +11,12 @@ rpacker = CANPacker("acura_ilx_2016_nidec") def get_car_can_parser(): dbc_f = 'honda_civic_touring_2016_can_generated' - signals = [ - ("STEER_TORQUE", 0xe4), - ("STEER_TORQUE_REQUEST", 0xe4), - ("COMPUTER_BRAKE", 0x1fa), - ("COMPUTER_BRAKE_REQUEST", 0x1fa), - ("GAS_COMMAND", 0x200), - ] checks = [ (0xe4, 100), (0x1fa, 50), (0x200, 50), ] - return CANParser(dbc_f, signals, checks, 0) + return CANParser(dbc_f, checks, 0) cp = get_car_can_parser() def can_function(pm, speed, angle, idx, cruise_button, is_engaged): diff --git a/tools/ubuntu_setup.sh b/tools/ubuntu_setup.sh index 63e8fcdf3d..581b785252 100755 --- a/tools/ubuntu_setup.sh +++ b/tools/ubuntu_setup.sh @@ -138,9 +138,8 @@ else exit 1 fi - -# install python dependencies -$ROOT/update_requirements.sh +# python setup +$DIR/install_python_dependencies.sh source ~/.bashrc if [ -z "$OPENPILOT_ENV" ]; then
%1%2 %4%5 %6%7