diff --git a/.gitattributes b/.gitattributes index 507eb73c13..1cf541aa3a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,5 +10,5 @@ *.otf filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text -selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text -common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text +openpilot/selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text +openpilot/common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 711f4597bd..e8d4057bb1 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -8,24 +8,24 @@ chore: car: - changed-files: - - any-glob-to-all-files: '{selfdrive/car/**,opendbc_repo}' + - any-glob-to-all-files: '{openpilot/selfdrive/car/**,opendbc_repo}' simulation: - changed-files: - - any-glob-to-all-files: 'tools/sim/**' + - any-glob-to-all-files: 'openpilot/tools/sim/**' ui: - changed-files: - - any-glob-to-all-files: '{selfdrive/assets/**,selfdrive/ui/**,system/ui/**}' + - any-glob-to-all-files: '{openpilot/selfdrive/assets/**,openpilot/selfdrive/ui/**,openpilot/system/ui/**}' tools: - changed-files: - - any-glob-to-all-files: 'tools/**' + - any-glob-to-all-files: 'openpilot/tools/**' multilanguage: - changed-files: - - any-glob-to-all-files: 'selfdrive/ui/translations/**' + - any-glob-to-all-files: 'openpilot/selfdrive/ui/translations/**' autonomy: - changed-files: - - any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit,sunnypilot/modeld*/models/**}" + - any-glob-to-all-files: "{openpilot/selfdrive/modeld/models/**,openpilot/selfdrive/test/process_replay/model_replay_ref_commit,openpilot/sunnypilot/modeld*/models/**}" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2b4a5ed48f..b986273097 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -44,8 +44,8 @@ Explain how you tested this bug fix. **Checklist** -- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs -- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py) +- [ ] added entry to CAR in openpilot/selfdrive/car/*/values.py and ran `openpilot/selfdrive/car/docs.py` to generate new docs +- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/openpilot/selfdrive/car/tests/routes.py) - [ ] route with openpilot: - [ ] route with stock system: - [ ] car harness used (if comma doesn't sell it, put N/A): diff --git a/.github/workflows/auto_pr_review.yaml b/.github/workflows/auto_pr_review.yaml index edb058d7d1..29149d8652 100644 --- a/.github/workflows/auto_pr_review.yaml +++ b/.github/workflows/auto_pr_review.yaml @@ -12,7 +12,7 @@ jobs: issues: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: false @@ -24,7 +24,7 @@ jobs: # Check PR target branch - name: check branch - uses: Vankka/pr-target-branch-action@def32ec9d93514138d6ac0132ee62e120a72aed5 + uses: Vankka/pr-target-branch-action@5da68a42bcb7b43d39104295a876a6f3f8d7908b if: github.repository == 'sunnypilot/sunnypilot' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/cereal_validation.yaml b/.github/workflows/cereal_validation.yaml index 2ab617b2f0..0c87688bf1 100644 --- a/.github/workflows/cereal_validation.yaml +++ b/.github/workflows/cereal_validation.yaml @@ -6,7 +6,7 @@ on: - master pull_request: paths: - - 'cereal/**' + - 'openpilot/cereal/**' workflow_dispatch: workflow_call: inputs: @@ -30,11 +30,25 @@ jobs: - name: Checkout sunnypilot cereal uses: actions/checkout@v6 with: - sparse-checkout: cereal + sparse-checkout: | + openpilot/cereal + uv.lock + submodules: false - name: Init sunnypilot opendbc submodule run: git submodule update --init --depth 1 opendbc_repo + - name: Locate sunnypilot capnp import paths + id: locate-sp-capnp + run: | + SP_IMPORT_ARGS="" + SP_CAR_CAPNP=$(find opendbc_repo -maxdepth 4 -name car.capnp -path '*/opendbc/car/car.capnp' -printf '%h\n' -quit) + if [ -n "$SP_CAR_CAPNP" ]; then + SP_IMPORT_ARGS="-I $SP_CAR_CAPNP" + echo "Found sunnypilot car.capnp at: $SP_CAR_CAPNP" + fi + echo "import_args=$SP_IMPORT_ARGS" >> "$GITHUB_OUTPUT" + - name: Checkout upstream openpilot uses: actions/checkout@v6 with: @@ -65,20 +79,19 @@ jobs: fi echo "import_args=$IMPORT_ARGS" >> "$GITHUB_OUTPUT" - - name: Install uv - run: pip install uv + - name: Install pycapnp + run: | + PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") + pip install "pycapnp==${PYCAPNP_VER}" - name: Generate sunnypilot schema run: | - PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") - uv run --isolated --with "pycapnp==${PYCAPNP_VER}" \ - python3 cereal/messaging/tests/validate_sp_cereal_upstream.py \ - -g -f /tmp/sp_schema.json --cereal-dir cereal + python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \ + -g -f /tmp/sp_schema.json --cereal-dir openpilot/cereal \ + ${{ steps.locate-sp-capnp.outputs.import_args }} - name: Validate against upstream run: | - PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") - uv run --isolated --with "pycapnp==${PYCAPNP_VER}" \ - python3 cereal/messaging/tests/validate_sp_cereal_upstream.py \ + python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \ -r -f /tmp/sp_schema.json --cereal-dir ${{ steps.locate-capnp.outputs.cereal_dir }} \ ${{ steps.locate-capnp.outputs.import_args }} diff --git a/.github/workflows/diff_report.yaml b/.github/workflows/diff_report.yaml index 2ddb850944..0f706ea2ed 100644 --- a/.github/workflows/diff_report.yaml +++ b/.github/workflows/diff_report.yaml @@ -17,29 +17,41 @@ jobs: - name: Wait for process replay id: wait continue-on-error: true - uses: lewagon/wait-on-check-action@v1.3.4 + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: ${{ github.event.pull_request.head.sha }} check-name: process replay repo-token: ${{ secrets.GITHUB_TOKEN }} allowed-conclusions: success,failure wait-interval: 20 + - name: Get tests run ID + if: steps.wait.outcome == 'success' + id: tests-run + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + run_id=$(gh api \ + "repos/${{ github.repository }}/actions/workflows/tests.yaml/runs?event=pull_request&head_sha=${{ github.event.pull_request.head.sha }}&per_page=1" \ + --jq '.workflow_runs[0].id // empty') + if [ -z "$run_id" ]; then + echo "No tests.yaml run found for ${{ github.event.pull_request.head.sha }}" >&2 + exit 1 + fi + echo "run-id=$run_id" >> "$GITHUB_OUTPUT" - name: Download diff if: steps.wait.outcome == 'success' - uses: dawidd6/action-download-artifact@v6 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: - github_token: ${{ secrets.GITHUB_TOKEN }} - workflow: tests.yaml - workflow_conclusion: '' - pr: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository }} + run-id: ${{ steps.tests-run.outputs.run-id }} name: diff_report_${{ github.event.number }} path: . - allow_forks: true - name: Comment on PR if: steps.wait.outcome == 'success' - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b with: - filePath: diff_report.txt - comment_tag: diff_report - pr_number: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + file-path: diff_report.txt + comment-tag: diff_report + pr-number: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 23b20a86ff..0af94ba0da 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -22,7 +22,7 @@ jobs: steps: - uses: commaai/timeout@v1 - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true @@ -34,7 +34,7 @@ jobs: python scripts/docs.py build # Push to docs.comma.ai - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 if: github.ref == 'refs/heads/master' && github.repository == 'sunnypilot/sunnypilot' with: path: openpilot-docs @@ -45,7 +45,7 @@ jobs: run: | set -x - source release/identity.sh + source tools/release/identity.sh cd openpilot-docs git checkout --orphan tmp diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index fdd26253fa..ebb14d5dba 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -11,7 +11,7 @@ jobs: contents: write steps: - name: Delete stale Jenkins branches - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const cutoff = Date.now() - 24 * 60 * 60 * 1000; @@ -52,7 +52,7 @@ jobs: steps: - name: Check for trigger phrase id: check_comment - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const triggerPhrase = "trigger-jenkins"; @@ -72,7 +72,7 @@ jobs: - name: Checkout repository if: steps.check_comment.outputs.result == 'true' - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: refs/pull/${{ github.event.issue.number }}/head @@ -86,7 +86,7 @@ jobs: - name: Delete trigger comment if: steps.check_comment.outputs.result == 'true' && always() - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | await github.rest.issues.deleteComment({ diff --git a/.github/workflows/model_review.yaml b/.github/workflows/model_review.yaml index 2775dbc574..82c732dc3b 100644 --- a/.github/workflows/model_review.yaml +++ b/.github/workflows/model_review.yaml @@ -4,7 +4,7 @@ on: pull_request: types: [opened, reopened, synchronize] paths: - - 'selfdrive/modeld/models/*.onnx' + - 'openpilot/selfdrive/modeld/models/*.onnx' workflow_dispatch: jobs: @@ -16,11 +16,11 @@ jobs: if: github.repository == 'commaai/openpilot' steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: submodules: true - name: Checkout master - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: master path: base @@ -36,7 +36,7 @@ jobs: echo "EOF" >> $GITHUB_OUTPUT - name: Post model report comment - uses: marocchino/sticky-pull-request-comment@baa7203ed60924babbe5dcd0ac8eae3b66ec5e16 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 with: header: model-review message: ${{ steps.report.outputs.content }} \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6ae5336557..56aa126684 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,17 +15,17 @@ jobs: steps: - name: Wait for green check mark if: ${{ github.event_name == 'schedule' }} - uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: master wait-interval: 30 running-workflow-name: 'build __nightly' repo-token: ${{ secrets.GITHUB_TOKEN }} check-regexp: ^((?!.*(build prebuilt|create badges).*).)*$ - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 # checkout version > v4 breaks nightly release script with: submodules: true fetch-depth: 0 - run: ./tools/op.sh setup - name: Push __nightly - run: BRANCH=__nightly release/build_stripped.sh + run: BRANCH=__nightly tools/release/build_stripped.sh diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index 0db4933649..becfb93627 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -3,6 +3,8 @@ name: repo maintenance on: schedule: - cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST) + pull_request: + types: [closed] workflow_dispatch: env: @@ -12,9 +14,11 @@ jobs: package_updates: name: package_updates runs-on: ubuntu-latest - if: github.repository == 'sunnypilot/sunnypilot' + if: >- + github.repository == 'sunnypilot/sunnypilot' && + (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -50,10 +54,10 @@ jobs: git add . - name: update car docs run: | - python selfdrive/car/docs.py + python openpilot/selfdrive/car/docs.py git add docs/CARS.md - name: Create Pull Request - uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 with: author: github-actions[bot] token: ${{ github.repository == 'commaai/openpilot' && secrets.ACTIONS_CREATE_PR_PAT || secrets.GITHUB_TOKEN }} @@ -75,3 +79,43 @@ jobs: ${{ steps.pip_tree.outputs.PIP_TREE }} ``` labels: bot + + cleanup_closed_branches: + if: github.repository == 'commaai/openpilot' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: read + steps: + - uses: actions/github-script@v9 + with: + script: | + const { owner, repo } = context.repo; + const upstream = `${owner}/${repo}`; + + for await (const response of github.paginate.iterator(github.rest.pulls.list, { + owner, + repo, + state: 'closed', + per_page: 100, + })) { + for (const pr of response.data) { + if (pr.head.repo?.full_name !== upstream) continue; + + const branch = pr.head.ref; + try { + await github.rest.git.deleteRef({ + owner, + repo, + ref: `heads/${branch}`, + }); + console.log(`Deleted branch ${branch} (PR #${pr.number})`); + } catch (error) { + if (error.status === 422 || error.status === 403) { + console.log(`Skipping branch ${branch} (PR #${pr.number}): ${error.message}`); + continue; + } + throw error; + } + } + } diff --git a/.github/workflows/sunnypilot-build-prebuilt.yaml b/.github/workflows/sunnypilot-build-prebuilt.yaml index 977dc94972..f0b646119c 100644 --- a/.github/workflows/sunnypilot-build-prebuilt.yaml +++ b/.github/workflows/sunnypilot-build-prebuilt.yaml @@ -79,7 +79,7 @@ jobs: is_stable_branch="$(echo "$CONFIG" | jq -r '.stable_branch // false')"; echo "is_stable_branch=$is_stable_branch" >> $GITHUB_OUTPUT - stable_version=$(cat sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g'); + stable_version=$(cat openpilot/sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g'); echo "version=$([ "$is_stable_branch" = "true" ] && echo "$stable_version" || echo "$BUILD")" >> $GITHUB_OUTPUT echo "extra_version_identifier=${environment}" >> $GITHUB_OUTPUT fi @@ -177,7 +177,7 @@ jobs: - name: Build Main Project run: | export PYTHONPATH="$BUILD_DIR" - ./release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/ + ./tools/release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/ cd $BUILD_DIR sed -i '/from .board.jungle import PandaJungle, PandaJungleDFU/s/^/#/' panda/__init__.py echo "Building sunnypilot's modeld_v2..." @@ -208,17 +208,17 @@ jobs: --exclude='Jenkinsfile' \ --exclude='**/release/' \ --exclude='**/.github/' \ - --exclude='**/selfdrive/ui/replay/' \ + --exclude='**/openpilot/selfdrive/ui/replay/' \ --exclude='**/__pycache__/' \ --exclude='${{env.SCONS_CACHE_DIR}}' \ --exclude='**/.git/' \ --exclude='**/SConstruct' \ --exclude='**/SConscript' \ --exclude='**/.venv/' \ - --exclude='selfdrive/modeld/models/*.onnx*' \ - --exclude='sunnypilot/modeld*/models/*.onnx*' \ - --exclude='third_party/*x86*' \ - --exclude='third_party/*Darwin*' \ + --exclude='openpilot/selfdrive/modeld/models/*.onnx*' \ + --exclude='openpilot/sunnypilot/modeld*/models/*.onnx*' \ + --exclude='openpilot/third_party/*x86*' \ + --exclude='openpilot/third_party/*Darwin*' \ --delete-excluded \ --chown=comma:comma \ ${BUILD_DIR}/ ${OUTPUT_DIR}/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ee8f61f880..b5f941fc76 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -35,27 +35,27 @@ jobs: STRIPPED_DIR: /tmp/releasepilot PYTHONPATH: /tmp/releasepilot steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - name: Getting LFS files - uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 with: timeout_minutes: 2 max_attempts: 3 command: git lfs pull - name: Build devel - timeout-minutes: 1 - run: TARGET_DIR=$STRIPPED_DIR release/build_stripped.sh + timeout-minutes: 3 + run: TARGET_DIR=$STRIPPED_DIR tools/release/build_stripped.sh - run: ./tools/op.sh setup - name: Build openpilot and run checks timeout-minutes: 30 working-directory: ${{ env.STRIPPED_DIR }} - run: python3 system/manager/build.py + run: python3 openpilot/system/manager/build.py - name: Run tests timeout-minutes: 1 working-directory: ${{ env.STRIPPED_DIR }} - run: release/check-dirty.sh + run: tools/release/check-dirty.sh - name: Check submodules if: github.repository == 'sunnypilot/sunnypilot' timeout-minutes: 3 @@ -75,15 +75,13 @@ jobs: export CHECK_PR_REFS=true fi fi - release/check-submodules.sh + tools/release/check-submodules.sh build_mac: name: build macOS runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }} steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - name: Remove Homebrew from environment run: | FILTERED=$(echo "$PATH" | tr ':' '\n' | grep -v '/opt/homebrew' | tr '\n' ':') @@ -101,9 +99,7 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - run: ./tools/op.sh setup - name: Static analysis timeout-minutes: 1 @@ -118,16 +114,18 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - run: ./tools/op.sh setup + - name: Install raylib headless dependencies + if: ${{ !contains(runner.name, 'nsc') }} + run: sudo apt-get install -y --no-install-recommends libgles2 libegl1 - name: Build openpilot run: scons - name: Run unit tests timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 999 }} + env: + RAYLIB_BACKEND: headless run: | - source selfdrive/test/setup_xvfb.sh # Pre-compile Python bytecode so each pytest worker doesn't need to $PYTEST --collect-only -m 'not slow' -qq MAX_EXAMPLES=1 $PYTEST -m 'not slow' @@ -142,39 +140,37 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Run replay timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 20 }} continue-on-error: ${{ github.ref == 'refs/heads/master' }} - run: selfdrive/test/process_replay/test_processes.py -j$(nproc) + run: openpilot/selfdrive/test/process_replay/test_processes.py -j$(nproc) - name: Print diff id: print-diff if: always() - run: cat selfdrive/test/process_replay/diff.txt + run: cat openpilot/selfdrive/test/process_replay/diff.txt - name: Print diff report if: always() - run: cat selfdrive/test/process_replay/diff_report.txt - - uses: actions/upload-artifact@v6 + run: cat openpilot/selfdrive/test/process_replay/diff_report.txt + - uses: actions/upload-artifact@v7 if: always() continue-on-error: true with: name: process_replay_diff.txt - path: selfdrive/test/process_replay/diff.txt + path: openpilot/selfdrive/test/process_replay/diff.txt - name: Upload diff report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: always() && github.event_name == 'pull_request' continue-on-error: true with: name: diff_report_${{ github.event.number }} - path: selfdrive/test/process_replay/diff_report.txt + path: openpilot/selfdrive/test/process_replay/diff_report.txt - name: Checkout ci-artifacts if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: repository: commaai/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -187,13 +183,13 @@ jobs: git config user.email "<>" git fetch origin process-replay || true git checkout process-replay 2>/dev/null || git checkout --orphan process-replay - cp ${{ github.workspace }}/selfdrive/test/process_replay/fakedata/*.zst . + cp ${{ github.workspace }}/openpilot/selfdrive/test/process_replay/fakedata/*.zst . echo "${{ github.sha }}" > ref_commit git add . git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" || echo "No changes to commit" - name: Push refs if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' - uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 with: timeout_minutes: 2 max_attempts: 3 @@ -203,7 +199,7 @@ jobs: timeout-minutes: 4 env: ONNXCPU: 1 - run: $PYTEST selfdrive/test/process_replay/test_regen.py + run: $PYTEST openpilot/selfdrive/test/process_replay/test_regen.py simulator_driving: name: simulator driving @@ -215,17 +211,16 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} if: false # FIXME: Started to timeout recently steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Driving test timeout-minutes: 2 - run: | - source selfdrive/test/setup_xvfb.sh - pytest -s tools/sim/tests/test_metadrive_bridge.py + env: + # MetaDrive renders offscreen through panda3d's EGL pipe on llvmpipe + EGL_PLATFORM: surfaceless + run: pytest -s openpilot/tools/sim/tests/test_metadrive_bridge.py create_ui_report: name: Create UI Report @@ -236,19 +231,21 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 - with: - submodules: true + - uses: actions/checkout@v7 - run: ./tools/op.sh setup + - name: Install raylib headless dependencies + if: ${{ !contains(runner.name, 'nsc') }} + run: sudo apt-get install -y --no-install-recommends libgles2 libegl1 - name: Build openpilot run: scons - name: Create UI Report + env: + RAYLIB_BACKEND: headless run: | - source selfdrive/test/setup_xvfb.sh - python3 selfdrive/ui/tests/diff/replay.py - python3 selfdrive/ui/tests/diff/replay.py --big + python3 openpilot/selfdrive/ui/tests/diff/replay.py + python3 openpilot/selfdrive/ui/tests/diff/replay.py --big - name: Upload UI Report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ui-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} - path: selfdrive/ui/tests/diff/report + path: openpilot/selfdrive/ui/tests/diff/report diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index a02726c3af..8b7b63f344 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -8,9 +8,9 @@ on: branches: - 'master' paths: - - 'selfdrive/assets/**' - - 'selfdrive/ui/**' - - 'system/ui/**' + - 'openpilot/selfdrive/assets/**' + - 'openpilot/selfdrive/ui/**' + - 'openpilot/system/ui/**' workflow_dispatch: env: @@ -34,12 +34,12 @@ jobs: pull-requests: write actions: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - name: Waiting for ui generation to end - uses: lewagon/wait-on-check-action@v1.3.4 + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: ${{ env.SHA }} check-name: ${{ env.UI_JOB_NAME }} @@ -53,7 +53,7 @@ jobs: echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?[0-9]+)") | .number')" >> $GITHUB_OUTPUT - name: Getting proposed ui - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 with: github_token: ${{ secrets.GITHUB_TOKEN }} run_id: ${{ steps.get_run_id.outputs.run_id }} @@ -62,7 +62,7 @@ jobs: path: ${{ github.workspace }}/pr_ui - name: Getting mici master ui - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: sunnypilot/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -70,7 +70,7 @@ jobs: ref: openpilot_master_ui_mici_raylib - name: Getting big master ui - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: sunnypilot/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -97,7 +97,7 @@ jobs: done - name: Setup FFmpeg - uses: AnimMouse/setup-ffmpeg@ae28d57dabbb148eff63170b6bf7f2b60062cbae + uses: AnimMouse/setup-ffmpeg@178e0b4a408f06ce40d896c3cd79f50fa6f8b0c3 - name: Finding diffs if: github.event_name == 'pull_request_target' @@ -115,13 +115,13 @@ jobs: cp "${{ github.workspace }}/master_${name}/${video}.mp4" "${{ github.workspace }}/pr_ui/${video}_master.mp4" diff_exit_code=0 - python3 ${{ github.workspace }}/selfdrive/ui/tests/diff/diff.py \ + python3 ${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/diff.py \ "${{ github.workspace }}/pr_ui/${video}_master.mp4" \ "${{ github.workspace }}/pr_ui/${video}_proposed.mp4" \ "${diff_name}.html" --basedir "$baseurl" --no-open || diff_exit_code=$? - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.html" "${{ github.workspace }}/pr_ui/" - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.mp4" "${{ github.workspace }}/pr_ui/" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${{ github.workspace }}/pr_ui/" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.mp4" "${{ github.workspace }}/pr_ui/" REPORT_URL="https://sunnypilot.github.io/ci-artifacts/${diff_name}_pr_${{ github.event.number }}.html" if [ $diff_exit_code -eq 0 ]; then @@ -156,7 +156,7 @@ jobs: for variant in $VARIANTS; do IFS=':' read -r name _ _ <<< "$variant" diff_name="${name}_diff" - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.html" "${diff_name}_pr_${{ github.event.number }}.html" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${diff_name}_pr_${{ github.event.number }}.html" git add "${diff_name}_pr_${{ github.event.number }}.html" done git commit -m "ui diff reports for PR #${{ github.event.number }}" || echo "No changes to commit" @@ -164,12 +164,12 @@ jobs: - name: Comment on PR if: github.event_name == 'pull_request_target' - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b with: message: | ## UI Preview ${{ steps.find_diff.outputs.COMMENT }} - comment_tag: run_id_ui_preview - pr_number: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + comment-tag: run_id_ui_preview + pr-number: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index e4eaeb2c50..a033f70507 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,13 @@ a.out .cache/ bin/ +# created at launch for TICI PYTHONPATH (PC uses editable installs via pyproject.toml) +/msgq +/opendbc +/rednose +/teleoprtc +/tinygrad + *.mp4 *.dylib *.DSYM @@ -44,18 +51,18 @@ bin/ config.json compile_commands.json compare_runtime*.html -selfdrive/modeld/models/tg_input_devices.json +openpilot/selfdrive/modeld/models/tg_input_devices.json # build artifacts docs_site/ -selfdrive/pandad/pandad -cereal/services.h -cereal/gen -cereal/messaging/bridge -selfdrive/ui/translations/tmp -selfdrive/car/tests/cars_dump -system/camerad/camerad -system/camerad/test/ae_gray_test +openpilot/selfdrive/pandad/pandad +openpilot/cereal/services.h +openpilot/cereal/gen +openpilot/cereal/messaging/bridge +openpilot/selfdrive/ui/translations/tmp +openpilot/selfdrive/car/tests/cars_dump +openpilot/system/camerad/camerad +openpilot/system/camerad/test/ae_gray_test .coverage* coverage.xml diff --git a/.gitmodules b/.gitmodules index e2088276e2..a2d892d07f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,5 +17,5 @@ path = tinygrad_repo url = https://github.com/sunnypilot/tinygrad.git [submodule "sunnypilot/neural_network_data"] - path = sunnypilot/neural_network_data + path = openpilot/sunnypilot/neural_network_data url = https://github.com/sunnypilot/neural-network-data.git diff --git a/.vscode/launch.json b/.vscode/launch.json index 151b757dab..5a052a112a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,9 +6,9 @@ "type": "pickString", "description": "Select the process to debug", "options": [ - "selfdrive/controls/controlsd.py", - "system/timed/timed.py", - "tools/sim/run_bridge.py" + "openpilot/selfdrive/controls/controlsd.py", + "openpilot/system/timed/timed.py", + "openpilot/tools/sim/run_bridge.py" ] }, { @@ -16,7 +16,7 @@ "type": "pickString", "description": "Select the process to debug", "options": [ - "selfdrive/ui/ui" + "openpilot/selfdrive/ui/ui" ] }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index 811306f399..68f6b90371 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,10 +17,5 @@ "**/.git", "**/.venv", "**/__pycache__", - // exclude directories that should be using the symlinked version - "common/**", - "selfdrive/**", - "system/**", - "tools/**", ] } diff --git a/Jenkinsfile b/Jenkinsfile index 90f86b1967..d57e9502aa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -63,6 +63,8 @@ if [ -f /data/openpilot/launch_env.sh ]; then source /data/openpilot/launch_env.sh fi +export LD_LIBRARY_PATH="\$(python -c 'import ffmpeg; print(ffmpeg.LIB_DIR)'):/usr/local/lib:\${LD_LIBRARY_PATH:-}" + ln -snf ${env.TEST_DIR} /data/pythonpath cd ${env.TEST_DIR} || true @@ -93,7 +95,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps) retry (3) { def date = sh(script: 'date', returnStdout: true).trim(); device(device_ip, "set time", "date -s '" + date + "'") - device(device_ip, "git checkout", extra + "\n" + readFile("selfdrive/test/setup_device_ci.sh")) + device(device_ip, "git checkout", extra + "\n" + readFile("openpilot/selfdrive/test/setup_device_ci.sh")) } steps.each { item -> def name = item[0] @@ -179,7 +181,7 @@ node { try { if (env.BRANCH_NAME == 'devel-staging') { deviceStage("build release-tizi-staging", "tizi-needs-can", [], [ - step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging,release-mici-staging $SOURCE_DIR/release/build_release.sh"), + step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging,release-mici-staging $SOURCE_DIR/tools/release/build_release.sh"), ]) } @@ -187,12 +189,12 @@ node { parallel ( 'nightly': { deviceStage("build nightly", "tizi-needs-can", [], [ - step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"), + step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/tools/release/build_release.sh"), ]) }, 'nightly-dev': { deviceStage("build nightly-dev", "tizi-needs-can", [], [ - step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/release/build_release.sh"), + step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/tools/release/build_release.sh"), ]) }, ) @@ -202,51 +204,51 @@ node { parallel ( 'onroad tests': { deviceStage("onroad", "tizi-needs-can", ["UNSAFE=1"], [ - step("build openpilot", "cd system/manager && ./build.py"), - step("check dirty", "release/check-dirty.sh"), - step("onroad tests", "pytest selfdrive/test/test_onroad.py -s", [timeout: 60]), + step("build openpilot", "cd openpilot/system/manager && ./build.py"), + step("check dirty", "tools/release/check-dirty.sh"), + step("onroad tests", "pytest openpilot/selfdrive/test/test_onroad.py -s", [timeout: 60]), ]) }, 'HW + Unit Tests': { deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test power draw", "pytest -s selfdrive/test//test_power_draw.py"), - step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]), - step("test manager", "pytest system/manager/test/test_manager.py"), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test power draw", "pytest -s openpilot/selfdrive/test//test_power_draw.py"), + step("test encoder", "pytest openpilot/system/loggerd/tests/test_encoder.py", [diffPaths: ["openpilot/system/loggerd/"]]), + step("test manager", "pytest openpilot/system/manager/test/test_manager.py"), ]) }, 'camerad OX03C10': { deviceStage("OX03C10", "tizi-ox03c10", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"), - step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 90]), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"), + step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]), ]) }, 'camerad OS04C10': { deviceStage("OS04C10", "tici-os04c10", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"), - step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 90]), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"), + step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]), ]) }, 'sensord': { deviceStage("LSM + MMC", "tizi-lsmc", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test sensord", "pytest system/sensord/tests/test_sensord.py"), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test sensord", "pytest openpilot/system/sensord/tests/test_sensord.py"), ]) }, 'replay': { deviceStage("model-replay", "tizi-replay", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]), - step("model replay", "selfdrive/test/process_replay/model_replay.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]), + step("build", "cd openpilot/system/manager && ./build.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]), + step("model replay", "openpilot/selfdrive/test/process_replay/model_replay.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]), ]) }, 'tizi': { deviceStage("tizi", "tizi", ["UNSAFE=1"], [ - step("build openpilot", "cd system/manager && ./build.py"), - step("test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"), - step("test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"), - step("test amp", "pytest common/hardware/tici/tests/test_amplifier.py"), + step("build openpilot", "cd openpilot/system/manager && ./build.py"), + step("test pandad loopback", "pytest openpilot/selfdrive/pandad/tests/test_pandad_loopback.py"), + step("test pandad spi", "pytest openpilot/selfdrive/pandad/tests/test_pandad_spi.py"), + step("test amp", "pytest openpilot/common/hardware/tici/tests/test_amplifier.py"), ]) }, diff --git a/RELEASES.md b/RELEASES.md index 7946fce019..770a7c40fe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1104,7 +1104,7 @@ Version 0.2.1 (2016-12-14) Version 0.2 (2016-12-12) ========================= - * Car/Radar abstraction layers have shipped, see cereal/car.capnp + * Car/Radar abstraction layers have shipped, see openpilot/cereal/car.capnp * controlsd has been refactored * Shipped plant model and testing maneuvers * visiond exits more gracefully now diff --git a/SConstruct b/SConstruct index 877351af07..fa3ba952c3 100644 --- a/SConstruct +++ b/SConstruct @@ -27,6 +27,21 @@ AddOption('--minimal', default=(not TICI and not release), help='the minimum build to run openpilot. no tests, tools, etc.') +submodule_python_paths = [ + Dir("#").abspath, + Dir("#msgq_repo").abspath, + Dir("#opendbc_repo").abspath, + Dir("#rednose_repo").abspath, + Dir("#teleoprtc_repo").abspath, + Dir("#tinygrad_repo").abspath, +] +for p in reversed(submodule_python_paths): + if p not in sys.path: + sys.path.insert(0, p) + +if external_pythonpath := os.environ.get("PYTHONPATH"): + submodule_python_paths += [p for p in external_pythonpath.split(os.pathsep) if p and p not in submodule_python_paths] + # Detect platform arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() if platform.system() == "Darwin": @@ -40,9 +55,24 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libjpeg', 'libyuv', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] +ffmpeg = pkgs[pkg_names.index('ffmpeg')] +# Shared package ships .so/.dylib; older device venvs still have static .a only. +# Keep static link deps (x264/z/va/drm) when the installed package is static so +# TICI CI works without upgrading the device venv yet. +# TODO: drop the static fallback once device venvs have comma-deps-ffmpeg>=7.1.0.post94 +_ffmpeg_lib_names = os.listdir(ffmpeg.LIB_DIR) if os.path.isdir(ffmpeg.LIB_DIR) else [] +ffmpeg_shared = any( + n.startswith('libavcodec.so') or (n.startswith('libavcodec') and n.endswith('.dylib')) + for n in _ffmpeg_lib_names +) +ffmpeg_libs = ['avformat', 'avcodec', 'swresample', 'avutil'] +if not ffmpeg_shared: + ffmpeg_libs += ['x264', 'z'] + if arch != "Darwin": + ffmpeg_libs += ['va', 'va-drm', 'drm'] acados_include_dirs = [ acados.INCLUDE_DIR, os.path.join(acados.INCLUDE_DIR, "blasfeo", "include"), @@ -91,7 +121,7 @@ def _libflags(target, source, env, for_signature): env = Environment( ENV={ "PATH": os.environ['PATH'], - "PYTHONPATH": Dir("#").abspath, + "PYTHONPATH": os.pathsep.join(submodule_python_paths), "ACADOS_SOURCE_DIR": acados.DIR, "ACADOS_PYTHON_INTERFACE_PATH": acados.TEMPLATE_DIR, "TERA_PATH": acados.TERA_PATH @@ -112,22 +142,27 @@ env = Environment( CFLAGS=["-std=gnu11"], CXXFLAGS=["-std=c++1z"], CPPPATH=[ - "#", - "#msgq", + "#openpilot", + "#msgq_repo", # #include "msgq/..." + "#opendbc_repo", # #include "opendbc/..." + "#rednose_repo", # #include "rednose/..." + "#rednose_repo/rednose", # #include "logger/..." (rednose package root) + "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], + "#", ], LIBPATH=[ - "#common", + "#openpilot/common", "#msgq_repo", - "#selfdrive/pandad", - "#rednose/helpers", + "#openpilot/selfdrive/pandad", + "#rednose_repo/rednose/helpers", [x.LIB_DIR for x in pkgs], ], - RPATH=[], + RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, - REDNOSE_ROOT="#", + REDNOSE_ROOT="#rednose_repo", tools=["default", "cython", "compilation_db", "rednose_filter"], toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"], ) @@ -190,7 +225,7 @@ else: np_version = SCons.Script.Value(np.__version__) Export('envCython', 'np_version') -Export('env', 'arch', 'acados', 'release') +Export('env', 'arch', 'acados', 'release', 'ffmpeg_libs') # Setup cache dir default_cache_dir = '/data/scons_cache' if arch == "larch64" else '/tmp/scons_cache' @@ -211,7 +246,7 @@ def prune_cache_dir(target=None, source=None, env=None): # ********** start building stuff ********** # Build common module -SConscript(['common/SConscript']) +SConscript(['openpilot/common/SConscript']) Import('_common') common = [_common, 'json11', 'zmq'] Export('common') @@ -222,7 +257,7 @@ env_swaglog = env.Clone() env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""') SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog}) -SConscript(['cereal/SConscript']) +SConscript(['openpilot/cereal/SConscript']) Import('socketmaster', 'msgq') messaging = [socketmaster, msgq, 'capnp', 'kj',] @@ -233,34 +268,33 @@ Export('messaging') SConscript(['panda/SConscript']) # Build rednose library -SConscript(['rednose/SConscript']) +SConscript(['rednose_repo/rednose/SConscript']) # Build system services SConscript([ - 'system/loggerd/SConscript', + 'openpilot/system/loggerd/SConscript', ]) if arch == "larch64": - SConscript(['system/camerad/SConscript']) + SConscript(['openpilot/system/camerad/SConscript']) # Build selfdrive SConscript([ - 'selfdrive/pandad/SConscript', - 'selfdrive/controls/lib/lateral_mpc_lib/SConscript', - 'selfdrive/controls/lib/longitudinal_mpc_lib/SConscript', - 'selfdrive/locationd/SConscript', - 'selfdrive/modeld/SConscript', - 'selfdrive/ui/SConscript', + 'openpilot/selfdrive/pandad/SConscript', + 'openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript', + 'openpilot/selfdrive/locationd/SConscript', + 'openpilot/selfdrive/modeld/SConscript', + 'openpilot/selfdrive/ui/SConscript', ]) -SConscript(['sunnypilot/SConscript']) +SConscript(['openpilot/sunnypilot/SConscript']) # Build desktop-only tools if GetOption('extras') and arch != "larch64": SConscript([ - 'tools/replay/SConscript', - 'tools/cabana/SConscript', - 'tools/jotpluggler/SConscript', + 'openpilot/tools/replay/SConscript', + 'openpilot/tools/cabana/SConscript', + 'openpilot/tools/jotpluggler/SConscript', ]) diff --git a/cereal/SConscript b/cereal/SConscript deleted file mode 100644 index de7ca0d721..0000000000 --- a/cereal/SConscript +++ /dev/null @@ -1,20 +0,0 @@ -Import('env', 'common', 'msgq') - -cereal_dir = Dir('.') -gen_dir = Dir('gen') - -# Build cereal -schema_files = ['log.capnp', 'car.capnp', 'deprecated.capnp', 'custom.capnp'] -env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files], - schema_files, - f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/") - -cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files]) - -# Build messaging -services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET') -env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc', 'messaging/bridge_zmq.cc'], LIBS=[msgq, common, 'pthread']) - -socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc']) - -Export('cereal', 'socketmaster') diff --git a/cereal/__init__.py b/cereal/__init__.py deleted file mode 100644 index 93f4d77227..0000000000 --- a/cereal/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -import capnp -from importlib.resources import as_file, files - -capnp.remove_import_hook() - -with as_file(files("cereal")) as fspath: - CEREAL_PATH = fspath.as_posix() - log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp")) - car = capnp.load(os.path.join(CEREAL_PATH, "car.capnp")) - custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp")) diff --git a/cereal/car.capnp b/cereal/car.capnp deleted file mode 120000 index 4bc7f89b1f..0000000000 --- a/cereal/car.capnp +++ /dev/null @@ -1 +0,0 @@ -../opendbc_repo/opendbc/car/car.capnp \ No newline at end of file diff --git a/common/tests/test_params.cc b/common/tests/test_params.cc deleted file mode 100644 index f8d6c79f55..0000000000 --- a/common/tests/test_params.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "catch2/catch.hpp" -#define private public -#include "common/params.h" -#include "common/util.h" - -TEST_CASE("params_nonblocking_put") { - char tmp_path[] = "/tmp/asyncWriter_XXXXXX"; - const std::string param_path = mkdtemp(tmp_path); - auto param_names = {"CarParams", "IsMetric"}; - { - Params params(param_path); - for (const auto &name : param_names) { - params.putNonBlocking(name, "1"); - // param is empty - REQUIRE(params.get(name).empty()); - } - - // check if thread is running - REQUIRE(params.future.valid()); - REQUIRE(params.future.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout); - } - // check results - Params p(param_path); - for (const auto &name : param_names) { - REQUIRE(p.get(name) == "1"); - } -} diff --git a/conftest.py b/conftest.py index 7fde82af8b..d7bc7a6bf1 100644 --- a/conftest.py +++ b/conftest.py @@ -9,11 +9,14 @@ from openpilot.common.hardware import TICI, HARDWARE # these are heavy CI-only tests, invoked explicitly in .github/workflows/tests.yaml collect_ignore = [ - "selfdrive/test/process_replay/test_processes.py", - "selfdrive/test/process_replay/test_regen.py", + "openpilot/selfdrive/test/process_replay/test_processes.py", + "openpilot/selfdrive/test/process_replay/test_regen.py", + + "openpilot/tools/sim/", + # tinygrad JIT has process-global state. Other test files import modeld → tinygrad, # which corrupts JIT captures for test_warp.py in the same process. Run separately in CI. - "sunnypilot/modeld_v2/tests/test_warp.py", + "openpilot/sunnypilot/modeld_v2/tests/test_warp.py", ] diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3d39420c01..cbeb5f6d3a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -68,6 +68,6 @@ A good pull request has all of the following: ### A guide for forks In order for your fork's data to be eligible for the training set: -* **Your cereal messaging structs must be [compatible](../cereal#custom-forks)** +* **Your cereal messaging structs must be [compatible](../openpilot/cereal#custom-forks)** * **The definitions of all the stock messaging structs must not change**: Do not change how any of the fields are set, including everything from `selfdriveState.enabled` to `carState.steeringAngleDeg`. Instead, create your own structs and set them however you'd like. * **Do not include cars that are not supported in upstream platforms**: Instead, create new opendbc platforms for cars that you'd like to support outside of upstream, even if it's just a trim-level difference. diff --git a/docs/SAFETY.md b/docs/SAFETY.md index 0a662ac6cd..5857c6d5b5 100644 --- a/docs/SAFETY.md +++ b/docs/SAFETY.md @@ -35,8 +35,8 @@ For additional safety implementation details, refer to [panda safety model](http ### Forks of openpilot -* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/selfdrive/monitoring) -* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/selfdrive/selfdrived/helpers.py) +* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/monitoring) +* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/selfdrived/helpers.py) * If your fork modifies any of the code in `opendbc/safety/`: * your fork cannot use the openpilot trademark * your fork must preserve the full [safety test suite](https://github.com/commaai/opendbc/tree/master/opendbc/safety/tests) and all tests must pass, including any new coverage required by the fork's changes diff --git a/docs/concepts/logs.md b/docs/concepts/logs.md index e533d36297..dd954d4c76 100644 --- a/docs/concepts/logs.md +++ b/docs/concepts/logs.md @@ -2,13 +2,13 @@ openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge. -Check out our [Python library](https://github.com/commaai/openpilot/blob/master/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. +Check out our [Python library](https://github.com/commaai/openpilot/blob/master/openpilot/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/openpilot/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. For each segment, openpilot records the following log types: ## rlog.zst -rlogs contain all the messages passed amongst openpilot's processes. See [cereal/services.py](https://github.com/commaai/openpilot/blob/master/cereal/services.py) for a list of all the logged services. They're a zstd archive of the serialized [Cap’n Proto](https://capnproto.org/) messages. +rlogs contain all the messages passed amongst openpilot's processes. See [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for a list of all the logged services. They're a zstd archive of the serialized [Cap’n Proto](https://capnproto.org/) messages. ## {f,e,d}camera.hevc @@ -20,7 +20,7 @@ Each camera stream is H.265 encoded and written to its respective file. ## qlog.zst & qcamera.ts -qlogs are a decimated subset of the rlogs. Check out [cereal/services.py](https://github.com/commaai/cereal/blob/master/services.py) for the decimation. +qlogs are a decimated subset of the rlogs. Check out [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for the decimation. qcameras are H.264 encoded, lower res versions of the fcamera.hevc. The video shown in [comma connect](https://connect.comma.ai/) is from the qcameras. diff --git a/docs/how-to/car-port.md b/docs/how-to/car-port.md index ca565e53f6..c4106f91a7 100644 --- a/docs/how-to/car-port.md +++ b/docs/how-to/car-port.md @@ -30,7 +30,7 @@ Each car brand is supported by a standard interface structure in `opendbc/car/[b For historical reasons, openpilot still contains a small amount of car-specific logic. This will eventually be migrated to opendbc or otherwise removed. -* `selfdrive/car/car_specific.py`: Brand-specific event logic +* `openpilot/selfdrive/car/car_specific.py`: Brand-specific event logic # How do I port car? diff --git a/docs/how-to/replay-a-drive.md b/docs/how-to/replay-a-drive.md index a11b29dcc4..129e7b8301 100644 --- a/docs/how-to/replay-a-drive.md +++ b/docs/how-to/replay-a-drive.md @@ -5,7 +5,7 @@ Replaying is a critical tool for openpilot development and debugging. ## Replaying a route *Hardware required: none* -Just run `tools/replay/replay --demo`. +Just run `openpilot/tools/replay/replay --demo`. ## Replaying CAN data *Hardware required: jungle and comma four* diff --git a/docs/how-to/turn-the-speed-blue.md b/docs/how-to/turn-the-speed-blue.md index b5692daff7..5cfa8e176a 100644 --- a/docs/how-to/turn-the-speed-blue.md +++ b/docs/how-to/turn-the-speed-blue.md @@ -28,10 +28,10 @@ scons We'll run the `replay` tool with the demo route to get data streaming for testing our UI changes. ```bash # in terminal 1 -tools/replay/replay --demo +openpilot/tools/replay/replay --demo # in terminal 2 -./selfdrive/ui/ui.py +./openpilot/selfdrive/ui/ui.py ``` The openpilot UI should launch and show a replay of the demo route. @@ -45,10 +45,10 @@ Now let’s update the speed display color in the UI. Search for the function responsible for rendering the current speed: ```bash -git grep "_draw_current_speed" selfdrive/ui/onroad/hud_renderer.py +git grep "_draw_current_speed" openpilot/selfdrive/ui/onroad/hud_renderer.py ``` -You'll find the relevant code inside `selfdrive/ui/onroad/hud_renderer.py`, in this function: +You'll find the relevant code inside `openpilot/selfdrive/ui/onroad/hud_renderer.py`, in this function: ```python def _draw_current_speed(self, rect: rl.Rectangle) -> None: @@ -72,7 +72,7 @@ Change `COLORS.white` to make it **blue** instead of white. A nice soft blue is After making changes, re-run the UI to see your new UI: ```bash -./selfdrive/ui/ui.py +./openpilot/selfdrive/ui/ui.py ``` ![](https://blog.comma.ai/img/blue_speed_ui.png) diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 46b0a5d079..4f767f3b19 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -19,12 +19,12 @@ function agnos_init { # Check if AGNOS update is required if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/common/hardware/tici/agnos.py" - MANIFEST="$DIR/system/hardware/tici/agnos.json" + AGNOS_PY="$DIR/openpilot/common/hardware/tici/agnos.py" + MANIFEST="$DIR/openpilot/system/hardware/tici/agnos.json" if $AGNOS_PY --verify $MANIFEST; then sudo reboot fi - $DIR/common/hardware/tici/updater $AGNOS_PY $MANIFEST + $DIR/openpilot/common/hardware/tici/updater $AGNOS_PY $MANIFEST fi } @@ -70,6 +70,14 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" + # submodule package symlinks for PYTHONPATH imports on device. + # on PC these come from editable installs via pyproject.toml / uv. + ln -sfn msgq_repo/msgq msgq + ln -sfn opendbc_repo/opendbc opendbc + ln -sfn rednose_repo/rednose rednose + ln -sfn teleoprtc_repo/teleoprtc teleoprtc + ln -sfn tinygrad_repo/tinygrad tinygrad + # hardware specific init if [ -f /AGNOS ]; then agnos_init @@ -79,7 +87,7 @@ function launch { tmux capture-pane -pq -S-1000 > /tmp/launch_log # start manager - cd system/manager + cd openpilot/system/manager if [ ! -f $DIR/prebuilt ]; then ./build.py fi diff --git a/msgq b/msgq deleted file mode 120000 index df09146f62..0000000000 --- a/msgq +++ /dev/null @@ -1 +0,0 @@ -msgq_repo/msgq \ No newline at end of file diff --git a/msgq_repo b/msgq_repo index 3e3611ee2d..bb6cc57ef4 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit 3e3611ee2d485ed5b87ac233ee126729f22ad79f +Subproject commit bb6cc57ef4d9a3f9952d9ca84bfa580575e7e2a0 diff --git a/opendbc b/opendbc deleted file mode 120000 index 7cd9a5bd1e..0000000000 --- a/opendbc +++ /dev/null @@ -1 +0,0 @@ -opendbc_repo/opendbc \ No newline at end of file diff --git a/cereal/README.md b/openpilot/cereal/README.md similarity index 86% rename from cereal/README.md rename to openpilot/cereal/README.md index 45e859c09c..17f27fd742 100644 --- a/cereal/README.md +++ b/openpilot/cereal/README.md @@ -24,17 +24,17 @@ things are not. Read more details [here](https://capnproto.org/language.html). ### Custom forks Forks of [openpilot](https://github.com/commaai/openpilot) might want to add things to the messaging -spec, however this could conflict with future changes made in mainline cereal/openpilot. Rebasing against mainline openpilot +spec, however this could conflict with future changes made in mainline openpilot's cereal spec. Rebasing against mainline openpilot then means breaking backwards-compatibility with all old logs of your fork. So we added reserved events in -[custom.capnp](custom.capnp) that we will leave empty in mainline cereal/openpilot. **If you only modify those, you can ensure your +[custom.capnp](custom.capnp) that we will leave empty in mainline openpilot's cereal spec. **If you only modify those, you can ensure your fork will remain backwards-compatible with all versions of mainline openpilot and your fork.** An example of compatible changes: ```diff -diff --git a/cereal/custom.capnp b/cereal/custom.capnp +diff --git a/openpilot/cereal/custom.capnp b/openpilot/cereal/custom.capnp index 3348e859e..3365c7b98 100644 ---- a/cereal/custom.capnp -+++ b/cereal/custom.capnp +--- a/openpilot/cereal/custom.capnp ++++ b/openpilot/cereal/custom.capnp @@ -10,7 +10,11 @@ $Cxx.namespace("cereal"); # DO rename the structs # DON'T change the identifier (e.g. @0x81c2f05a394cf4af) @@ -48,10 +48,10 @@ index 3348e859e..3365c7b98 100644 } struct CustomReserved1 @0xaedffd8f31e7b55d { -diff --git a/cereal/log.capnp b/cereal/log.capnp +diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 1209f3fd9..b189f58b6 100644 ---- a/cereal/log.capnp -+++ b/cereal/log.capnp +--- a/openpilot/cereal/log.capnp ++++ b/openpilot/cereal/log.capnp @@ -2558,14 +2558,14 @@ struct Event { # DO change the name of the field @@ -76,7 +76,7 @@ index 1209f3fd9..b189f58b6 100644 Example --- ```python -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging # in subscriber sm = messaging.SubMaster(['sensorEvents']) diff --git a/openpilot/cereal/SConscript b/openpilot/cereal/SConscript new file mode 100644 index 0000000000..bee7620b1e --- /dev/null +++ b/openpilot/cereal/SConscript @@ -0,0 +1,22 @@ +Import('env', 'common', 'msgq') + +cereal_dir = Dir('.') +gen_dir = Dir('gen') + +# Build cereal +schema_files = ['log.capnp', 'deprecated.capnp', 'custom.capnp'] +car_capnp = '#opendbc_repo/opendbc/car/car.capnp' +all_output = schema_files + ['car.capnp'] +env.Command([f'gen/cpp/{s}.c++' for s in all_output] + [f'gen/cpp/{s}.h' for s in all_output], + schema_files + [car_capnp], + f"capnpc --src-prefix={cereal_dir.path} --src-prefix=opendbc_repo/opendbc/car --import-path=opendbc_repo/opendbc/car $SOURCES -o c++:{gen_dir.path}/cpp/") + +cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in all_output]) + +# Build messaging +services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET') +env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc', 'messaging/bridge_zmq.cc'], LIBS=[msgq, common, 'pthread']) + +socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc']) + +Export('cereal', 'socketmaster') diff --git a/openpilot/cereal/__init__.py b/openpilot/cereal/__init__.py new file mode 100644 index 0000000000..d4a43a8474 --- /dev/null +++ b/openpilot/cereal/__init__.py @@ -0,0 +1,11 @@ +import os +import capnp +from importlib.resources import as_file, files + +capnp.remove_import_hook() + +with as_file(files("openpilot.cereal")) as fspath, as_file(files("opendbc")) as opendbc_path: + CEREAL_PATH = fspath.as_posix() + opendbc_import_path = os.path.join(os.path.realpath(opendbc_path.as_posix()), 'car') + log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"), imports=[opendbc_import_path]) + custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp"), imports=[opendbc_import_path]) diff --git a/cereal/custom.capnp b/openpilot/cereal/custom.capnp similarity index 99% rename from cereal/custom.capnp rename to openpilot/cereal/custom.capnp index fe3ed9196f..e78f7a75c7 100644 --- a/cereal/custom.capnp +++ b/openpilot/cereal/custom.capnp @@ -1,4 +1,4 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); @0xb526ba661d550a59; diff --git a/cereal/deprecated.capnp b/openpilot/cereal/deprecated.capnp similarity index 99% rename from cereal/deprecated.capnp rename to openpilot/cereal/deprecated.capnp index 5e4b0b4de0..37153e4d62 100644 --- a/cereal/deprecated.capnp +++ b/openpilot/cereal/deprecated.capnp @@ -1,4 +1,4 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); @0x80ef1ec4889c2a63; diff --git a/cereal/include/c++.capnp b/openpilot/cereal/include/c++.capnp similarity index 100% rename from cereal/include/c++.capnp rename to openpilot/cereal/include/c++.capnp diff --git a/cereal/log.capnp b/openpilot/cereal/log.capnp similarity index 96% rename from cereal/log.capnp rename to openpilot/cereal/log.capnp index baf947f672..bcacad920e 100644 --- a/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -1,7 +1,7 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); -using Car = import "car.capnp"; +using Car = import "/car.capnp"; using Deprecated = import "deprecated.capnp"; using Custom = import "custom.capnp"; @@ -414,6 +414,10 @@ struct CanData { struct DeviceState @0xa4d8b5af2aa492eb { deviceType @45 :InitData.DeviceType; + # usb + chestnutPresent @51 :Bool; + usbState @52 :UsbState; + networkType @22 :NetworkType; networkInfo @31 :NetworkInfo; networkStrength @24 :NetworkStrength; @@ -684,33 +688,47 @@ struct PeripheralState { } } +struct UsbState { + devices @0 :List(Device); + + struct Device { + busnum @0 :UInt8; + devnum @1 :UInt8; + vendorId @2 :UInt16; + productId @3 :UInt16; + speedMbps @4 :UInt16; + manufacturer @6 :Text; + product @5 :Text; + linkErrorCount @7 :UInt16; + } +} + struct RadarState @0x9a185389d6fdd05f { - mdMonoTime @6 :UInt64; - carStateMonoTime @11 :UInt64; + mdMonoTime @6 :UInt64; # for debugging radarErrors @13 :Car.RadarData.Error; leadOne @3 :LeadData; leadTwo @4 :LeadData; struct LeadData { - dRel @0 :Float32; - yRel @1 :Float32; - vRel @2 :Float32; - aRel @3 :Float32; - vLead @4 :Float32; - dPath @6 :Float32; - vLat @7 :Float32; - vLeadK @8 :Float32; - aLeadK @9 :Float32; - fcw @10 :Bool; - status @11 :Bool; - aLeadTau @12 :Float32; - modelProb @13 :Float32; - radar @14 :Bool; - radarTrackId @15 :Int32 = -1; + dRel @0 :Float32; # m from the front bumper of the car + yRel @1 :Float32; # m in car frame, left positive + vRel @2 :Float32; # m/s relative longitudinal speed + vLead @4 :Float32; # m/s absolute lead speed + vLeadK @8 :Float32; # kalman-filtered lead speed + aLeadK @9 :Float32; # kalman-filtered lead accel + present @11 :Bool; # true if a lead is present + aLeadTau @12 :Float32; # lead accel time constant + modelProb @13 :Float32; # vision model lead probability + radar @14 :Bool; # true if lead is radar-matched (vs vision-only) + radarTrackId @15 :Int32 = -1; # for debugging deprecated :group { + aRel @3 :Float32; aLead @5 :Float32; + dPath @6 :Float32; + vLat @7 :Float32; + fcw @10 :Bool; } } @@ -723,6 +741,7 @@ struct RadarState @0x9a185389d6fdd05f { calPerc @9 :Int8; canMonoTimes @10 :List(UInt64); cumLagMs @5 :Float32; + carStateMonoTime @11 :UInt64; radarErrors @12 :List(Car.RadarData.ErrorDEPRECATED); } } @@ -771,13 +790,30 @@ struct SelfdriveState { alertStatus @5 :AlertStatus; alertSize @6 :AlertSize; alertType @7 :Text; - alertSound @8 :Car.CarControl.HUDControl.AudibleAlert; + alertSound @13 :AudibleAlert; alertHudVisual @12 :Car.CarControl.HUDControl.VisualAlert; # configurable driving settings experimentalMode @10 :Bool; personality @11 :LongitudinalPersonality; + enum AudibleAlert { + none @0; + + engage @1; + disengage @2; + refuse @3; + + warningSoft @4; + warningImmediate @5; + + prompt @6; + promptRepeat @7; + promptDistracted @8; + + preAlert @9; + } + enum OpenpilotState @0xdbe58b96d2d1ac61 { disabled @0; preEnabled @1; @@ -798,6 +834,10 @@ struct SelfdriveState { mid @2; full @3; } + + deprecated :group { + alertSound @8 :Car.CarControl.HUDControl.AudibleAlert; + } } struct ControlsState @0x97ff69c53601abf1 { @@ -918,7 +958,7 @@ struct ControlsState @0x97ff69c53601abf1 { alertStatus @38 :SelfdriveState.AlertStatus; alertSize @39 :SelfdriveState.AlertSize; alertType @44 :Text; - alertSound2 @56 :Car.CarControl.HUDControl.AudibleAlert; + alertSound2 @56 :SelfdriveState.AudibleAlert; engageable @41 :Bool; # can OP be engaged? state @31 :SelfdriveState.OpenpilotState; enabled @19 :Bool; @@ -1001,7 +1041,6 @@ struct ModelDataV2 { roadEdgeStds @14 :List(Float32); # predicted lead cars - leads @11 :List(LeadDataV2); leadsV3 @18 :List(LeadDataV3); meta @12 :MetaData; @@ -1011,8 +1050,9 @@ struct ModelDataV2 { action @26: Action; lateralPlannerSolutionDEPRECATED @25: Deprecated.LateralPlannerSolution; + leadsDEPRECATED @11 :List(LeadDataV2DEPRECATED); - struct LeadDataV2 { + struct LeadDataV2DEPRECATED { prob @0 :Float32; # probability that car is your lead at time t t @1 :Float32; @@ -1132,7 +1172,7 @@ struct EncodeIndex { } } -struct AndroidLogEntry { +struct OperatingSystemLogEntry { id @0 :UInt8; ts @1 :UInt64; priority @2 :UInt8; @@ -1270,7 +1310,7 @@ struct LateralPlan @0xe1e9318e2ae8b51e { struct LiveLocationKalman { # More info on reference frames: - # https://github.com/commaai/openpilot/tree/master/common/transformations + # https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations positionECEF @0 : Measurement; positionGeodetic @1 : Measurement; @@ -1327,7 +1367,7 @@ struct LiveLocationKalman { struct LivePose { # More info on reference frames: - # https://github.com/commaai/openpilot/tree/master/common/transformations + # https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations orientationNED @0 :XYZMeasurement; velocityDevice @1 :XYZMeasurement; accelerationDevice @2 :XYZMeasurement; @@ -2120,8 +2160,10 @@ struct DriverMonitoringStateDEPRECATED @0xb83cda094a1da284 { struct DriverMonitoringState { lockout @0 :Bool; - alertCountLockoutPercent @1 :Int8; - alertTimeLockoutPercent @2 :Int8; + lockoutRecoveryPercent @11 :Int8; + alert3Count @12 :Int8; + noResponseCount @13 :Int8; + noResponseForceDecel @14 :Bool; alwaysOn @3 :Bool; alwaysOnLockout @4 :Bool; @@ -2185,6 +2227,11 @@ struct DriverMonitoringState { calibratedPercent @0 :Int8; offset @1 :Float32; } + + deprecated :group { + alertCountLockoutPercent @1 :Int8; + alertTimeLockoutPercent @2 :Int8; + } } struct Boot { @@ -2517,7 +2564,7 @@ struct Event { rawAudioData @147 :AudioData; # systems stuff - androidLog @20 :AndroidLogEntry; + operatingSystemLog @20 :OperatingSystemLogEntry; managerState @78 :ManagerState; procLog @33 :ProcLog; clocks @35 :Clocks; diff --git a/cereal/messaging/__init__.py b/openpilot/cereal/messaging/__init__.py similarity index 99% rename from cereal/messaging/__init__.py rename to openpilot/cereal/messaging/__init__.py index ae32bfd4cb..cb5f090095 100644 --- a/cereal/messaging/__init__.py +++ b/openpilot/cereal/messaging/__init__.py @@ -9,8 +9,8 @@ import time from typing import Optional, List, Union, Dict -from cereal import log -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import MovingAverage NO_TRAVERSAL_LIMIT = 2**64-1 diff --git a/cereal/messaging/bridge.cc b/openpilot/cereal/messaging/bridge.cc similarity index 95% rename from cereal/messaging/bridge.cc rename to openpilot/cereal/messaging/bridge.cc index 77823c413a..ee3d5e93ca 100644 --- a/cereal/messaging/bridge.cc +++ b/openpilot/cereal/messaging/bridge.cc @@ -1,7 +1,7 @@ #include -#include "cereal/messaging/msgq_to_zmq.h" -#include "cereal/services.h" +#include "openpilot/cereal/messaging/msgq_to_zmq.h" +#include "openpilot/cereal/services.h" #include "common/util.h" ExitHandler do_exit; diff --git a/cereal/messaging/bridge_zmq.cc b/openpilot/cereal/messaging/bridge_zmq.cc similarity index 98% rename from cereal/messaging/bridge_zmq.cc rename to openpilot/cereal/messaging/bridge_zmq.cc index 5c56673b47..72d4345d03 100644 --- a/cereal/messaging/bridge_zmq.cc +++ b/openpilot/cereal/messaging/bridge_zmq.cc @@ -1,4 +1,4 @@ -#include "cereal/messaging/bridge_zmq.h" +#include "openpilot/cereal/messaging/bridge_zmq.h" #include #include diff --git a/cereal/messaging/bridge_zmq.h b/openpilot/cereal/messaging/bridge_zmq.h similarity index 100% rename from cereal/messaging/bridge_zmq.h rename to openpilot/cereal/messaging/bridge_zmq.h diff --git a/cereal/messaging/messaging.h b/openpilot/cereal/messaging/messaging.h similarity index 98% rename from cereal/messaging/messaging.h rename to openpilot/cereal/messaging/messaging.h index fb9c261f2b..933e0b9f15 100644 --- a/cereal/messaging/messaging.h +++ b/openpilot/cereal/messaging/messaging.h @@ -8,7 +8,7 @@ #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "common/timing.h" #include "msgq/ipc.h" diff --git a/cereal/messaging/msgq_to_zmq.cc b/openpilot/cereal/messaging/msgq_to_zmq.cc similarity index 98% rename from cereal/messaging/msgq_to_zmq.cc rename to openpilot/cereal/messaging/msgq_to_zmq.cc index 5e7ea22273..adea00f923 100644 --- a/cereal/messaging/msgq_to_zmq.cc +++ b/openpilot/cereal/messaging/msgq_to_zmq.cc @@ -1,8 +1,8 @@ -#include "cereal/messaging/msgq_to_zmq.h" +#include "openpilot/cereal/messaging/msgq_to_zmq.h" #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/util.h" extern ExitHandler do_exit; diff --git a/cereal/messaging/msgq_to_zmq.h b/openpilot/cereal/messaging/msgq_to_zmq.h similarity index 94% rename from cereal/messaging/msgq_to_zmq.h rename to openpilot/cereal/messaging/msgq_to_zmq.h index 64f3a2173e..a34f0ebbf0 100644 --- a/cereal/messaging/msgq_to_zmq.h +++ b/openpilot/cereal/messaging/msgq_to_zmq.h @@ -8,7 +8,7 @@ #include #include "msgq/impl_msgq.h" -#include "cereal/messaging/bridge_zmq.h" +#include "openpilot/cereal/messaging/bridge_zmq.h" class MsgqToZmq { public: diff --git a/cereal/messaging/socketmaster.cc b/openpilot/cereal/messaging/socketmaster.cc similarity index 98% rename from cereal/messaging/socketmaster.cc rename to openpilot/cereal/messaging/socketmaster.cc index dfeeb807ee..dd285a0c8e 100644 --- a/cereal/messaging/socketmaster.cc +++ b/openpilot/cereal/messaging/socketmaster.cc @@ -3,8 +3,8 @@ #include #include -#include "cereal/services.h" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" +#include "openpilot/cereal/messaging/messaging.h" const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1"); diff --git a/cereal/messaging/tests/__init__.py b/openpilot/cereal/messaging/tests/__init__.py similarity index 100% rename from cereal/messaging/tests/__init__.py rename to openpilot/cereal/messaging/tests/__init__.py diff --git a/cereal/messaging/tests/test_messaging.py b/openpilot/cereal/messaging/tests/test_messaging.py similarity index 97% rename from cereal/messaging/tests/test_messaging.py rename to openpilot/cereal/messaging/tests/test_messaging.py index 97388446f4..c2ac1578d4 100644 --- a/cereal/messaging/tests/test_messaging.py +++ b/openpilot/cereal/messaging/tests/test_messaging.py @@ -8,9 +8,10 @@ import time from openpilot.common.parameterized import parameterized import pytest -from cereal import log, car -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST events = [evt for evt in log.Event.schema.union_fields if evt in SERVICE_LIST.keys()] diff --git a/cereal/messaging/tests/test_pub_sub_master.py b/openpilot/cereal/messaging/tests/test_pub_sub_master.py similarity index 96% rename from cereal/messaging/tests/test_pub_sub_master.py rename to openpilot/cereal/messaging/tests/test_pub_sub_master.py index 5e26b49701..eb8f62140b 100644 --- a/cereal/messaging/tests/test_pub_sub_master.py +++ b/openpilot/cereal/messaging/tests/test_pub_sub_master.py @@ -2,11 +2,11 @@ import random import time from typing import Sized, cast -import cereal.messaging as messaging -from cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \ +import openpilot.cereal.messaging as messaging +from openpilot.cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \ random_bytes, random_carstate, assert_carstate, \ zmq_sleep -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST class TestSubMaster: diff --git a/cereal/messaging/tests/test_services.py b/openpilot/cereal/messaging/tests/test_services.py similarity index 64% rename from cereal/messaging/tests/test_services.py rename to openpilot/cereal/messaging/tests/test_services.py index 3320723fec..9ae7c3d840 100644 --- a/cereal/messaging/tests/test_services.py +++ b/openpilot/cereal/messaging/tests/test_services.py @@ -1,10 +1,10 @@ -import os +import subprocess import tempfile -from typing import Dict + from openpilot.common.parameterized import parameterized -import cereal.services as services -from cereal.services import SERVICE_LIST +import openpilot.cereal.services as services +from openpilot.cereal.services import SERVICE_LIST class TestServices: @@ -17,5 +17,5 @@ class TestServices: def test_generated_header(self): with tempfile.NamedTemporaryFile(suffix=".h") as f: - ret = os.system(f"python3 {services.__file__} > {f.name} && clang++ {f.name} -std=c++11") + ret = subprocess.run(f"python3 {services.__file__} > {f.name} && clang++ {f.name} -std=c++11", shell=True).returncode assert ret == 0, "generated services header is not valid C" diff --git a/cereal/messaging/tests/validate_sp_cereal_upstream.py b/openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py similarity index 100% rename from cereal/messaging/tests/validate_sp_cereal_upstream.py rename to openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py diff --git a/cereal/services.py b/openpilot/cereal/services.py similarity index 99% rename from cereal/services.py rename to openpilot/cereal/services.py index f933fc0125..ffe573a907 100755 --- a/cereal/services.py +++ b/openpilot/cereal/services.py @@ -41,7 +41,7 @@ _services: dict[str, tuple] = { "liveCalibration": (True, 4., 4), "liveTorqueParameters": (True, 4., 1), "liveDelay": (True, 4., 1), - "androidLog": (True, 0.), + "operatingSystemLog": (True, 0.), "carState": (True, 100., 10), "carControl": (True, 100., 10), "carOutput": (True, 100., 10), diff --git a/openpilot/common b/openpilot/common deleted file mode 120000 index 60d3b0a6a8..0000000000 --- a/openpilot/common +++ /dev/null @@ -1 +0,0 @@ -../common \ No newline at end of file diff --git a/common/SConscript b/openpilot/common/SConscript similarity index 81% rename from common/SConscript rename to openpilot/common/SConscript index c9bd1c72d1..13935b80d5 100644 --- a/common/SConscript +++ b/openpilot/common/SConscript @@ -5,6 +5,7 @@ common_libs = [ 'swaglog.cc', 'util.cc', 'ratekeeper.cc', + 'yuv.cc', ] _common = env.Library('common', common_libs, LIBS="json11") @@ -12,7 +13,7 @@ Export('_common') if GetOption('extras'): env.Program('tests/test_common', - ['tests/test_runner.cc', 'tests/test_params.cc', 'tests/test_util.cc', 'tests/test_swaglog.cc'], + ['tests/test_runner.cc', 'tests/test_util.cc', 'tests/test_swaglog.cc'], LIBS=[_common, 'json11', 'zmq', 'pthread']) # Cython bindings diff --git a/common/__init__.py b/openpilot/common/__init__.py similarity index 100% rename from common/__init__.py rename to openpilot/common/__init__.py diff --git a/common/api/__init__.py b/openpilot/common/api/__init__.py similarity index 100% rename from common/api/__init__.py rename to openpilot/common/api/__init__.py diff --git a/common/api/base.py b/openpilot/common/api/base.py similarity index 98% rename from common/api/base.py rename to openpilot/common/api/base.py index ddda6e6ae2..b58dd6bbd0 100644 --- a/common/api/base.py +++ b/openpilot/common/api/base.py @@ -4,7 +4,7 @@ import requests import unicodedata from datetime import datetime, timedelta, UTC from openpilot.common.hardware.hw import Paths -from openpilot.system.version import get_version +from openpilot.common.version import get_version # name: jwt signature algorithm KEYS = {"id_rsa": "RS256", diff --git a/common/api/comma_connect.py b/openpilot/common/api/comma_connect.py similarity index 100% rename from common/api/comma_connect.py rename to openpilot/common/api/comma_connect.py diff --git a/common/basedir.py b/openpilot/common/basedir.py similarity index 71% rename from common/basedir.py rename to openpilot/common/basedir.py index 6b4811e53c..49b092d930 100644 --- a/common/basedir.py +++ b/openpilot/common/basedir.py @@ -1,4 +1,4 @@ import os -BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) +BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../..")) diff --git a/common/constants.py b/openpilot/common/constants.py similarity index 100% rename from common/constants.py rename to openpilot/common/constants.py diff --git a/common/esim/__init__.py b/openpilot/common/esim/__init__.py similarity index 100% rename from common/esim/__init__.py rename to openpilot/common/esim/__init__.py diff --git a/common/esim/base.py b/openpilot/common/esim/base.py similarity index 100% rename from common/esim/base.py rename to openpilot/common/esim/base.py diff --git a/common/esim/esim.py b/openpilot/common/esim/esim.py similarity index 100% rename from common/esim/esim.py rename to openpilot/common/esim/esim.py diff --git a/common/esim/gsma_ci_bundle.pem b/openpilot/common/esim/gsma_ci_bundle.pem similarity index 100% rename from common/esim/gsma_ci_bundle.pem rename to openpilot/common/esim/gsma_ci_bundle.pem diff --git a/common/esim/lpa.py b/openpilot/common/esim/lpa.py similarity index 98% rename from common/esim/lpa.py rename to openpilot/common/esim/lpa.py index 4009823323..80138b54ae 100644 --- a/common/esim/lpa.py +++ b/openpilot/common/esim/lpa.py @@ -6,7 +6,6 @@ import fcntl import hashlib import os import requests -import serial import subprocess import sys import termios @@ -20,6 +19,7 @@ from pathlib import Path from openpilot.common.time_helpers import system_time_valid from openpilot.common.esim.base import LPABase, LPAError, LPAProfileNotFoundError, Profile +from openpilot.common.serial import Serial, SerialException GSMA_CI_BUNDLE = str(Path(__file__).parent / "gsma_ci_bundle.pem") @@ -133,7 +133,7 @@ class AtClient: self._device = device self._baud = baud self._timeout = timeout - self._serial: serial.Serial | None = None + self._serial: Serial | None = None def send_raw(self, data: bytes) -> None: self._ensure_serial() @@ -185,14 +185,14 @@ class AtClient: pass self._serial = None if self._serial is None: - self._serial = serial.Serial(self._device, baudrate=self._baud, timeout=self._timeout) + self._serial = Serial(self._device, baudrate=self._baud, timeout=self._timeout) def query(self, cmd: str) -> list[str]: self._ensure_serial() try: self._send(cmd) return self._expect() - except serial.SerialException: + except SerialException: self._ensure_serial(reconnect=True) self._send(cmd) return self._expect() @@ -208,7 +208,7 @@ class AtClient: if self._serial: try: self._serial.reset_input_buffer() - except (OSError, serial.SerialException, termios.error): + except (OSError, SerialException, termios.error): self._ensure_serial(reconnect=True) for line in self.query(f'AT+CCHO="{ISDR_AID}"'): if line.startswith("+CCHO:") and (ch := line.split(":", 1)[1].strip()): @@ -230,7 +230,7 @@ class AtClient: try: self._open_isdr_once() return - except (RuntimeError, TimeoutError, termios.error, serial.SerialException): + except (RuntimeError, TimeoutError, termios.error, SerialException): time.sleep(OPEN_ISDR_RETRY_DELAY_S) if attempt == OPEN_ISDR_RESET_ATTEMPT: self._reset_modem() diff --git a/common/file_chunker.py b/openpilot/common/file_chunker.py similarity index 58% rename from common/file_chunker.py rename to openpilot/common/file_chunker.py index 57dfc35531..74f3013f71 100755 --- a/common/file_chunker.py +++ b/openpilot/common/file_chunker.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import io import sys import math import os @@ -21,13 +22,12 @@ def get_chunk_targets(path, file_size): def chunk_file(path, targets): manifest_path, *chunk_paths = targets - with open(path, 'rb') as f: - data = f.read() - actual_num_chunks = max(1, math.ceil(len(data) / CHUNK_SIZE)) + actual_num_chunks = max(1, math.ceil(os.path.getsize(path) / CHUNK_SIZE)) assert len(chunk_paths) >= actual_num_chunks, f"Allowed {len(chunk_paths)} chunks but needs at least {actual_num_chunks}, for path {path}" - for i, chunk_path in enumerate(chunk_paths): - with open(chunk_path, 'wb') as f: - f.write(data[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE]) + with open(path, 'rb') as f: + for chunk_path in chunk_paths: + with open(chunk_path, 'wb') as out: + out.write(f.read(CHUNK_SIZE)) Path(manifest_path).write_text(str(len(chunk_paths))) os.remove(path) @@ -39,14 +39,40 @@ def get_existing_chunks(path): return _chunk_paths(path, num_chunks) raise FileNotFoundError(path) -def read_file_chunked(path): +class ChunkStream(io.RawIOBase): + def __init__(self, paths): + self._paths = iter(paths) + self._buf = memoryview(b'') + + def readable(self): + return True + + def readinto(self, b): + n = 0 + while n < len(b): + if not self._buf: + p = next(self._paths, None) + if p is None: + break + with open(p, 'rb') as f: + self._buf = memoryview(f.read()) + continue + take = min(len(b) - n, len(self._buf)) + b[n:n + take] = self._buf[:take] + self._buf = self._buf[take:] + n += take + return n + +def open_file_chunked(path): manifest_path = get_manifest_path(path) if os.path.isfile(manifest_path): num_chunks = int(Path(manifest_path).read_text().strip()) - return b''.join(Path(get_chunk_name(path, i, num_chunks)).read_bytes() for i in range(num_chunks)) - if os.path.isfile(path): - return Path(path).read_bytes() - raise FileNotFoundError(path) + paths = [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)] + elif os.path.isfile(path): + paths = [path] + else: + raise FileNotFoundError(path) + return io.BufferedReader(ChunkStream(paths)) if __name__ == "__main__": diff --git a/common/filter_simple.py b/openpilot/common/filter_simple.py similarity index 100% rename from common/filter_simple.py rename to openpilot/common/filter_simple.py diff --git a/common/git.py b/openpilot/common/git.py similarity index 100% rename from common/git.py rename to openpilot/common/git.py diff --git a/common/gpio.py b/openpilot/common/gpio.py similarity index 100% rename from common/gpio.py rename to openpilot/common/gpio.py diff --git a/common/gps.py b/openpilot/common/gps.py similarity index 100% rename from common/gps.py rename to openpilot/common/gps.py diff --git a/common/hardware/__init__.py b/openpilot/common/hardware/__init__.py similarity index 100% rename from common/hardware/__init__.py rename to openpilot/common/hardware/__init__.py diff --git a/common/hardware/base.h b/openpilot/common/hardware/base.h similarity index 91% rename from common/hardware/base.h rename to openpilot/common/hardware/base.h index 3cb8add783..f4546adfa8 100644 --- a/common/hardware/base.h +++ b/openpilot/common/hardware/base.h @@ -5,7 +5,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" // no-op base hw class class HardwareNone { diff --git a/common/hardware/base.py b/openpilot/common/hardware/base.py similarity index 99% rename from common/hardware/base.py rename to openpilot/common/hardware/base.py index bf6523db77..5d8f7770dc 100644 --- a/common/hardware/base.py +++ b/openpilot/common/hardware/base.py @@ -2,7 +2,7 @@ import os from abc import abstractmethod, ABC from dataclasses import dataclass, fields -from cereal import log +from openpilot.cereal import log from openpilot.common.esim.base import LPABase NetworkType = log.DeviceState.NetworkType diff --git a/common/hardware/hw.h b/openpilot/common/hardware/hw.h similarity index 100% rename from common/hardware/hw.h rename to openpilot/common/hardware/hw.h diff --git a/common/hardware/hw.py b/openpilot/common/hardware/hw.py similarity index 100% rename from common/hardware/hw.py rename to openpilot/common/hardware/hw.py diff --git a/common/hardware/pc/__init__.py b/openpilot/common/hardware/pc/__init__.py similarity index 100% rename from common/hardware/pc/__init__.py rename to openpilot/common/hardware/pc/__init__.py diff --git a/common/hardware/pc/hardware.h b/openpilot/common/hardware/pc/hardware.h similarity index 100% rename from common/hardware/pc/hardware.h rename to openpilot/common/hardware/pc/hardware.h diff --git a/common/hardware/pc/hardware.py b/openpilot/common/hardware/pc/hardware.py similarity index 88% rename from common/hardware/pc/hardware.py rename to openpilot/common/hardware/pc/hardware.py index b387f03127..b4aa56c904 100644 --- a/common/hardware/pc/hardware.py +++ b/openpilot/common/hardware/pc/hardware.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.hardware.base import HardwareBase class Pc(HardwareBase): diff --git a/common/hardware/tici/__init__.py b/openpilot/common/hardware/tici/__init__.py similarity index 100% rename from common/hardware/tici/__init__.py rename to openpilot/common/hardware/tici/__init__.py diff --git a/common/hardware/tici/agnos.json b/openpilot/common/hardware/tici/agnos.json similarity index 100% rename from common/hardware/tici/agnos.json rename to openpilot/common/hardware/tici/agnos.json diff --git a/common/hardware/tici/agnos.py b/openpilot/common/hardware/tici/agnos.py similarity index 98% rename from common/hardware/tici/agnos.py rename to openpilot/common/hardware/tici/agnos.py index c5ca7efb4a..e1f62c841c 100755 --- a/common/hardware/tici/agnos.py +++ b/openpilot/common/hardware/tici/agnos.py @@ -12,7 +12,7 @@ import requests SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') -AGNOS_MANIFEST_FILE = "system/hardware/tici/agnos.json" +AGNOS_MANIFEST_FILE = "openpilot/system/hardware/tici/agnos.json" class StreamingDecompressor: @@ -228,7 +228,7 @@ def flash_agnos_update(manifest_path: str, target_slot_number: int, cloudlog, st cloudlog.info(f"Target slot {target_slot_number}") # set target slot as unbootable - os.system(f"abctl --set_unbootable {target_slot_number}") + subprocess.run(f"abctl --set_unbootable {target_slot_number}", shell=True) for partition in update: success = False diff --git a/common/hardware/tici/all-partitions.json b/openpilot/common/hardware/tici/all-partitions.json similarity index 100% rename from common/hardware/tici/all-partitions.json rename to openpilot/common/hardware/tici/all-partitions.json diff --git a/common/hardware/tici/amplifier.py b/openpilot/common/hardware/tici/amplifier.py similarity index 100% rename from common/hardware/tici/amplifier.py rename to openpilot/common/hardware/tici/amplifier.py diff --git a/common/hardware/tici/hardware.h b/openpilot/common/hardware/tici/hardware.h similarity index 100% rename from common/hardware/tici/hardware.h rename to openpilot/common/hardware/tici/hardware.h diff --git a/common/hardware/tici/hardware.py b/openpilot/common/hardware/tici/hardware.py similarity index 99% rename from common/hardware/tici/hardware.py rename to openpilot/common/hardware/tici/hardware.py index bec4c90423..773cbd4bed 100644 --- a/common/hardware/tici/hardware.py +++ b/openpilot/common/hardware/tici/hardware.py @@ -7,7 +7,7 @@ import time from functools import cached_property, lru_cache from pathlib import Path -from cereal import log +from openpilot.cereal import log from openpilot.common.utils import sudo_read, sudo_write from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action from openpilot.common.esim.base import LPABase @@ -241,7 +241,7 @@ class Tici(HardwareBase): return (self.read_param_file("/sys/class/power_supply/bms/voltage_now", int) * self.read_param_file("/sys/class/power_supply/bms/current_now", int) / 1e12) def shutdown(self): - os.system("sudo poweroff") + subprocess.run("sudo poweroff", shell=True) def get_thermal_config(self): intake, exhaust, gnss, bottomSoc = None, None, None, None @@ -335,7 +335,7 @@ class Tici(HardwareBase): self.amplifier.initialize_configuration() # Allow hardwared to write engagement status to kmsg - os.system("sudo chmod a+w /dev/kmsg") + subprocess.run("sudo chmod a+w /dev/kmsg", shell=True) # Ensure fan gpio is enabled so fan runs until shutdown, also turned on at boot by the ABL gpio_init(GPIO.SOM_ST_IO, True) diff --git a/common/hardware/tici/id_rsa b/openpilot/common/hardware/tici/id_rsa similarity index 100% rename from common/hardware/tici/id_rsa rename to openpilot/common/hardware/tici/id_rsa diff --git a/common/hardware/tici/modem.py b/openpilot/common/hardware/tici/modem.py similarity index 98% rename from common/hardware/tici/modem.py rename to openpilot/common/hardware/tici/modem.py index 39266be122..0d30c49328 100755 --- a/common/hardware/tici/modem.py +++ b/openpilot/common/hardware/tici/modem.py @@ -3,7 +3,6 @@ import fcntl import json import logging import os -import serial import signal import subprocess import tempfile @@ -13,6 +12,8 @@ from ipaddress import IPv4Address, AddressValueError from enum import Enum +from openpilot.common.serial import Serial + logging.basicConfig( level=logging.INFO, format="%(asctime)s.%(msecs)03d %(levelname)-7s modem: %(message)s", @@ -96,7 +97,7 @@ class PPPSession: def reset_data_port(): """Drop DTR on PPP_PORT so the modem terminates any stuck PPP session.""" try: - with serial.Serial(PPP_PORT, 460800, timeout=1) as s: + with Serial(PPP_PORT, baudrate=460800, timeout=1) as s: s.dtr = False time.sleep(0.2) s.dtr = True @@ -220,7 +221,7 @@ class Modem: os.close(fd) return [] try: - with serial.Serial(AT_PORT, 9600, timeout=5) as ser: + with Serial(AT_PORT, baudrate=9600, timeout=5) as ser: ser.reset_input_buffer() ser.write((cmd + "\r").encode()) lines = [] @@ -505,7 +506,11 @@ class Modem: except (AddressValueError, ValueError): pass if not dns_servers: - logging.warning(f"no cellular DNS servers reported by modem: {v!r}") + dns_servers = [ + "8.8.8.8", # Google + "1.1.1.1", # Cloudflare + ] + logging.warning(f"no cellular DNS servers reported by modem: {v!r}; using fallback {dns_servers}") return dns_servers def _poll_byte_counters(self) -> dict: diff --git a/common/hardware/tici/pins.py b/openpilot/common/hardware/tici/pins.py similarity index 100% rename from common/hardware/tici/pins.py rename to openpilot/common/hardware/tici/pins.py diff --git a/common/hardware/tici/power_monitor.py b/openpilot/common/hardware/tici/power_monitor.py similarity index 100% rename from common/hardware/tici/power_monitor.py rename to openpilot/common/hardware/tici/power_monitor.py diff --git a/common/hardware/tici/tests/__init__.py b/openpilot/common/hardware/tici/tests/__init__.py similarity index 100% rename from common/hardware/tici/tests/__init__.py rename to openpilot/common/hardware/tici/tests/__init__.py diff --git a/common/hardware/tici/tests/test_agnos_updater.py b/openpilot/common/hardware/tici/tests/test_agnos_updater.py similarity index 100% rename from common/hardware/tici/tests/test_agnos_updater.py rename to openpilot/common/hardware/tici/tests/test_agnos_updater.py diff --git a/common/hardware/tici/tests/test_amplifier.py b/openpilot/common/hardware/tici/tests/test_amplifier.py similarity index 97% rename from common/hardware/tici/tests/test_amplifier.py rename to openpilot/common/hardware/tici/tests/test_amplifier.py index 39628b53cc..3e36ff3a3d 100644 --- a/common/hardware/tici/tests/test_amplifier.py +++ b/openpilot/common/hardware/tici/tests/test_amplifier.py @@ -1,6 +1,5 @@ import pytest import time -import random import subprocess from panda import Panda @@ -57,7 +56,7 @@ class TestAmplifier: time.sleep(0.1) self.panda.set_siren(True) - time.sleep(random.randint(0, 5)) + time.sleep(0.1) amp = Amplifier(debug=True) r = amp.initialize_configuration() diff --git a/common/hardware/tici/updater b/openpilot/common/hardware/tici/updater similarity index 100% rename from common/hardware/tici/updater rename to openpilot/common/hardware/tici/updater diff --git a/openpilot/common/hardware/usb.py b/openpilot/common/hardware/usb.py new file mode 100644 index 0000000000..983002b538 --- /dev/null +++ b/openpilot/common/hardware/usb.py @@ -0,0 +1,73 @@ +from pathlib import Path + +CHESTNUT_VENDOR_ID = 0xADD1 +CHESTNUT_PRODUCT_ID = 0x0001 +USB_DEVICES_PATH = Path("/sys/bus/usb/devices") + + +def read(path: Path) -> str | None: + try: + return path.read_text().strip() + except OSError: + return None + + +def read_int(path: Path, base: int = 10) -> int: + try: + return int(path.read_text(), base) + except (OSError, ValueError): + return 0 + + +def usb_devices() -> list[Path]: + try: + devices = (d for d in USB_DEVICES_PATH.glob("*") if (d / "idVendor").exists()) + return sorted(devices, key=lambda p: p.name) + except OSError: + return [] + + +def controller(device: Path) -> Path | None: + try: + return next((parent for parent in device.resolve().parents if parent.name.endswith(".ssusb")), None) + except OSError: + return None + + +def get_usb_state() -> list[dict]: + devices = [] + for device in usb_devices(): + vendor_id = read_int(device / "idVendor", 16) + product_id = read_int(device / "idProduct", 16) + ctrl = controller(device) + devices.append({ + "busnum": read_int(device / "busnum"), + "devnum": read_int(device / "devnum"), + "vendorId": vendor_id, + "productId": product_id, + "speedMbps": read_int(device / "speed"), + "manufacturer": read(device / "manufacturer") or "", + "product": read(device / "product") or "", + "linkErrorCount": read_int(ctrl / "portli", 0) & 0xFFFF if ctrl is not None else 0, + }) + return devices + + +def set_usb_state(device_state, devices: list[dict]) -> None: + entries = device_state.usbState.init('devices', len(devices)) + + chestnut_present = False + for entry, device in zip(entries, devices, strict=True): + entry.busnum = device["busnum"] + entry.devnum = device["devnum"] + entry.vendorId = device["vendorId"] + entry.productId = device["productId"] + entry.speedMbps = device["speedMbps"] + entry.manufacturer = device["manufacturer"] + entry.product = device["product"] + entry.linkErrorCount = device["linkErrorCount"] + + if (entry.vendorId, entry.productId) == (CHESTNUT_VENDOR_ID, CHESTNUT_PRODUCT_ID): + chestnut_present = True + + device_state.chestnutPresent = chestnut_present diff --git a/common/i2c.py b/openpilot/common/i2c.py similarity index 100% rename from common/i2c.py rename to openpilot/common/i2c.py diff --git a/openpilot/common/linux.py b/openpilot/common/linux.py new file mode 100644 index 0000000000..73ea77b509 --- /dev/null +++ b/openpilot/common/linux.py @@ -0,0 +1,50 @@ +class LinuxSystemStats: + def __init__(self) -> None: + self._last_cpu_times = self._read_cpu_times() + + @staticmethod + def _read_cpu_times() -> dict[int, tuple[int, int]]: + cpu_times = {} + with open('/proc/stat') as f: + for line in f: + name, *values = line.split() + if not name.startswith('cpu') or not name[3:].isdigit(): + continue + + times = [int(value) for value in values] + idle = sum(times[3:5]) + total = sum(times[:8]) + cpu_times[int(name[3:])] = (idle, total) + return cpu_times + + def cpu_usage_percent(self) -> list[float]: + current_cpu_times = self._read_cpu_times() + usage = [] + for cpu, (idle, total) in sorted(current_cpu_times.items()): + last_times = self._last_cpu_times.get(cpu) + if last_times is None: + usage.append(0.) + continue + + last_idle, last_total = last_times + idle_delta = idle - last_idle + total_delta = total - last_total + if idle_delta < 0 or total_delta <= 0: + usage.append(0.) + else: + usage.append(max(0., min(100., 100. * (total_delta - idle_delta) / total_delta))) + + self._last_cpu_times = current_cpu_times + return usage + + @staticmethod + def memory_usage_percent() -> float: + memory = {} + with open('/proc/meminfo') as f: + for line in f: + key, value, *_ = line.split() + if key in ('MemTotal:', 'MemAvailable:'): + memory[key] = int(value) + + total = memory['MemTotal:'] + return max(0., min(100., 100. * (total - memory['MemAvailable:']) / total)) diff --git a/common/logging_extra.py b/openpilot/common/logging_extra.py similarity index 100% rename from common/logging_extra.py rename to openpilot/common/logging_extra.py diff --git a/common/markdown.py b/openpilot/common/markdown.py similarity index 100% rename from common/markdown.py rename to openpilot/common/markdown.py diff --git a/common/mock/__init__.py b/openpilot/common/mock/__init__.py similarity index 88% rename from common/mock/__init__.py rename to openpilot/common/mock/__init__.py index 4b01dfe841..ff4dd32b92 100644 --- a/common/mock/__init__.py +++ b/openpilot/common/mock/__init__.py @@ -1,13 +1,13 @@ """ Utilities for generating mock messages for testing. -example in common/tests/test_mock.py +example in openpilot/common/tests/test_mock.py """ import functools import threading -from cereal.messaging import PubMaster -from cereal.services import SERVICE_LIST +from openpilot.cereal.messaging import PubMaster +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.mock.generators import generate_livePose from openpilot.common.realtime import Ratekeeper diff --git a/common/mock/generators.py b/openpilot/common/mock/generators.py similarity index 91% rename from common/mock/generators.py rename to openpilot/common/mock/generators.py index 5cd9c88a56..28a3b98e58 100644 --- a/common/mock/generators.py +++ b/openpilot/common/mock/generators.py @@ -1,4 +1,4 @@ -from cereal import messaging +from openpilot.cereal import messaging def generate_livePose(): diff --git a/common/parameterized.py b/openpilot/common/parameterized.py similarity index 100% rename from common/parameterized.py rename to openpilot/common/parameterized.py diff --git a/common/params.cc b/openpilot/common/params.cc similarity index 100% rename from common/params.cc rename to openpilot/common/params.cc diff --git a/common/params.h b/openpilot/common/params.h similarity index 100% rename from common/params.h rename to openpilot/common/params.h diff --git a/common/params.py b/openpilot/common/params.py similarity index 100% rename from common/params.py rename to openpilot/common/params.py diff --git a/common/params_keys.h b/openpilot/common/params_keys.h similarity index 98% rename from common/params_keys.h rename to openpilot/common/params_keys.h index 81f849b636..f5639afe5c 100644 --- a/common/params_keys.h +++ b/openpilot/common/params_keys.h @@ -3,7 +3,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" inline static std::unordered_map keys = { {"AccessToken", {CLEAR_ON_MANAGER_START | DONT_LOG, STRING}}, @@ -61,10 +61,8 @@ inline static std::unordered_map keys = { {"IsLiveStreaming", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsMetric", {PERSISTENT | BACKUP, BOOL}}, {"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}}, - {"IsOnroad", {PERSISTENT, BOOL}}, {"IsRhdDetected", {PERSISTENT, BOOL}}, {"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}}, - {"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}}, {"JoystickDebugMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}}, {"LanguageSetting", {PERSISTENT | BACKUP, STRING, "en"}}, @@ -95,7 +93,6 @@ inline static std::unordered_map keys = { {"Offroad_ConnectivityNeeded", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_ConnectivityNeededPrompt", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_ExcessiveActuation", {PERSISTENT, JSON}}, - {"Offroad_IsTakingSnapshot", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_NeosUpdate", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_NoFirmware", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}}, {"Offroad_Recalibration", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}}, diff --git a/common/params_pyx.pyx b/openpilot/common/params_pyx.pyx similarity index 100% rename from common/params_pyx.pyx rename to openpilot/common/params_pyx.pyx diff --git a/common/pid.py b/openpilot/common/pid.py similarity index 100% rename from common/pid.py rename to openpilot/common/pid.py diff --git a/common/prefix.h b/openpilot/common/prefix.h similarity index 100% rename from common/prefix.h rename to openpilot/common/prefix.h diff --git a/common/prefix.py b/openpilot/common/prefix.py similarity index 100% rename from common/prefix.py rename to openpilot/common/prefix.py diff --git a/common/queue.h b/openpilot/common/queue.h similarity index 100% rename from common/queue.h rename to openpilot/common/queue.h diff --git a/common/ratekeeper.cc b/openpilot/common/ratekeeper.cc similarity index 100% rename from common/ratekeeper.cc rename to openpilot/common/ratekeeper.cc diff --git a/common/ratekeeper.h b/openpilot/common/ratekeeper.h similarity index 100% rename from common/ratekeeper.h rename to openpilot/common/ratekeeper.h diff --git a/common/realtime.py b/openpilot/common/realtime.py similarity index 100% rename from common/realtime.py rename to openpilot/common/realtime.py diff --git a/openpilot/common/serial.py b/openpilot/common/serial.py new file mode 100644 index 0000000000..68083f40a6 --- /dev/null +++ b/openpilot/common/serial.py @@ -0,0 +1,272 @@ +import errno +import fcntl +import os +import select +import struct +import termios +import time + + +# Modem control lines (linux/termios.h); fall back to common x86_64 values. +TIOCMBIS = getattr(termios, "TIOCMBIS", 0x5416) +TIOCMBIC = getattr(termios, "TIOCMBIC", 0x5417) +TIOCM_DTR = getattr(termios, "TIOCM_DTR", 0x002) +TIOCM_RTS = getattr(termios, "TIOCM_RTS", 0x004) +_TIOCM_DTR = struct.pack("I", TIOCM_DTR) +_TIOCM_RTS = struct.pack("I", TIOCM_RTS) + + +class SerialException(OSError): + pass + + +class Serial: + def __init__(self, port: str, baudrate: int = 9600, timeout: float | None = None, *, + rtscts: bool = False, dsrdtr: bool = False, exclusive: bool = False): + self._port = port + self._baudrate = baudrate + self._timeout = timeout + self._rtscts = rtscts + self._dsrdtr = dsrdtr + self._exclusive = exclusive + self._dtr = True + self._fd = -1 + self.open() + + def __enter__(self): + return self + + def __exit__(self, *args) -> None: + self.close() + + @property + def fd(self) -> int: + self._ensure_open() + return self._fd + + @property + def baudrate(self) -> int: + return self._baudrate + + @baudrate.setter + def baudrate(self, value: int) -> None: + self._baudrate = int(value) + if self._fd >= 0: + self._configure() + + @property + def dtr(self) -> bool: + return self._dtr + + @dtr.setter + def dtr(self, value: bool) -> None: + self._dtr = bool(value) + if self._fd >= 0: + self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr) + + def open(self) -> None: + if self._fd >= 0: + return + try: + self._fd = os.open(self._port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) + except OSError as e: + self._fd = -1 + raise SerialException(e.errno, f"could not open port {self._port}: {e}") from e + + try: + if self._exclusive: + try: + fcntl.flock(self._fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except OSError as e: + raise SerialException(e.errno, f"could not exclusively lock port {self._port}: {e}") from e + + self._configure() + + # When not using hardware DSR/DTR handshaking, drive lines ourselves. + if not self._dsrdtr: + try: + self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr) + if not self._rtscts: + self._set_line(TIOCM_RTS, _TIOCM_RTS, True) + except OSError as e: + if e.errno not in (errno.EINVAL, errno.ENOTTY): + raise + + self.reset_input_buffer() + except BaseException: + self._close_fd() + raise + + def close(self) -> None: + self._close_fd() + + def read(self, size: int = 1) -> bytes: + self._ensure_open() + if size <= 0: + return b"" + + buf = bytearray() + deadline = self._deadline() + while len(buf) < size: + remaining = None if deadline is None else max(0.0, deadline - time.monotonic()) + if not self._wait_readable(remaining): + break + try: + chunk = os.read(self._fd, size - len(buf)) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + if self._timeout == 0: + break + continue + raise SerialException(e.errno, f"read failed: {e}") from e + if not chunk: + break + buf.extend(chunk) + return bytes(buf) + + def readline(self) -> bytes: + self._ensure_open() + buf = bytearray() + deadline = self._deadline() + while True: + remaining = None if deadline is None else max(0.0, deadline - time.monotonic()) + if deadline is not None and remaining == 0.0 and not buf: + # match pyserial: timed-out readline returns empty + if not self._wait_readable(0.0): + return b"" + elif not self._wait_readable(remaining): + return bytes(buf) + + try: + chunk = os.read(self._fd, 1) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + if self._timeout == 0: + return bytes(buf) + continue + raise SerialException(e.errno, f"read failed: {e}") from e + if not chunk: + return bytes(buf) + buf.extend(chunk) + if chunk == b"\n": + return bytes(buf) + + def write(self, data: bytes) -> int: + self._ensure_open() + if not data: + return 0 + view = memoryview(data) + total = 0 + while total < len(data): + try: + n = os.write(self._fd, view[total:]) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + select.select([], [self._fd], [], None) + continue + raise SerialException(e.errno, f"write failed: {e}") from e + if n == 0: + raise SerialException("write returned 0") + total += n + return total + + def flush(self) -> None: + self._ensure_open() + termios.tcdrain(self._fd) + + def reset_input_buffer(self) -> None: + self._ensure_open() + termios.tcflush(self._fd, termios.TCIFLUSH) + + def reset_output_buffer(self) -> None: + self._ensure_open() + termios.tcflush(self._fd, termios.TCOFLUSH) + + def _close_fd(self) -> None: + if self._fd >= 0: + try: + if self._exclusive: + fcntl.flock(self._fd, fcntl.LOCK_UN) + except OSError: + pass + try: + os.close(self._fd) + except OSError: + pass + self._fd = -1 + + def _ensure_open(self) -> None: + if self._fd < 0: + raise SerialException("port is not open") + + def _deadline(self) -> float | None: + if self._timeout is None: + return None + if self._timeout == 0: + return time.monotonic() + return time.monotonic() + self._timeout + + def _wait_readable(self, timeout: float | None) -> bool: + """Return True if fd is readable. timeout None blocks; 0 polls.""" + if timeout is not None and timeout < 0: + timeout = 0.0 + try: + ready, _, _ = select.select([self._fd], [], [], timeout) + except InterruptedError: + return False + return bool(ready) + + def _baud_constant(self, baudrate: int) -> int: + try: + return getattr(termios, f"B{baudrate}") + except AttributeError as e: + raise ValueError(f"unsupported baud rate: {baudrate}") from e + + def _configure(self) -> None: + self._ensure_open() + try: + attrs = termios.tcgetattr(self._fd) + except termios.error as e: + raise SerialException(f"could not get port attributes: {e}") from e + + iflag, oflag, cflag, lflag, _ispeed, _ospeed, cc = attrs + + # raw binary 8N1 + iflag = 0 + oflag = 0 + lflag = 0 + cflag |= termios.CLOCAL | termios.CREAD + cflag &= ~termios.CSIZE + cflag |= termios.CS8 + cflag &= ~(termios.PARENB | termios.PARODD | termios.CSTOPB) + + if hasattr(termios, "CRTSCTS"): + if self._rtscts: + cflag |= termios.CRTSCTS + else: + cflag &= ~termios.CRTSCTS + + speed = self._baud_constant(self._baudrate) + cc = list(cc) + # Non-blocking reads are handled via select + O_NONBLOCK; keep VMIN/VTIME at 0. + cc[termios.VMIN] = 0 + cc[termios.VTIME] = 0 + + try: + termios.tcsetattr(self._fd, termios.TCSANOW, [iflag, oflag, cflag, lflag, speed, speed, cc]) + except termios.error as e: + raise SerialException(f"could not configure port: {e}") from e + + # Keep the fd non-blocking so timeout=0 and select work consistently. + flags = fcntl.fcntl(self._fd, fcntl.F_GETFL) + fcntl.fcntl(self._fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) + + def _set_line(self, _bit: int, packed: bytes, enabled: bool) -> None: + request = TIOCMBIS if enabled else TIOCMBIC + fcntl.ioctl(self._fd, request, packed) diff --git a/common/simple_kalman.py b/openpilot/common/simple_kalman.py similarity index 100% rename from common/simple_kalman.py rename to openpilot/common/simple_kalman.py diff --git a/common/spinner.py b/openpilot/common/spinner.py similarity index 97% rename from common/spinner.py rename to openpilot/common/spinner.py index 12a816eaf8..f152285138 100755 --- a/common/spinner.py +++ b/openpilot/common/spinner.py @@ -8,7 +8,7 @@ class Spinner: try: self.spinner_proc = subprocess.Popen(["./spinner.py"], stdin=subprocess.PIPE, - cwd=os.path.join(BASEDIR, "system", "ui"), + cwd=os.path.join(BASEDIR, "openpilot/system", "ui"), close_fds=True) except OSError: self.spinner_proc = None diff --git a/common/stat_live.py b/openpilot/common/stat_live.py similarity index 100% rename from common/stat_live.py rename to openpilot/common/stat_live.py diff --git a/common/swaglog.cc b/openpilot/common/swaglog.cc similarity index 100% rename from common/swaglog.cc rename to openpilot/common/swaglog.cc diff --git a/common/swaglog.h b/openpilot/common/swaglog.h similarity index 100% rename from common/swaglog.h rename to openpilot/common/swaglog.h diff --git a/common/swaglog.py b/openpilot/common/swaglog.py similarity index 100% rename from common/swaglog.py rename to openpilot/common/swaglog.py diff --git a/common/tests/.gitignore b/openpilot/common/tests/.gitignore similarity index 100% rename from common/tests/.gitignore rename to openpilot/common/tests/.gitignore diff --git a/common/tests/__init__.py b/openpilot/common/tests/__init__.py similarity index 100% rename from common/tests/__init__.py rename to openpilot/common/tests/__init__.py diff --git a/common/tests/test_file_helpers.py b/openpilot/common/tests/test_file_helpers.py similarity index 100% rename from common/tests/test_file_helpers.py rename to openpilot/common/tests/test_file_helpers.py diff --git a/common/tests/test_markdown.py b/openpilot/common/tests/test_markdown.py similarity index 100% rename from common/tests/test_markdown.py rename to openpilot/common/tests/test_markdown.py diff --git a/common/tests/test_params.py b/openpilot/common/tests/test_params.py similarity index 100% rename from common/tests/test_params.py rename to openpilot/common/tests/test_params.py diff --git a/common/tests/test_runner.cc b/openpilot/common/tests/test_runner.cc similarity index 100% rename from common/tests/test_runner.cc rename to openpilot/common/tests/test_runner.cc diff --git a/common/tests/test_simple_kalman.py b/openpilot/common/tests/test_simple_kalman.py similarity index 100% rename from common/tests/test_simple_kalman.py rename to openpilot/common/tests/test_simple_kalman.py diff --git a/common/tests/test_swaglog.cc b/openpilot/common/tests/test_swaglog.cc similarity index 100% rename from common/tests/test_swaglog.cc rename to openpilot/common/tests/test_swaglog.cc diff --git a/common/tests/test_util.cc b/openpilot/common/tests/test_util.cc similarity index 100% rename from common/tests/test_util.cc rename to openpilot/common/tests/test_util.cc diff --git a/common/text_window.py b/openpilot/common/text_window.py similarity index 98% rename from common/text_window.py rename to openpilot/common/text_window.py index 358243d1f1..94cfa7811e 100755 --- a/common/text_window.py +++ b/openpilot/common/text_window.py @@ -10,7 +10,7 @@ class TextWindow: try: self.text_proc = subprocess.Popen(["./text.py", text], stdin=subprocess.PIPE, - cwd=os.path.join(BASEDIR, "system", "ui"), + cwd=os.path.join(BASEDIR, "openpilot/system", "ui"), close_fds=True) except OSError: self.text_proc = None diff --git a/common/time_helpers.py b/openpilot/common/time_helpers.py similarity index 100% rename from common/time_helpers.py rename to openpilot/common/time_helpers.py diff --git a/common/timeout.py b/openpilot/common/timeout.py similarity index 100% rename from common/timeout.py rename to openpilot/common/timeout.py diff --git a/common/timing.h b/openpilot/common/timing.h similarity index 100% rename from common/timing.h rename to openpilot/common/timing.h diff --git a/common/transformations/README.md b/openpilot/common/transformations/README.md similarity index 100% rename from common/transformations/README.md rename to openpilot/common/transformations/README.md diff --git a/common/transformations/__init__.py b/openpilot/common/transformations/__init__.py similarity index 100% rename from common/transformations/__init__.py rename to openpilot/common/transformations/__init__.py diff --git a/common/transformations/camera.py b/openpilot/common/transformations/camera.py similarity index 100% rename from common/transformations/camera.py rename to openpilot/common/transformations/camera.py diff --git a/common/transformations/coordinates.py b/openpilot/common/transformations/coordinates.py similarity index 100% rename from common/transformations/coordinates.py rename to openpilot/common/transformations/coordinates.py diff --git a/common/transformations/model.py b/openpilot/common/transformations/model.py similarity index 100% rename from common/transformations/model.py rename to openpilot/common/transformations/model.py diff --git a/common/transformations/orientation.py b/openpilot/common/transformations/orientation.py similarity index 95% rename from common/transformations/orientation.py rename to openpilot/common/transformations/orientation.py index 86e6a6c347..d2ccda13a5 100644 --- a/common/transformations/orientation.py +++ b/openpilot/common/transformations/orientation.py @@ -25,11 +25,10 @@ def numpy_wrap(function, input_shape, output_shape) -> Callable[..., np.ndarray] # Add empty dimension if inputs is not a list if len(shape) == len(input_shape): - inp.shape = (1, ) + inp.shape + inp = inp.reshape((1, ) + inp.shape) result = np.asarray([function(*args, i) for i in inp]) - result.shape = out_shape - return result + return result.reshape(out_shape) return f diff --git a/common/transformations/tests/__init__.py b/openpilot/common/transformations/tests/__init__.py similarity index 100% rename from common/transformations/tests/__init__.py rename to openpilot/common/transformations/tests/__init__.py diff --git a/common/transformations/tests/test_coordinates.py b/openpilot/common/transformations/tests/test_coordinates.py similarity index 100% rename from common/transformations/tests/test_coordinates.py rename to openpilot/common/transformations/tests/test_coordinates.py diff --git a/common/transformations/tests/test_orientation.py b/openpilot/common/transformations/tests/test_orientation.py similarity index 100% rename from common/transformations/tests/test_orientation.py rename to openpilot/common/transformations/tests/test_orientation.py diff --git a/common/transformations/transformations.py b/openpilot/common/transformations/transformations.py similarity index 100% rename from common/transformations/transformations.py rename to openpilot/common/transformations/transformations.py diff --git a/common/util.cc b/openpilot/common/util.cc similarity index 100% rename from common/util.cc rename to openpilot/common/util.cc diff --git a/common/util.h b/openpilot/common/util.h similarity index 100% rename from common/util.h rename to openpilot/common/util.h diff --git a/common/utils.py b/openpilot/common/utils.py similarity index 98% rename from common/utils.py rename to openpilot/common/utils.py index 183363f39d..22d024fca7 100644 --- a/common/utils.py +++ b/openpilot/common/utils.py @@ -37,13 +37,13 @@ def sudo_write(val: str, path: str) -> None: with open(path, 'w') as f: f.write(str(val)) except PermissionError: - os.system(f"sudo chmod a+w {path}") + subprocess.run(f"sudo chmod a+w {path}", shell=True) try: with open(path, 'w') as f: f.write(str(val)) except PermissionError: # fallback for debugfs files - os.system(f"sudo su -c 'echo {val} > {path}'") + subprocess.run(f"sudo su -c 'echo {val} > {path}'", shell=True) def sudo_read(path: str) -> str: diff --git a/common/version.h b/openpilot/common/version.h similarity index 100% rename from common/version.h rename to openpilot/common/version.h diff --git a/system/version.py b/openpilot/common/version.py similarity index 98% rename from system/version.py rename to openpilot/common/version.py index 2d4fc8f765..f1514aa3cd 100755 --- a/system/version.py +++ b/openpilot/common/version.py @@ -40,7 +40,7 @@ sunnylink_consent_declined: str = "-1" def get_version(path: str = BASEDIR) -> str: - with open(os.path.join(path, "sunnypilot", "common", "version.h")) as _versionf: + with open(os.path.join(path, "openpilot", "sunnypilot", "common", "version.h")) as _versionf: version = _versionf.read().split('"')[1] return version diff --git a/openpilot/common/yuv.cc b/openpilot/common/yuv.cc new file mode 100644 index 0000000000..a7a64fb594 --- /dev/null +++ b/openpilot/common/yuv.cc @@ -0,0 +1,132 @@ +#include "common/yuv.h" + +#include +#include + +namespace yuv { + +namespace { + +inline uint8_t clamp_u8(int v) { + return static_cast(std::clamp(v, 0, 255)); +} + +void copy_plane(const uint8_t *src, int src_stride, + uint8_t *dst, int dst_stride, + int width, int height) { + if (src_stride == width && dst_stride == width) { + std::memcpy(dst, src, static_cast(width) * height); + return; + } + for (int y = 0; y < height; ++y) { + std::memcpy(dst + y * dst_stride, src + y * src_stride, width); + } +} + +void scale_plane_point(const uint8_t *src, int src_stride, int src_width, int src_height, + uint8_t *dst, int dst_stride, int dst_width, int dst_height) { + if (src_width == dst_width && src_height == dst_height) { + copy_plane(src, src_stride, dst, dst_stride, dst_width, dst_height); + return; + } + for (int y = 0; y < dst_height; ++y) { + const int sy = y * src_height / dst_height; + const uint8_t *src_row = src + sy * src_stride; + uint8_t *dst_row = dst + y * dst_stride; + for (int x = 0; x < dst_width; ++x) { + dst_row[x] = src_row[x * src_width / dst_width]; + } + } +} + +// BT.601 limited range → RGB (integer form used widely, incl. similar to libyuv). +inline void yuv_to_rgb(int y, int u, int v, uint8_t *r, uint8_t *g, uint8_t *b) { + const int c = (y - 16) * 298; + const int d = u - 128; + const int e = v - 128; + *r = clamp_u8((c + 409 * e + 128) >> 8); + *g = clamp_u8((c - 100 * d - 208 * e + 128) >> 8); + *b = clamp_u8((c + 516 * d + 128) >> 8); +} + +} // namespace + +void nv12_to_i420(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int width, int height) { + copy_plane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + + const int uv_width = width / 2; + const int uv_height = height / 2; + for (int y = 0; y < uv_height; ++y) { + const uint8_t *uv = src_uv + y * src_stride_uv; + uint8_t *u = dst_u + y * dst_stride_u; + uint8_t *v = dst_v + y * dst_stride_v; + for (int x = 0; x < uv_width; ++x) { + u[x] = uv[2 * x]; + v[x] = uv[2 * x + 1]; + } + } +} + +void i420_to_nv12(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_uv, int dst_stride_uv, + int width, int height) { + copy_plane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + + const int uv_width = width / 2; + const int uv_height = height / 2; + for (int y = 0; y < uv_height; ++y) { + const uint8_t *u = src_u + y * src_stride_u; + const uint8_t *v = src_v + y * src_stride_v; + uint8_t *uv = dst_uv + y * dst_stride_uv; + for (int x = 0; x < uv_width; ++x) { + uv[2 * x] = u[x]; + uv[2 * x + 1] = v[x]; + } + } +} + +void i420_scale(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + int src_width, int src_height, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int dst_width, int dst_height) { + scale_plane_point(src_y, src_stride_y, src_width, src_height, + dst_y, dst_stride_y, dst_width, dst_height); + scale_plane_point(src_u, src_stride_u, src_width / 2, src_height / 2, + dst_u, dst_stride_u, dst_width / 2, dst_height / 2); + scale_plane_point(src_v, src_stride_v, src_width / 2, src_height / 2, + dst_v, dst_stride_v, dst_width / 2, dst_height / 2); +} + +void nv12_to_rgba(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_rgba, int dst_stride_rgba, + int width, int height) { + for (int y = 0; y < height; ++y) { + const uint8_t *y_row = src_y + y * src_stride_y; + const uint8_t *uv_row = src_uv + (y / 2) * src_stride_uv; + uint8_t *dst = dst_rgba + y * dst_stride_rgba; + for (int x = 0; x < width; ++x) { + const int uv_x = (x & ~1); + uint8_t r, g, b; + yuv_to_rgb(y_row[x], uv_row[uv_x], uv_row[uv_x + 1], &r, &g, &b); + dst[4 * x + 0] = r; + dst[4 * x + 1] = g; + dst[4 * x + 2] = b; + dst[4 * x + 3] = 255; + } + } +} + +} // namespace yuv diff --git a/openpilot/common/yuv.h b/openpilot/common/yuv.h new file mode 100644 index 0000000000..7ab096f764 --- /dev/null +++ b/openpilot/common/yuv.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +// NV12: Y plane + interleaved UV. I420: planar Y, U, V. + +namespace yuv { + +// Deinterleave NV12 UV into planar I420. +void nv12_to_i420(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int width, int height); + +// Interleave planar I420 UV into NV12. +void i420_to_nv12(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_uv, int dst_stride_uv, + int width, int height); + +// Point-sample scale I420 (equivalent to libyuv::I420Scale + kFilterNone). +void i420_scale(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + int src_width, int src_height, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int dst_width, int dst_height); + +// Convert NV12 to packed RGBA (R,G,B,A bytes — suitable for GL_RGBA). +// BT.601 limited-range, matching common libyuv defaults. +void nv12_to_rgba(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_rgba, int dst_stride_rgba, + int width, int height); + +} diff --git a/openpilot/selfdrive b/openpilot/selfdrive deleted file mode 120000 index e005fd0d04..0000000000 --- a/openpilot/selfdrive +++ /dev/null @@ -1 +0,0 @@ -../selfdrive/ \ No newline at end of file diff --git a/selfdrive/__init__.py b/openpilot/selfdrive/__init__.py similarity index 100% rename from selfdrive/__init__.py rename to openpilot/selfdrive/__init__.py diff --git a/selfdrive/assets/.gitignore b/openpilot/selfdrive/assets/.gitignore similarity index 100% rename from selfdrive/assets/.gitignore rename to openpilot/selfdrive/assets/.gitignore diff --git a/selfdrive/assets/assets.qrc b/openpilot/selfdrive/assets/assets.qrc similarity index 100% rename from selfdrive/assets/assets.qrc rename to openpilot/selfdrive/assets/assets.qrc diff --git a/selfdrive/assets/body/awake.gif b/openpilot/selfdrive/assets/body/awake.gif similarity index 100% rename from selfdrive/assets/body/awake.gif rename to openpilot/selfdrive/assets/body/awake.gif diff --git a/selfdrive/assets/body/sleep.gif b/openpilot/selfdrive/assets/body/sleep.gif similarity index 100% rename from selfdrive/assets/body/sleep.gif rename to openpilot/selfdrive/assets/body/sleep.gif diff --git a/selfdrive/assets/compress-images.sh b/openpilot/selfdrive/assets/compress-images.sh similarity index 100% rename from selfdrive/assets/compress-images.sh rename to openpilot/selfdrive/assets/compress-images.sh diff --git a/selfdrive/assets/fonts/Audiowide-Regular.ttf b/openpilot/selfdrive/assets/fonts/Audiowide-Regular.ttf similarity index 100% rename from selfdrive/assets/fonts/Audiowide-Regular.ttf rename to openpilot/selfdrive/assets/fonts/Audiowide-Regular.ttf diff --git a/selfdrive/assets/fonts/Inter-Black.ttf b/openpilot/selfdrive/assets/fonts/Inter-Black.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Black.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Black.ttf diff --git a/selfdrive/assets/fonts/Inter-Bold.ttf b/openpilot/selfdrive/assets/fonts/Inter-Bold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Bold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Bold.ttf diff --git a/selfdrive/assets/fonts/Inter-ExtraBold.ttf b/openpilot/selfdrive/assets/fonts/Inter-ExtraBold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-ExtraBold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-ExtraBold.ttf diff --git a/selfdrive/assets/fonts/Inter-ExtraLight.ttf b/openpilot/selfdrive/assets/fonts/Inter-ExtraLight.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-ExtraLight.ttf rename to openpilot/selfdrive/assets/fonts/Inter-ExtraLight.ttf diff --git a/selfdrive/assets/fonts/Inter-Light.ttf b/openpilot/selfdrive/assets/fonts/Inter-Light.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Light.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Light.ttf diff --git a/selfdrive/assets/fonts/Inter-Medium.ttf b/openpilot/selfdrive/assets/fonts/Inter-Medium.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Medium.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Medium.ttf diff --git a/selfdrive/assets/fonts/Inter-Regular.ttf b/openpilot/selfdrive/assets/fonts/Inter-Regular.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Regular.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Regular.ttf diff --git a/selfdrive/assets/fonts/Inter-SemiBold.ttf b/openpilot/selfdrive/assets/fonts/Inter-SemiBold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-SemiBold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-SemiBold.ttf diff --git a/selfdrive/assets/fonts/Inter-Thin.ttf b/openpilot/selfdrive/assets/fonts/Inter-Thin.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Thin.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Thin.ttf diff --git a/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf b/openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf similarity index 100% rename from selfdrive/assets/fonts/JetBrainsMono-Medium.ttf rename to openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf diff --git a/selfdrive/assets/fonts/NotoColorEmoji.ttf b/openpilot/selfdrive/assets/fonts/NotoColorEmoji.ttf similarity index 100% rename from selfdrive/assets/fonts/NotoColorEmoji.ttf rename to openpilot/selfdrive/assets/fonts/NotoColorEmoji.ttf diff --git a/selfdrive/assets/fonts/process.py b/openpilot/selfdrive/assets/fonts/process.py similarity index 100% rename from selfdrive/assets/fonts/process.py rename to openpilot/selfdrive/assets/fonts/process.py diff --git a/selfdrive/assets/fonts/unifont.otf b/openpilot/selfdrive/assets/fonts/unifont.otf similarity index 100% rename from selfdrive/assets/fonts/unifont.otf rename to openpilot/selfdrive/assets/fonts/unifont.otf diff --git a/selfdrive/assets/icons/arrow-right.png b/openpilot/selfdrive/assets/icons/arrow-right.png similarity index 100% rename from selfdrive/assets/icons/arrow-right.png rename to openpilot/selfdrive/assets/icons/arrow-right.png diff --git a/selfdrive/assets/icons/backspace.png b/openpilot/selfdrive/assets/icons/backspace.png similarity index 100% rename from selfdrive/assets/icons/backspace.png rename to openpilot/selfdrive/assets/icons/backspace.png diff --git a/selfdrive/assets/icons/calibration.png b/openpilot/selfdrive/assets/icons/calibration.png similarity index 100% rename from selfdrive/assets/icons/calibration.png rename to openpilot/selfdrive/assets/icons/calibration.png diff --git a/selfdrive/assets/icons/capslock-fill.png b/openpilot/selfdrive/assets/icons/capslock-fill.png similarity index 100% rename from selfdrive/assets/icons/capslock-fill.png rename to openpilot/selfdrive/assets/icons/capslock-fill.png diff --git a/selfdrive/assets/icons/checkmark.png b/openpilot/selfdrive/assets/icons/checkmark.png similarity index 100% rename from selfdrive/assets/icons/checkmark.png rename to openpilot/selfdrive/assets/icons/checkmark.png diff --git a/selfdrive/assets/icons/checkmark.svg b/openpilot/selfdrive/assets/icons/checkmark.svg similarity index 100% rename from selfdrive/assets/icons/checkmark.svg rename to openpilot/selfdrive/assets/icons/checkmark.svg diff --git a/selfdrive/assets/icons/chevron_right.png b/openpilot/selfdrive/assets/icons/chevron_right.png similarity index 100% rename from selfdrive/assets/icons/chevron_right.png rename to openpilot/selfdrive/assets/icons/chevron_right.png diff --git a/selfdrive/assets/icons/chffr_wheel.png b/openpilot/selfdrive/assets/icons/chffr_wheel.png similarity index 100% rename from selfdrive/assets/icons/chffr_wheel.png rename to openpilot/selfdrive/assets/icons/chffr_wheel.png diff --git a/selfdrive/assets/icons/circled_check.png b/openpilot/selfdrive/assets/icons/circled_check.png similarity index 100% rename from selfdrive/assets/icons/circled_check.png rename to openpilot/selfdrive/assets/icons/circled_check.png diff --git a/selfdrive/assets/icons/circled_check.svg b/openpilot/selfdrive/assets/icons/circled_check.svg similarity index 100% rename from selfdrive/assets/icons/circled_check.svg rename to openpilot/selfdrive/assets/icons/circled_check.svg diff --git a/selfdrive/assets/icons/circled_slash.png b/openpilot/selfdrive/assets/icons/circled_slash.png similarity index 100% rename from selfdrive/assets/icons/circled_slash.png rename to openpilot/selfdrive/assets/icons/circled_slash.png diff --git a/selfdrive/assets/icons/circled_slash.svg b/openpilot/selfdrive/assets/icons/circled_slash.svg similarity index 100% rename from selfdrive/assets/icons/circled_slash.svg rename to openpilot/selfdrive/assets/icons/circled_slash.svg diff --git a/selfdrive/assets/icons/close.png b/openpilot/selfdrive/assets/icons/close.png similarity index 100% rename from selfdrive/assets/icons/close.png rename to openpilot/selfdrive/assets/icons/close.png diff --git a/selfdrive/assets/icons/close.svg b/openpilot/selfdrive/assets/icons/close.svg similarity index 100% rename from selfdrive/assets/icons/close.svg rename to openpilot/selfdrive/assets/icons/close.svg diff --git a/selfdrive/assets/icons/close2.png b/openpilot/selfdrive/assets/icons/close2.png similarity index 100% rename from selfdrive/assets/icons/close2.png rename to openpilot/selfdrive/assets/icons/close2.png diff --git a/selfdrive/assets/icons/close2.svg b/openpilot/selfdrive/assets/icons/close2.svg similarity index 100% rename from selfdrive/assets/icons/close2.svg rename to openpilot/selfdrive/assets/icons/close2.svg diff --git a/selfdrive/assets/icons/couch.png b/openpilot/selfdrive/assets/icons/couch.png similarity index 100% rename from selfdrive/assets/icons/couch.png rename to openpilot/selfdrive/assets/icons/couch.png diff --git a/selfdrive/assets/icons/couch.svg b/openpilot/selfdrive/assets/icons/couch.svg similarity index 100% rename from selfdrive/assets/icons/couch.svg rename to openpilot/selfdrive/assets/icons/couch.svg diff --git a/selfdrive/assets/icons/disengage_on_accelerator.png b/openpilot/selfdrive/assets/icons/disengage_on_accelerator.png similarity index 100% rename from selfdrive/assets/icons/disengage_on_accelerator.png rename to openpilot/selfdrive/assets/icons/disengage_on_accelerator.png diff --git a/selfdrive/assets/icons/disengage_on_accelerator.svg b/openpilot/selfdrive/assets/icons/disengage_on_accelerator.svg similarity index 100% rename from selfdrive/assets/icons/disengage_on_accelerator.svg rename to openpilot/selfdrive/assets/icons/disengage_on_accelerator.svg diff --git a/selfdrive/assets/icons/driver_face.png b/openpilot/selfdrive/assets/icons/driver_face.png similarity index 100% rename from selfdrive/assets/icons/driver_face.png rename to openpilot/selfdrive/assets/icons/driver_face.png diff --git a/selfdrive/assets/icons/experimental.png b/openpilot/selfdrive/assets/icons/experimental.png similarity index 100% rename from selfdrive/assets/icons/experimental.png rename to openpilot/selfdrive/assets/icons/experimental.png diff --git a/selfdrive/assets/icons/experimental.svg b/openpilot/selfdrive/assets/icons/experimental.svg similarity index 100% rename from selfdrive/assets/icons/experimental.svg rename to openpilot/selfdrive/assets/icons/experimental.svg diff --git a/selfdrive/assets/icons/experimental_grey.png b/openpilot/selfdrive/assets/icons/experimental_grey.png similarity index 100% rename from selfdrive/assets/icons/experimental_grey.png rename to openpilot/selfdrive/assets/icons/experimental_grey.png diff --git a/selfdrive/assets/icons/experimental_grey.svg b/openpilot/selfdrive/assets/icons/experimental_grey.svg similarity index 100% rename from selfdrive/assets/icons/experimental_grey.svg rename to openpilot/selfdrive/assets/icons/experimental_grey.svg diff --git a/selfdrive/assets/icons/experimental_white.png b/openpilot/selfdrive/assets/icons/experimental_white.png similarity index 100% rename from selfdrive/assets/icons/experimental_white.png rename to openpilot/selfdrive/assets/icons/experimental_white.png diff --git a/selfdrive/assets/icons/experimental_white.svg b/openpilot/selfdrive/assets/icons/experimental_white.svg similarity index 100% rename from selfdrive/assets/icons/experimental_white.svg rename to openpilot/selfdrive/assets/icons/experimental_white.svg diff --git a/selfdrive/assets/icons/eye_closed.png b/openpilot/selfdrive/assets/icons/eye_closed.png similarity index 100% rename from selfdrive/assets/icons/eye_closed.png rename to openpilot/selfdrive/assets/icons/eye_closed.png diff --git a/selfdrive/assets/icons/eye_closed.svg b/openpilot/selfdrive/assets/icons/eye_closed.svg similarity index 100% rename from selfdrive/assets/icons/eye_closed.svg rename to openpilot/selfdrive/assets/icons/eye_closed.svg diff --git a/selfdrive/assets/icons/eye_open.png b/openpilot/selfdrive/assets/icons/eye_open.png similarity index 100% rename from selfdrive/assets/icons/eye_open.png rename to openpilot/selfdrive/assets/icons/eye_open.png diff --git a/selfdrive/assets/icons/eye_open.svg b/openpilot/selfdrive/assets/icons/eye_open.svg similarity index 100% rename from selfdrive/assets/icons/eye_open.svg rename to openpilot/selfdrive/assets/icons/eye_open.svg diff --git a/selfdrive/assets/icons/eyes_crossed.png b/openpilot/selfdrive/assets/icons/eyes_crossed.png similarity index 100% rename from selfdrive/assets/icons/eyes_crossed.png rename to openpilot/selfdrive/assets/icons/eyes_crossed.png diff --git a/selfdrive/assets/icons/eyes_open.png b/openpilot/selfdrive/assets/icons/eyes_open.png similarity index 100% rename from selfdrive/assets/icons/eyes_open.png rename to openpilot/selfdrive/assets/icons/eyes_open.png diff --git a/selfdrive/assets/icons/link.png b/openpilot/selfdrive/assets/icons/link.png similarity index 100% rename from selfdrive/assets/icons/link.png rename to openpilot/selfdrive/assets/icons/link.png diff --git a/selfdrive/assets/icons/lock_closed.png b/openpilot/selfdrive/assets/icons/lock_closed.png similarity index 100% rename from selfdrive/assets/icons/lock_closed.png rename to openpilot/selfdrive/assets/icons/lock_closed.png diff --git a/selfdrive/assets/icons/lock_closed.svg b/openpilot/selfdrive/assets/icons/lock_closed.svg similarity index 100% rename from selfdrive/assets/icons/lock_closed.svg rename to openpilot/selfdrive/assets/icons/lock_closed.svg diff --git a/selfdrive/assets/icons/menu.png b/openpilot/selfdrive/assets/icons/menu.png similarity index 100% rename from selfdrive/assets/icons/menu.png rename to openpilot/selfdrive/assets/icons/menu.png diff --git a/selfdrive/assets/icons/metric.png b/openpilot/selfdrive/assets/icons/metric.png similarity index 100% rename from selfdrive/assets/icons/metric.png rename to openpilot/selfdrive/assets/icons/metric.png diff --git a/selfdrive/assets/icons/microphone.png b/openpilot/selfdrive/assets/icons/microphone.png similarity index 100% rename from selfdrive/assets/icons/microphone.png rename to openpilot/selfdrive/assets/icons/microphone.png diff --git a/selfdrive/assets/icons/minus.png b/openpilot/selfdrive/assets/icons/minus.png similarity index 100% rename from selfdrive/assets/icons/minus.png rename to openpilot/selfdrive/assets/icons/minus.png diff --git a/selfdrive/assets/icons/monitoring.png b/openpilot/selfdrive/assets/icons/monitoring.png similarity index 100% rename from selfdrive/assets/icons/monitoring.png rename to openpilot/selfdrive/assets/icons/monitoring.png diff --git a/selfdrive/assets/icons/network.png b/openpilot/selfdrive/assets/icons/network.png similarity index 100% rename from selfdrive/assets/icons/network.png rename to openpilot/selfdrive/assets/icons/network.png diff --git a/selfdrive/assets/icons/road.png b/openpilot/selfdrive/assets/icons/road.png similarity index 100% rename from selfdrive/assets/icons/road.png rename to openpilot/selfdrive/assets/icons/road.png diff --git a/selfdrive/assets/icons/settings.png b/openpilot/selfdrive/assets/icons/settings.png similarity index 100% rename from selfdrive/assets/icons/settings.png rename to openpilot/selfdrive/assets/icons/settings.png diff --git a/selfdrive/assets/icons/shell.png b/openpilot/selfdrive/assets/icons/shell.png similarity index 100% rename from selfdrive/assets/icons/shell.png rename to openpilot/selfdrive/assets/icons/shell.png diff --git a/selfdrive/assets/icons/shift-fill.png b/openpilot/selfdrive/assets/icons/shift-fill.png similarity index 100% rename from selfdrive/assets/icons/shift-fill.png rename to openpilot/selfdrive/assets/icons/shift-fill.png diff --git a/selfdrive/assets/icons/shift.png b/openpilot/selfdrive/assets/icons/shift.png similarity index 100% rename from selfdrive/assets/icons/shift.png rename to openpilot/selfdrive/assets/icons/shift.png diff --git a/selfdrive/assets/icons/speed_limit.png b/openpilot/selfdrive/assets/icons/speed_limit.png similarity index 100% rename from selfdrive/assets/icons/speed_limit.png rename to openpilot/selfdrive/assets/icons/speed_limit.png diff --git a/selfdrive/assets/icons/triangle.png b/openpilot/selfdrive/assets/icons/triangle.png similarity index 100% rename from selfdrive/assets/icons/triangle.png rename to openpilot/selfdrive/assets/icons/triangle.png diff --git a/selfdrive/assets/icons/triangle.svg b/openpilot/selfdrive/assets/icons/triangle.svg similarity index 100% rename from selfdrive/assets/icons/triangle.svg rename to openpilot/selfdrive/assets/icons/triangle.svg diff --git a/selfdrive/assets/icons/warning.png b/openpilot/selfdrive/assets/icons/warning.png similarity index 100% rename from selfdrive/assets/icons/warning.png rename to openpilot/selfdrive/assets/icons/warning.png diff --git a/selfdrive/assets/icons/wifi_strength_full.png b/openpilot/selfdrive/assets/icons/wifi_strength_full.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_full.png rename to openpilot/selfdrive/assets/icons/wifi_strength_full.png diff --git a/selfdrive/assets/icons/wifi_strength_full.svg b/openpilot/selfdrive/assets/icons/wifi_strength_full.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_full.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_full.svg diff --git a/selfdrive/assets/icons/wifi_strength_high.png b/openpilot/selfdrive/assets/icons/wifi_strength_high.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_high.png rename to openpilot/selfdrive/assets/icons/wifi_strength_high.png diff --git a/selfdrive/assets/icons/wifi_strength_high.svg b/openpilot/selfdrive/assets/icons/wifi_strength_high.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_high.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_high.svg diff --git a/selfdrive/assets/icons/wifi_strength_low.png b/openpilot/selfdrive/assets/icons/wifi_strength_low.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_low.png rename to openpilot/selfdrive/assets/icons/wifi_strength_low.png diff --git a/selfdrive/assets/icons/wifi_strength_low.svg b/openpilot/selfdrive/assets/icons/wifi_strength_low.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_low.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_low.svg diff --git a/selfdrive/assets/icons/wifi_strength_medium.png b/openpilot/selfdrive/assets/icons/wifi_strength_medium.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_medium.png rename to openpilot/selfdrive/assets/icons/wifi_strength_medium.png diff --git a/selfdrive/assets/icons/wifi_strength_medium.svg b/openpilot/selfdrive/assets/icons/wifi_strength_medium.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_medium.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_medium.svg diff --git a/selfdrive/assets/icons/wifi_uploading.png b/openpilot/selfdrive/assets/icons/wifi_uploading.png similarity index 100% rename from selfdrive/assets/icons/wifi_uploading.png rename to openpilot/selfdrive/assets/icons/wifi_uploading.png diff --git a/selfdrive/assets/icons/wifi_uploading.svg b/openpilot/selfdrive/assets/icons/wifi_uploading.svg similarity index 100% rename from selfdrive/assets/icons/wifi_uploading.svg rename to openpilot/selfdrive/assets/icons/wifi_uploading.svg diff --git a/selfdrive/assets/icons_mici/adb_short.png b/openpilot/selfdrive/assets/icons_mici/adb_short.png similarity index 100% rename from selfdrive/assets/icons_mici/adb_short.png rename to openpilot/selfdrive/assets/icons_mici/adb_short.png diff --git a/selfdrive/assets/icons_mici/alerts_bell.png b/openpilot/selfdrive/assets/icons_mici/alerts_bell.png similarity index 100% rename from selfdrive/assets/icons_mici/alerts_bell.png rename to openpilot/selfdrive/assets/icons_mici/alerts_bell.png diff --git a/selfdrive/assets/icons_mici/alerts_pill.png b/openpilot/selfdrive/assets/icons_mici/alerts_pill.png similarity index 100% rename from selfdrive/assets/icons_mici/alerts_pill.png rename to openpilot/selfdrive/assets/icons_mici/alerts_pill.png diff --git a/selfdrive/assets/icons_mici/body.png b/openpilot/selfdrive/assets/icons_mici/body.png similarity index 100% rename from selfdrive/assets/icons_mici/body.png rename to openpilot/selfdrive/assets/icons_mici/body.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_red.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_red.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/slider_bg.png b/openpilot/selfdrive/assets/icons_mici/buttons/slider_bg.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/slider_bg.png rename to openpilot/selfdrive/assets/icons_mici/buttons/slider_bg.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png diff --git a/selfdrive/assets/icons_mici/egpu.png b/openpilot/selfdrive/assets/icons_mici/egpu.png similarity index 100% rename from selfdrive/assets/icons_mici/egpu.png rename to openpilot/selfdrive/assets/icons_mici/egpu.png diff --git a/selfdrive/assets/icons_mici/egpu_gray.png b/openpilot/selfdrive/assets/icons_mici/egpu_gray.png similarity index 100% rename from selfdrive/assets/icons_mici/egpu_gray.png rename to openpilot/selfdrive/assets/icons_mici/egpu_gray.png diff --git a/selfdrive/assets/icons_mici/exclamation_point.png b/openpilot/selfdrive/assets/icons_mici/exclamation_point.png similarity index 100% rename from selfdrive/assets/icons_mici/exclamation_point.png rename to openpilot/selfdrive/assets/icons_mici/exclamation_point.png diff --git a/selfdrive/assets/icons_mici/experimental_mode.png b/openpilot/selfdrive/assets/icons_mici/experimental_mode.png similarity index 100% rename from selfdrive/assets/icons_mici/experimental_mode.png rename to openpilot/selfdrive/assets/icons_mici/experimental_mode.png diff --git a/selfdrive/assets/icons_mici/microphone.png b/openpilot/selfdrive/assets/icons_mici/microphone.png similarity index 100% rename from selfdrive/assets/icons_mici/microphone.png rename to openpilot/selfdrive/assets/icons_mici/microphone.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/big_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/red_warning.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/small_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/onroad/blind_spot_left.png b/openpilot/selfdrive/assets/icons_mici/onroad/blind_spot_left.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/blind_spot_left.png rename to openpilot/selfdrive/assets/icons_mici/onroad/blind_spot_left.png diff --git a/selfdrive/assets/icons_mici/onroad/bookmark.png b/openpilot/selfdrive/assets/icons_mici/onroad/bookmark.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/bookmark.png rename to openpilot/selfdrive/assets/icons_mici/onroad/bookmark.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png diff --git a/selfdrive/assets/icons_mici/onroad/eye_fill.png b/openpilot/selfdrive/assets/icons_mici/onroad/eye_fill.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/eye_fill.png rename to openpilot/selfdrive/assets/icons_mici/onroad/eye_fill.png diff --git a/selfdrive/assets/icons_mici/onroad/eye_orange.png b/openpilot/selfdrive/assets/icons_mici/onroad/eye_orange.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/eye_orange.png rename to openpilot/selfdrive/assets/icons_mici/onroad/eye_orange.png diff --git a/selfdrive/assets/icons_mici/onroad/glasses.png b/openpilot/selfdrive/assets/icons_mici/onroad/glasses.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/glasses.png rename to openpilot/selfdrive/assets/icons_mici/onroad/glasses.png diff --git a/selfdrive/assets/icons_mici/onroad/onroad_fade.png b/openpilot/selfdrive/assets/icons_mici/onroad/onroad_fade.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/onroad_fade.png rename to openpilot/selfdrive/assets/icons_mici/onroad/onroad_fade.png diff --git a/selfdrive/assets/icons_mici/onroad/turn_signal_left.png b/openpilot/selfdrive/assets/icons_mici/onroad/turn_signal_left.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/turn_signal_left.png rename to openpilot/selfdrive/assets/icons_mici/onroad/turn_signal_left.png diff --git a/selfdrive/assets/icons_mici/settings.png b/openpilot/selfdrive/assets/icons_mici/settings.png similarity index 100% rename from selfdrive/assets/icons_mici/settings.png rename to openpilot/selfdrive/assets/icons_mici/settings.png diff --git a/selfdrive/assets/icons_mici/settings/comma_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/comma_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/comma_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/comma_icon.png diff --git a/selfdrive/assets/icons_mici/settings/developer/ssh.png b/openpilot/selfdrive/assets/icons_mici/settings/developer/ssh.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/developer/ssh.png rename to openpilot/selfdrive/assets/icons_mici/settings/developer/ssh.png diff --git a/selfdrive/assets/icons_mici/settings/developer_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/developer_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/developer_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/developer_icon.png diff --git a/selfdrive/assets/icons_mici/settings/device/cameras.png b/openpilot/selfdrive/assets/icons_mici/settings/device/cameras.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/cameras.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/cameras.png diff --git a/selfdrive/assets/icons_mici/settings/device/fcc_logo.png b/openpilot/selfdrive/assets/icons_mici/settings/device/fcc_logo.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/fcc_logo.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/fcc_logo.png diff --git a/selfdrive/assets/icons_mici/settings/device/info.png b/openpilot/selfdrive/assets/icons_mici/settings/device/info.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/info.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/info.png diff --git a/selfdrive/assets/icons_mici/settings/device/lkas.png b/openpilot/selfdrive/assets/icons_mici/settings/device/lkas.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/lkas.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/lkas.png diff --git a/selfdrive/assets/icons_mici/settings/device/pair.png b/openpilot/selfdrive/assets/icons_mici/settings/device/pair.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/pair.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/pair.png diff --git a/selfdrive/assets/icons_mici/settings/device/power.png b/openpilot/selfdrive/assets/icons_mici/settings/device/power.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/power.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/power.png diff --git a/selfdrive/assets/icons_mici/settings/device/reboot.png b/openpilot/selfdrive/assets/icons_mici/settings/device/reboot.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/reboot.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/reboot.png diff --git a/selfdrive/assets/icons_mici/settings/device/uninstall.png b/openpilot/selfdrive/assets/icons_mici/settings/device/uninstall.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/uninstall.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/uninstall.png diff --git a/selfdrive/assets/icons_mici/settings/device/up_to_date.png b/openpilot/selfdrive/assets/icons_mici/settings/device/up_to_date.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/up_to_date.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/up_to_date.png diff --git a/selfdrive/assets/icons_mici/settings/device/update.png b/openpilot/selfdrive/assets/icons_mici/settings/device/update.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/update.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/update.png diff --git a/selfdrive/assets/icons_mici/settings/device_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/device_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/device_icon.png diff --git a/selfdrive/assets/icons_mici/settings/firehose.png b/openpilot/selfdrive/assets/icons_mici/settings/firehose.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/firehose.png rename to openpilot/selfdrive/assets/icons_mici/settings/firehose.png diff --git a/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png b/openpilot/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png rename to openpilot/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/backspace.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/backspace.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/backspace.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/backspace.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/enter.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/enter.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/space.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/space.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/space.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/space.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_full.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_high.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_low.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_none.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/forget_button.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/forget_button.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/lock.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/lock.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/lock.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/lock.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/trash.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/trash.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/trash.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/trash.png diff --git a/selfdrive/assets/icons_mici/settings/network/tethering.png b/openpilot/selfdrive/assets/icons_mici/settings/network/tethering.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/tethering.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/tethering.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png diff --git a/selfdrive/assets/icons_mici/settings/software.png b/openpilot/selfdrive/assets/icons_mici/settings/software.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/software.png rename to openpilot/selfdrive/assets/icons_mici/settings/software.png diff --git a/selfdrive/assets/icons_mici/setup/cancel.png b/openpilot/selfdrive/assets/icons_mici/setup/cancel.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/cancel.png rename to openpilot/selfdrive/assets/icons_mici/setup/cancel.png diff --git a/selfdrive/assets/icons_mici/setup/continue.png b/openpilot/selfdrive/assets/icons_mici/setup/continue.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue.png diff --git a/selfdrive/assets/icons_mici/setup/continue_disabled.png b/openpilot/selfdrive/assets/icons_mici/setup/continue_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue_disabled.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue_disabled.png diff --git a/selfdrive/assets/icons_mici/setup/continue_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/continue_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png b/openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png rename to openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png diff --git a/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png b/openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png rename to openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png diff --git a/selfdrive/assets/icons_mici/setup/factory_reset.png b/openpilot/selfdrive/assets/icons_mici/setup/factory_reset.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/factory_reset.png rename to openpilot/selfdrive/assets/icons_mici/setup/factory_reset.png diff --git a/selfdrive/assets/icons_mici/setup/green_dm.png b/openpilot/selfdrive/assets/icons_mici/setup/green_dm.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/green_dm.png rename to openpilot/selfdrive/assets/icons_mici/setup/green_dm.png diff --git a/selfdrive/assets/icons_mici/setup/green_info.png b/openpilot/selfdrive/assets/icons_mici/setup/green_info.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/green_info.png rename to openpilot/selfdrive/assets/icons_mici/setup/green_info.png diff --git a/selfdrive/assets/icons_mici/setup/orange_dm.png b/openpilot/selfdrive/assets/icons_mici/setup/orange_dm.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/orange_dm.png rename to openpilot/selfdrive/assets/icons_mici/setup/orange_dm.png diff --git a/selfdrive/assets/icons_mici/setup/red_warning.png b/openpilot/selfdrive/assets/icons_mici/setup/red_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/red_warning.png rename to openpilot/selfdrive/assets/icons_mici/setup/red_warning.png diff --git a/selfdrive/assets/icons_mici/setup/reset_failed.png b/openpilot/selfdrive/assets/icons_mici/setup/reset_failed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/reset_failed.png rename to openpilot/selfdrive/assets/icons_mici/setup/reset_failed.png diff --git a/selfdrive/assets/icons_mici/setup/restore.png b/openpilot/selfdrive/assets/icons_mici/setup/restore.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/restore.png rename to openpilot/selfdrive/assets/icons_mici/setup/restore.png diff --git a/selfdrive/assets/icons_mici/setup/small_button.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button.png diff --git a/selfdrive/assets/icons_mici/setup/small_button_disabled.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button_disabled.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button_disabled.png diff --git a/selfdrive/assets/icons_mici/setup/small_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/start_button.png b/openpilot/selfdrive/assets/icons_mici/setup/start_button.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/start_button.png rename to openpilot/selfdrive/assets/icons_mici/setup/start_button.png diff --git a/selfdrive/assets/icons_mici/setup/start_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/start_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/start_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/start_button_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/warning.png b/openpilot/selfdrive/assets/icons_mici/setup/warning.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/warning.png rename to openpilot/selfdrive/assets/icons_mici/setup/warning.png diff --git a/selfdrive/assets/icons_mici/ssh_short.png b/openpilot/selfdrive/assets/icons_mici/ssh_short.png similarity index 100% rename from selfdrive/assets/icons_mici/ssh_short.png rename to openpilot/selfdrive/assets/icons_mici/ssh_short.png diff --git a/selfdrive/assets/icons_mici/turn_intent_left.png b/openpilot/selfdrive/assets/icons_mici/turn_intent_left.png similarity index 100% rename from selfdrive/assets/icons_mici/turn_intent_left.png rename to openpilot/selfdrive/assets/icons_mici/turn_intent_left.png diff --git a/selfdrive/assets/icons_mici/wheel.png b/openpilot/selfdrive/assets/icons_mici/wheel.png similarity index 100% rename from selfdrive/assets/icons_mici/wheel.png rename to openpilot/selfdrive/assets/icons_mici/wheel.png diff --git a/selfdrive/assets/icons_mici/wheel_critical.png b/openpilot/selfdrive/assets/icons_mici/wheel_critical.png similarity index 100% rename from selfdrive/assets/icons_mici/wheel_critical.png rename to openpilot/selfdrive/assets/icons_mici/wheel_critical.png diff --git a/selfdrive/assets/images/button_continue_triangle.png b/openpilot/selfdrive/assets/images/button_continue_triangle.png similarity index 100% rename from selfdrive/assets/images/button_continue_triangle.png rename to openpilot/selfdrive/assets/images/button_continue_triangle.png diff --git a/selfdrive/assets/images/button_continue_triangle.svg b/openpilot/selfdrive/assets/images/button_continue_triangle.svg similarity index 100% rename from selfdrive/assets/images/button_continue_triangle.svg rename to openpilot/selfdrive/assets/images/button_continue_triangle.svg diff --git a/selfdrive/assets/images/button_flag.png b/openpilot/selfdrive/assets/images/button_flag.png similarity index 100% rename from selfdrive/assets/images/button_flag.png rename to openpilot/selfdrive/assets/images/button_flag.png diff --git a/selfdrive/assets/images/button_home.png b/openpilot/selfdrive/assets/images/button_home.png similarity index 100% rename from selfdrive/assets/images/button_home.png rename to openpilot/selfdrive/assets/images/button_home.png diff --git a/selfdrive/assets/images/button_settings.png b/openpilot/selfdrive/assets/images/button_settings.png similarity index 100% rename from selfdrive/assets/images/button_settings.png rename to openpilot/selfdrive/assets/images/button_settings.png diff --git a/selfdrive/assets/images/spinner_comma.png b/openpilot/selfdrive/assets/images/spinner_comma.png similarity index 100% rename from selfdrive/assets/images/spinner_comma.png rename to openpilot/selfdrive/assets/images/spinner_comma.png diff --git a/selfdrive/assets/images/spinner_track.png b/openpilot/selfdrive/assets/images/spinner_track.png similarity index 100% rename from selfdrive/assets/images/spinner_track.png rename to openpilot/selfdrive/assets/images/spinner_track.png diff --git a/selfdrive/assets/offroad/fcc.html b/openpilot/selfdrive/assets/offroad/fcc.html similarity index 100% rename from selfdrive/assets/offroad/fcc.html rename to openpilot/selfdrive/assets/offroad/fcc.html diff --git a/selfdrive/assets/offroad/mici_fcc.html b/openpilot/selfdrive/assets/offroad/mici_fcc.html similarity index 100% rename from selfdrive/assets/offroad/mici_fcc.html rename to openpilot/selfdrive/assets/offroad/mici_fcc.html diff --git a/selfdrive/assets/prep-svg.sh b/openpilot/selfdrive/assets/prep-svg.sh similarity index 100% rename from selfdrive/assets/prep-svg.sh rename to openpilot/selfdrive/assets/prep-svg.sh diff --git a/selfdrive/assets/sounds/disengage.wav b/openpilot/selfdrive/assets/sounds/disengage.wav similarity index 100% rename from selfdrive/assets/sounds/disengage.wav rename to openpilot/selfdrive/assets/sounds/disengage.wav diff --git a/selfdrive/assets/sounds/disengage_tizi.wav b/openpilot/selfdrive/assets/sounds/disengage_tizi.wav similarity index 100% rename from selfdrive/assets/sounds/disengage_tizi.wav rename to openpilot/selfdrive/assets/sounds/disengage_tizi.wav diff --git a/selfdrive/assets/sounds/engage.wav b/openpilot/selfdrive/assets/sounds/engage.wav similarity index 100% rename from selfdrive/assets/sounds/engage.wav rename to openpilot/selfdrive/assets/sounds/engage.wav diff --git a/selfdrive/assets/sounds/engage_tizi.wav b/openpilot/selfdrive/assets/sounds/engage_tizi.wav similarity index 100% rename from selfdrive/assets/sounds/engage_tizi.wav rename to openpilot/selfdrive/assets/sounds/engage_tizi.wav diff --git a/selfdrive/assets/sounds/make_beeps.py b/openpilot/selfdrive/assets/sounds/make_beeps.py similarity index 100% rename from selfdrive/assets/sounds/make_beeps.py rename to openpilot/selfdrive/assets/sounds/make_beeps.py diff --git a/openpilot/selfdrive/assets/sounds/pre_alert.wav b/openpilot/selfdrive/assets/sounds/pre_alert.wav new file mode 100644 index 0000000000..4443bf7d23 --- /dev/null +++ b/openpilot/selfdrive/assets/sounds/pre_alert.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c0af7f5fe57bb36ab96fae868e20feca763541c97a61b3a3a84a0e7fcb81163 +size 83350 diff --git a/selfdrive/assets/sounds/prompt.wav b/openpilot/selfdrive/assets/sounds/prompt.wav similarity index 100% rename from selfdrive/assets/sounds/prompt.wav rename to openpilot/selfdrive/assets/sounds/prompt.wav diff --git a/openpilot/selfdrive/assets/sounds/prompt_distracted.wav b/openpilot/selfdrive/assets/sounds/prompt_distracted.wav new file mode 100644 index 0000000000..c11993f20c --- /dev/null +++ b/openpilot/selfdrive/assets/sounds/prompt_distracted.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:412ef25d2fb103c1ebd55c667313a5921493305fb4e1f4e1dafc08d3b95d86ab +size 73026 diff --git a/selfdrive/assets/sounds/prompt_single_high.wav b/openpilot/selfdrive/assets/sounds/prompt_single_high.wav similarity index 100% rename from selfdrive/assets/sounds/prompt_single_high.wav rename to openpilot/selfdrive/assets/sounds/prompt_single_high.wav diff --git a/selfdrive/assets/sounds/prompt_single_low.wav b/openpilot/selfdrive/assets/sounds/prompt_single_low.wav similarity index 100% rename from selfdrive/assets/sounds/prompt_single_low.wav rename to openpilot/selfdrive/assets/sounds/prompt_single_low.wav diff --git a/selfdrive/assets/sounds/refuse.wav b/openpilot/selfdrive/assets/sounds/refuse.wav similarity index 100% rename from selfdrive/assets/sounds/refuse.wav rename to openpilot/selfdrive/assets/sounds/refuse.wav diff --git a/selfdrive/assets/sounds/warning_immediate.wav b/openpilot/selfdrive/assets/sounds/warning_immediate.wav similarity index 100% rename from selfdrive/assets/sounds/warning_immediate.wav rename to openpilot/selfdrive/assets/sounds/warning_immediate.wav diff --git a/selfdrive/assets/sounds/warning_soft.wav b/openpilot/selfdrive/assets/sounds/warning_soft.wav similarity index 100% rename from selfdrive/assets/sounds/warning_soft.wav rename to openpilot/selfdrive/assets/sounds/warning_soft.wav diff --git a/selfdrive/assets/training/step0.png b/openpilot/selfdrive/assets/training/step0.png similarity index 100% rename from selfdrive/assets/training/step0.png rename to openpilot/selfdrive/assets/training/step0.png diff --git a/selfdrive/assets/training/step1.png b/openpilot/selfdrive/assets/training/step1.png similarity index 100% rename from selfdrive/assets/training/step1.png rename to openpilot/selfdrive/assets/training/step1.png diff --git a/selfdrive/assets/training/step10.png b/openpilot/selfdrive/assets/training/step10.png similarity index 100% rename from selfdrive/assets/training/step10.png rename to openpilot/selfdrive/assets/training/step10.png diff --git a/selfdrive/assets/training/step11.png b/openpilot/selfdrive/assets/training/step11.png similarity index 100% rename from selfdrive/assets/training/step11.png rename to openpilot/selfdrive/assets/training/step11.png diff --git a/selfdrive/assets/training/step12.png b/openpilot/selfdrive/assets/training/step12.png similarity index 100% rename from selfdrive/assets/training/step12.png rename to openpilot/selfdrive/assets/training/step12.png diff --git a/selfdrive/assets/training/step13.png b/openpilot/selfdrive/assets/training/step13.png similarity index 100% rename from selfdrive/assets/training/step13.png rename to openpilot/selfdrive/assets/training/step13.png diff --git a/selfdrive/assets/training/step14.png b/openpilot/selfdrive/assets/training/step14.png similarity index 100% rename from selfdrive/assets/training/step14.png rename to openpilot/selfdrive/assets/training/step14.png diff --git a/selfdrive/assets/training/step15.png b/openpilot/selfdrive/assets/training/step15.png similarity index 100% rename from selfdrive/assets/training/step15.png rename to openpilot/selfdrive/assets/training/step15.png diff --git a/selfdrive/assets/training/step16.png b/openpilot/selfdrive/assets/training/step16.png similarity index 100% rename from selfdrive/assets/training/step16.png rename to openpilot/selfdrive/assets/training/step16.png diff --git a/selfdrive/assets/training/step17.png b/openpilot/selfdrive/assets/training/step17.png similarity index 100% rename from selfdrive/assets/training/step17.png rename to openpilot/selfdrive/assets/training/step17.png diff --git a/selfdrive/assets/training/step18.png b/openpilot/selfdrive/assets/training/step18.png similarity index 100% rename from selfdrive/assets/training/step18.png rename to openpilot/selfdrive/assets/training/step18.png diff --git a/selfdrive/assets/training/step2.png b/openpilot/selfdrive/assets/training/step2.png similarity index 100% rename from selfdrive/assets/training/step2.png rename to openpilot/selfdrive/assets/training/step2.png diff --git a/selfdrive/assets/training/step3.png b/openpilot/selfdrive/assets/training/step3.png similarity index 100% rename from selfdrive/assets/training/step3.png rename to openpilot/selfdrive/assets/training/step3.png diff --git a/selfdrive/assets/training/step4.png b/openpilot/selfdrive/assets/training/step4.png similarity index 100% rename from selfdrive/assets/training/step4.png rename to openpilot/selfdrive/assets/training/step4.png diff --git a/selfdrive/assets/training/step5.png b/openpilot/selfdrive/assets/training/step5.png similarity index 100% rename from selfdrive/assets/training/step5.png rename to openpilot/selfdrive/assets/training/step5.png diff --git a/selfdrive/assets/training/step6.png b/openpilot/selfdrive/assets/training/step6.png similarity index 100% rename from selfdrive/assets/training/step6.png rename to openpilot/selfdrive/assets/training/step6.png diff --git a/selfdrive/assets/training/step7.png b/openpilot/selfdrive/assets/training/step7.png similarity index 100% rename from selfdrive/assets/training/step7.png rename to openpilot/selfdrive/assets/training/step7.png diff --git a/selfdrive/assets/training/step8.png b/openpilot/selfdrive/assets/training/step8.png similarity index 100% rename from selfdrive/assets/training/step8.png rename to openpilot/selfdrive/assets/training/step8.png diff --git a/selfdrive/assets/training/step9.png b/openpilot/selfdrive/assets/training/step9.png similarity index 100% rename from selfdrive/assets/training/step9.png rename to openpilot/selfdrive/assets/training/step9.png diff --git a/selfdrive/car/CARS_template.md b/openpilot/selfdrive/car/CARS_template.md similarity index 98% rename from selfdrive/car/CARS_template.md rename to openpilot/selfdrive/car/CARS_template.md index bc335b6bd3..35804ff1fa 100644 --- a/selfdrive/car/CARS_template.md +++ b/openpilot/selfdrive/car/CARS_template.md @@ -6,7 +6,7 @@ {% set hardware_col_name = 'Hardware Needed' %} {% set wide_hardware_col_name = width_tag|format(hardware_col_name) -%} - + # Supported Cars diff --git a/selfdrive/car/__init__.py b/openpilot/selfdrive/car/__init__.py similarity index 100% rename from selfdrive/car/__init__.py rename to openpilot/selfdrive/car/__init__.py diff --git a/selfdrive/car/car_specific.py b/openpilot/selfdrive/car/car_specific.py similarity index 99% rename from selfdrive/car/car_specific.py rename to openpilot/selfdrive/car/car_specific.py index baa29978e3..244a8e3b07 100644 --- a/selfdrive/car/car_specific.py +++ b/openpilot/selfdrive/car/car_specific.py @@ -1,4 +1,5 @@ -from cereal import car, log +from openpilot.cereal import log +from opendbc.car.structs import car from opendbc.car import DT_CTRL, structs from opendbc.car.car_helpers import interfaces from opendbc.car.interfaces import MAX_CTRL_SPEED diff --git a/selfdrive/car/card.py b/openpilot/selfdrive/car/card.py similarity index 99% rename from selfdrive/car/card.py rename to openpilot/selfdrive/car/card.py index 995d02aabc..d9b7b4bb5a 100755 --- a/selfdrive/car/card.py +++ b/openpilot/selfdrive/car/card.py @@ -3,9 +3,10 @@ import os import time import threading -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging -from cereal import car, log, custom +from openpilot.cereal import log, custom +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper diff --git a/selfdrive/car/cruise.py b/openpilot/selfdrive/car/cruise.py similarity index 99% rename from selfdrive/car/cruise.py rename to openpilot/selfdrive/car/cruise.py index 572dfabc02..b554c1a978 100644 --- a/selfdrive/car/cruise.py +++ b/openpilot/selfdrive/car/cruise.py @@ -1,7 +1,7 @@ import math import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.sunnypilot.selfdrive.car.cruise_ext import VCruiseHelperSP diff --git a/selfdrive/car/docs.py b/openpilot/selfdrive/car/docs.py similarity index 89% rename from selfdrive/car/docs.py rename to openpilot/selfdrive/car/docs.py index f807fc320e..ea7a70688e 100755 --- a/selfdrive/car/docs.py +++ b/openpilot/selfdrive/car/docs.py @@ -6,7 +6,7 @@ from openpilot.common.basedir import BASEDIR from opendbc.car.docs import get_all_car_docs, generate_cars_md CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md") -CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") +CARS_MD_TEMPLATE = os.path.join(BASEDIR, "openpilot/selfdrive", "car", "CARS_template.md") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Auto generates supported cars documentation", diff --git a/selfdrive/car/helpers.py b/openpilot/selfdrive/car/helpers.py similarity index 98% rename from selfdrive/car/helpers.py rename to openpilot/selfdrive/car/helpers.py index 384152c71b..ec9e3efeeb 100644 --- a/selfdrive/car/helpers.py +++ b/openpilot/selfdrive/car/helpers.py @@ -1,7 +1,7 @@ import capnp from typing import Any -from cereal import custom +from openpilot.cereal import custom from opendbc.car import structs _FIELDS = '__dataclass_fields__' # copy of dataclasses._FIELDS diff --git a/selfdrive/car/tests/__init__.py b/openpilot/selfdrive/car/tests/__init__.py similarity index 100% rename from selfdrive/car/tests/__init__.py rename to openpilot/selfdrive/car/tests/__init__.py diff --git a/openpilot/selfdrive/car/tests/big_cars_test.sh b/openpilot/selfdrive/car/tests/big_cars_test.sh new file mode 100755 index 0000000000..456fc698c5 --- /dev/null +++ b/openpilot/selfdrive/car/tests/big_cars_test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(dirname "$0") +BASEDIR=$(realpath "$SCRIPT_DIR/../../../../") +cd $BASEDIR + +export MAX_EXAMPLES=300 +export INTERNAL_SEG_CNT=300 +export INTERNAL_SEG_LIST=openpilot/selfdrive/car/tests/test_models_segs.txt + +cd openpilot/selfdrive/car/tests && pytest test_models.py test_car_interfaces.py diff --git a/selfdrive/car/tests/test_car_interfaces.py b/openpilot/selfdrive/car/tests/test_car_interfaces.py similarity index 97% rename from selfdrive/car/tests/test_car_interfaces.py rename to openpilot/selfdrive/car/tests/test_car_interfaces.py index cd44759cbf..3c4587cbc6 100644 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/openpilot/selfdrive/car/tests/test_car_interfaces.py @@ -3,7 +3,8 @@ import hypothesis.strategies as st from hypothesis import Phase, given, settings from openpilot.common.parameterized import parameterized -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from opendbc.car import DT_CTRL from opendbc.car.structs import CarParams from opendbc.car.tests.test_car_interfaces import get_fuzzy_car_interface diff --git a/selfdrive/car/tests/test_cruise_speed.py b/openpilot/selfdrive/car/tests/test_cruise_speed.py similarity index 98% rename from selfdrive/car/tests/test_cruise_speed.py rename to openpilot/selfdrive/car/tests/test_cruise_speed.py index 360c93c25b..c0b6ac979f 100644 --- a/selfdrive/car/tests/test_cruise_speed.py +++ b/openpilot/selfdrive/car/tests/test_cruise_speed.py @@ -3,9 +3,10 @@ import itertools import numpy as np from openpilot.common.parameterized import parameterized_class -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.car.cruise import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_INITIAL, IMPERIAL_INCREMENT -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver diff --git a/selfdrive/car/tests/test_docs.py b/openpilot/selfdrive/car/tests/test_docs.py similarity index 99% rename from selfdrive/car/tests/test_docs.py rename to openpilot/selfdrive/car/tests/test_docs.py index ef6795ef80..8ccbfb5a79 100644 --- a/selfdrive/car/tests/test_docs.py +++ b/openpilot/selfdrive/car/tests/test_docs.py @@ -1,4 +1,3 @@ - from opendbc.car.docs import generate_cars_md, get_all_car_docs from openpilot.selfdrive.car.docs import CARS_MD_TEMPLATE diff --git a/selfdrive/car/tests/test_models.py b/openpilot/selfdrive/car/tests/test_models.py similarity index 99% rename from selfdrive/car/tests/test_models.py rename to openpilot/selfdrive/car/tests/test_models.py index c13061c0f7..adf0509121 100644 --- a/selfdrive/car/tests/test_models.py +++ b/openpilot/selfdrive/car/tests/test_models.py @@ -8,7 +8,6 @@ from collections import defaultdict, Counter import hypothesis.strategies as st from hypothesis import Phase, given, settings from openpilot.common.parameterized import parameterized_class - from opendbc.car import DT_CTRL, gen_empty_fingerprint, structs from opendbc.car.can_definitions import CanData from opendbc.car.car_helpers import FRAME_FINGERPRINT, interfaces diff --git a/selfdrive/car/tests/test_models_segs.txt b/openpilot/selfdrive/car/tests/test_models_segs.txt similarity index 100% rename from selfdrive/car/tests/test_models_segs.txt rename to openpilot/selfdrive/car/tests/test_models_segs.txt diff --git a/selfdrive/controls/__init__.py b/openpilot/selfdrive/controls/__init__.py similarity index 100% rename from selfdrive/controls/__init__.py rename to openpilot/selfdrive/controls/__init__.py diff --git a/selfdrive/controls/controlsd.py b/openpilot/selfdrive/controls/controlsd.py similarity index 98% rename from selfdrive/controls/controlsd.py rename to openpilot/selfdrive/controls/controlsd.py index 5c0fa30e4a..d9c0b445d8 100755 --- a/selfdrive/controls/controlsd.py +++ b/openpilot/selfdrive/controls/controlsd.py @@ -2,8 +2,9 @@ import math from numbers import Number -from cereal import car, log -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_CTRL, Priority, Ratekeeper @@ -218,7 +219,7 @@ class Controls(ControlsExt): cs.upAccelCmd = float(self.LoC.pid.p) cs.uiAccelCmd = float(self.LoC.pid.i) cs.ufAccelCmd = float(self.LoC.pid.f) - cs.forceDecel = bool((self.sm['driverMonitoringState'].alertLevel == log.DriverMonitoringState.AlertLevel.three) or + cs.forceDecel = bool(self.sm['driverMonitoringState'].noResponseForceDecel or (self.sm['selfdriveState'].state == State.softDisabling)) # trigger the car's stock driver monitoring escalation diff --git a/selfdrive/controls/lib/__init__.py b/openpilot/selfdrive/controls/lib/__init__.py similarity index 100% rename from selfdrive/controls/lib/__init__.py rename to openpilot/selfdrive/controls/lib/__init__.py diff --git a/selfdrive/controls/lib/desire_helper.py b/openpilot/selfdrive/controls/lib/desire_helper.py similarity index 68% rename from selfdrive/controls/lib/desire_helper.py rename to openpilot/selfdrive/controls/lib/desire_helper.py index f558f80d65..df4e5c56ab 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/openpilot/selfdrive/controls/lib/desire_helper.py @@ -1,4 +1,4 @@ -from cereal import log, custom +from openpilot.cereal import log, custom from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL from openpilot.sunnypilot.selfdrive.controls.lib.auto_lane_change import AutoLaneChangeController, AutoLaneChangeMode @@ -10,27 +10,7 @@ TurnDirection = custom.ModelDataV2SP.TurnDirection LANE_CHANGE_SPEED_MIN = 20 * CV.MPH_TO_MS LANE_CHANGE_TIME_MAX = 10. - -DESIRES = { - LaneChangeDirection.none: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.none, - LaneChangeState.laneChangeFinishing: log.Desire.none, - }, - LaneChangeDirection.left: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.laneChangeLeft, - LaneChangeState.laneChangeFinishing: log.Desire.laneChangeLeft, - }, - LaneChangeDirection.right: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.laneChangeRight, - LaneChangeState.laneChangeFinishing: log.Desire.laneChangeRight, - }, -} +LANE_CHANGE_START_TIME = 0.5 TURN_DESIRES = { TurnDirection.none: log.Desire.none, @@ -38,13 +18,11 @@ TURN_DESIRES = { TurnDirection.turnRight: log.Desire.turnRight, } - class DesireHelper: def __init__(self): self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none self.lane_change_timer = 0.0 - self.lane_change_ll_prob = 1.0 self.prev_one_blinker = False self.desire = log.Desire.none self.alc = AutoLaneChangeController(self) @@ -70,15 +48,14 @@ class DesireHelper: if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX or self.alc.lane_change_set_timer == AutoLaneChangeMode.OFF: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none + self.lane_change_timer = 0.0 else: - # LaneChangeState.off if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed: self.lane_change_state = LaneChangeState.preLaneChange - self.lane_change_ll_prob = 1.0 + self.lane_change_timer = 0.0 # Initialize lane change direction to prevent UI alert flicker self.lane_change_direction = self.get_lane_change_direction(carstate) - # LaneChangeState.preLaneChange elif self.lane_change_state == LaneChangeState.preLaneChange: # Update lane change direction self.lane_change_direction = self.get_lane_change_direction(carstate) @@ -95,40 +72,33 @@ class DesireHelper: if not one_blinker or below_lane_change_speed: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none + self.lane_change_timer = 0.0 elif (torque_applied or self.alc.auto_lane_change_allowed) and not blindspot_detected: self.lane_change_state = LaneChangeState.laneChangeStarting + self.lane_change_timer = 0.0 - # LaneChangeState.laneChangeStarting elif self.lane_change_state == LaneChangeState.laneChangeStarting: - # fade out over .5s - self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0) + self.lane_change_timer += DT_MDL - # 98% certainty - if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01: - self.lane_change_state = LaneChangeState.laneChangeFinishing - - # LaneChangeState.laneChangeFinishing - elif self.lane_change_state == LaneChangeState.laneChangeFinishing: - # fade in laneline over 1s - self.lane_change_ll_prob = min(self.lane_change_ll_prob + DT_MDL, 1.0) - - if self.lane_change_ll_prob > 0.99: - self.lane_change_direction = LaneChangeDirection.none + if lane_change_prob < 0.02 and self.lane_change_timer >= LANE_CHANGE_START_TIME: + self.lane_change_timer = 0.0 if one_blinker: self.lane_change_state = LaneChangeState.preLaneChange + self.lane_change_direction = self.get_lane_change_direction(carstate) else: self.lane_change_state = LaneChangeState.off + self.lane_change_direction = LaneChangeDirection.none - if self.lane_change_state in (LaneChangeState.off, LaneChangeState.preLaneChange): - self.lane_change_timer = 0.0 - else: - self.lane_change_timer += DT_MDL - - self.prev_one_blinker = one_blinker + self.prev_one_blinker = one_blinker and lateral_active if self.lane_turn_direction != TurnDirection.none: self.desire = TURN_DESIRES[self.lane_turn_direction] else: - self.desire = DESIRES[self.lane_change_direction][self.lane_change_state] + self.desire = log.Desire.none + if self.lane_change_state == LaneChangeState.laneChangeStarting: + if self.lane_change_direction == LaneChangeDirection.left: + self.desire = log.Desire.laneChangeLeft + elif self.lane_change_direction == LaneChangeDirection.right: + self.desire = log.Desire.laneChangeRight self.alc.update_state() diff --git a/selfdrive/controls/lib/drive_helpers.py b/openpilot/selfdrive/controls/lib/drive_helpers.py similarity index 100% rename from selfdrive/controls/lib/drive_helpers.py rename to openpilot/selfdrive/controls/lib/drive_helpers.py diff --git a/selfdrive/controls/lib/latcontrol.py b/openpilot/selfdrive/controls/lib/latcontrol.py similarity index 100% rename from selfdrive/controls/lib/latcontrol.py rename to openpilot/selfdrive/controls/lib/latcontrol.py diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/openpilot/selfdrive/controls/lib/latcontrol_angle.py similarity index 98% rename from selfdrive/controls/lib/latcontrol_angle.py rename to openpilot/selfdrive/controls/lib/latcontrol_angle.py index 9aa5b3cd01..18ccbae57b 100644 --- a/selfdrive/controls/lib/latcontrol_angle.py +++ b/openpilot/selfdrive/controls/lib/latcontrol_angle.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.latcontrol import LatControl # TODO This is speed dependent diff --git a/selfdrive/controls/lib/latcontrol_curvature.py b/openpilot/selfdrive/controls/lib/latcontrol_curvature.py similarity index 98% rename from selfdrive/controls/lib/latcontrol_curvature.py rename to openpilot/selfdrive/controls/lib/latcontrol_curvature.py index 0f4e45687e..3dfe691e10 100644 --- a/selfdrive/controls/lib/latcontrol_curvature.py +++ b/openpilot/selfdrive/controls/lib/latcontrol_curvature.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.common.pid import PIDController from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.selfdrive.controls.lib.drive_helpers import MAX_CURVATURE diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/openpilot/selfdrive/controls/lib/latcontrol_pid.py similarity index 98% rename from selfdrive/controls/lib/latcontrol_pid.py rename to openpilot/selfdrive/controls/lib/latcontrol_pid.py index 25b2c8d87e..214f4724d1 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/openpilot/selfdrive/controls/lib/latcontrol_pid.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.common.pid import PIDController diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/openpilot/selfdrive/controls/lib/latcontrol_torque.py similarity index 99% rename from selfdrive/controls/lib/latcontrol_torque.py rename to openpilot/selfdrive/controls/lib/latcontrol_torque.py index d0eb40d096..952234de99 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/openpilot/selfdrive/controls/lib/latcontrol_torque.py @@ -2,7 +2,7 @@ import math import numpy as np from collections import deque -from cereal import log +from openpilot.cereal import log from opendbc.car.lateral import FRICTION_THRESHOLD, get_friction from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/controls/lib/ldw.py b/openpilot/selfdrive/controls/lib/ldw.py similarity index 97% rename from selfdrive/controls/lib/ldw.py rename to openpilot/selfdrive/controls/lib/ldw.py index 78a6d6cf6e..6db59791cc 100644 --- a/selfdrive/controls/lib/ldw.py +++ b/openpilot/selfdrive/controls/lib/ldw.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.realtime import DT_CTRL from openpilot.common.constants import CV diff --git a/selfdrive/controls/lib/longcontrol.py b/openpilot/selfdrive/controls/lib/longcontrol.py similarity index 90% rename from selfdrive/controls/lib/longcontrol.py rename to openpilot/selfdrive/controls/lib/longcontrol.py index ec714f452e..99a42b1bca 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/openpilot/selfdrive/controls/lib/longcontrol.py @@ -1,5 +1,5 @@ import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N from openpilot.common.pid import PIDController @@ -15,11 +15,9 @@ def long_control_state_trans(CP, CP_SP, active, long_control_state, v_ego, # Gas Interceptor cruise_standstill = cruise_standstill and not CP_SP.enableGasInterceptor - stopping_condition = should_stop starting_condition = (not should_stop and not cruise_standstill and not brake_pressed) - started_condition = v_ego > CP.vEgoStarting if not active: long_control_state = LongCtrlState.off @@ -28,11 +26,10 @@ def long_control_state_trans(CP, CP_SP, active, long_control_state, v_ego, if long_control_state == LongCtrlState.off: if not starting_condition: long_control_state = LongCtrlState.stopping + elif CP.startingState: + long_control_state = LongCtrlState.starting else: - if starting_condition and CP.startingState: - long_control_state = LongCtrlState.starting - else: - long_control_state = LongCtrlState.pid + long_control_state = LongCtrlState.pid elif long_control_state == LongCtrlState.stopping: if starting_condition and CP.startingState: @@ -41,9 +38,9 @@ def long_control_state_trans(CP, CP_SP, active, long_control_state, v_ego, long_control_state = LongCtrlState.pid elif long_control_state in [LongCtrlState.starting, LongCtrlState.pid]: - if stopping_condition: + if should_stop: long_control_state = LongCtrlState.stopping - elif started_condition: + elif v_ego > CP.vEgoStarting: long_control_state = LongCtrlState.pid return long_control_state diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript similarity index 98% rename from selfdrive/controls/lib/longitudinal_mpc_lib/SConscript rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript index a3218e9f34..636ef0fb21 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript +++ b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript @@ -55,7 +55,7 @@ acados_include_dir = Dir(acados.INCLUDE_DIR) acados_template_dir = Dir(acados.TEMPLATE_DIR) source_list = ['long_mpc.py', - '#selfdrive/modeld/constants.py', + '#openpilot/selfdrive/modeld/constants.py', acados_include_dir.File('acados_c/ocp_nlp_interface.h'), acados_template_dir.File('c_templates_tera/acados_solver.in.c'), ] diff --git a/selfdrive/controls/lib/lateral_mpc_lib/__init__.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py similarity index 100% rename from selfdrive/controls/lib/lateral_mpc_lib/__init__.py rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py similarity index 96% rename from selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index deae416489..de1ba0c278 100755 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -2,7 +2,7 @@ import os import time import numpy as np -from cereal import log +from openpilot.cereal import log from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX from openpilot.common.realtime import DT_MDL from openpilot.common.swaglog import cloudlog @@ -240,14 +240,10 @@ class LongitudinalMpc: self.solver.set(i, 'x', np.zeros(X_DIM)) self.last_cloudlog_t = 0 - self.status = False self.crash_cnt = 0.0 self.solution_status = 0 # timers self.solve_time = 0.0 - self.time_qp_solution = 0.0 - self.time_linearization = 0.0 - self.time_integrator = 0.0 self.x0 = np.zeros(X_DIM) self.set_weights() @@ -292,7 +288,7 @@ class LongitudinalMpc: def process_lead(self, lead): v_ego = self.x0[1] - if lead is not None and lead.status: + if lead is not None and lead.present: x_lead = lead.dRel v_lead = lead.vLead a_lead = lead.aLeadK @@ -316,7 +312,6 @@ class LongitudinalMpc: def update(self, radarstate, v_cruise, personality=log.LongitudinalPersonality.standard): t_follow = get_T_FOLLOW(personality) v_ego = self.x0[1] - self.status = radarstate.leadOne.status or radarstate.leadTwo.status lead_xv_0 = self.process_lead(radarstate.leadOne) lead_xv_1 = self.process_lead(radarstate.leadTwo) @@ -365,9 +360,6 @@ class LongitudinalMpc: self.solution_status = self.solver.solve() self.solve_time = float(self.solver.get_stats('time_tot')[0]) - self.time_qp_solution = float(self.solver.get_stats('time_qp')[0]) - self.time_linearization = float(self.solver.get_stats('time_lin')[0]) - self.time_integrator = float(self.solver.get_stats('time_sim')[0]) for i in range(N+1): self.x_sol[i] = self.solver.get(i, 'x') diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py similarity index 87% rename from selfdrive/controls/lib/longitudinal_planner.py rename to openpilot/selfdrive/controls/lib/longitudinal_planner.py index e02b02d2e0..4f7e1e92de 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py @@ -2,7 +2,7 @@ import math import numpy as np -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX from openpilot.common.constants import CV from openpilot.common.filter_simple import FirstOrderFilter @@ -66,26 +66,6 @@ class LongitudinalPlanner(LongitudinalPlannerSP): self.a_desired_trajectory = np.zeros(CONTROL_N) self.j_desired_trajectory = np.zeros(CONTROL_N) - @staticmethod - def parse_model(model_msg): - if (len(model_msg.position.x) == ModelConstants.IDX_N and - len(model_msg.velocity.x) == ModelConstants.IDX_N and - len(model_msg.acceleration.x) == ModelConstants.IDX_N): - x = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.position.x) - v = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.velocity.x) - a = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.acceleration.x) - j = np.zeros(len(T_IDXS_MPC)) - else: - x = np.zeros(len(T_IDXS_MPC)) - v = np.zeros(len(T_IDXS_MPC)) - a = np.zeros(len(T_IDXS_MPC)) - j = np.zeros(len(T_IDXS_MPC)) - if len(model_msg.meta.disengagePredictions.gasPressProbs) > 1: - throttle_prob = model_msg.meta.disengagePredictions.gasPressProbs[1] - else: - throttle_prob = 1.0 - return x, v, a, j, throttle_prob - def update(self, sm): LongitudinalPlannerSP.update(self, sm) @@ -121,7 +101,8 @@ class LongitudinalPlanner(LongitudinalPlannerSP): # Prevent divergence, smooth in current v_ego self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego)) - _, _, _, _, throttle_prob = self.parse_model(sm['modelV2']) + throttle_probs = sm['modelV2'].meta.disengagePredictions.gasPressProbs + throttle_prob = throttle_probs[1] if len(throttle_probs) > 1 else 1.0 # Don't clip at low speeds since throttle_prob doesn't account for creep self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED @@ -177,7 +158,7 @@ class LongitudinalPlanner(LongitudinalPlannerSP): def publish(self, sm, pm): plan_send = messaging.new_message('longitudinalPlan') - plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState', 'selfdriveState', 'radarState']) + plan_send.valid = sm.all_checks() longitudinalPlan = plan_send.longitudinalPlan longitudinalPlan.modelMonoTime = sm.logMonoTime['modelV2'] @@ -188,7 +169,7 @@ class LongitudinalPlanner(LongitudinalPlannerSP): longitudinalPlan.accels = self.a_desired_trajectory.tolist() longitudinalPlan.jerks = self.j_desired_trajectory.tolist() - longitudinalPlan.hasLead = sm['radarState'].leadOne.status + longitudinalPlan.hasLead = sm['radarState'].leadOne.present longitudinalPlan.longitudinalPlanSource = self.mpc.source longitudinalPlan.fcw = self.fcw diff --git a/selfdrive/controls/plannerd.py b/openpilot/selfdrive/controls/plannerd.py similarity index 92% rename from selfdrive/controls/plannerd.py rename to openpilot/selfdrive/controls/plannerd.py index f7d3370f90..66b17d60a7 100755 --- a/selfdrive/controls/plannerd.py +++ b/openpilot/selfdrive/controls/plannerd.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.gps import get_gps_location_service from openpilot.common.params import Params from openpilot.common.realtime import Priority, config_realtime_process from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.ldw import LaneDepartureWarning from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def main(): @@ -39,7 +40,7 @@ def main(): ldw.update(sm.frame, sm['modelV2'], sm['carState'], sm['carControl']) msg = messaging.new_message('driverAssistance') - msg.valid = sm.all_checks(['carState', 'carControl', 'modelV2', 'liveParameters']) + msg.valid = sm.all_checks() msg.driverAssistance.leftLaneDeparture = ldw.left msg.driverAssistance.rightLaneDeparture = ldw.right pm.send('driverAssistance', msg) diff --git a/selfdrive/controls/radard.py b/openpilot/selfdrive/controls/radard.py similarity index 93% rename from selfdrive/controls/radard.py rename to openpilot/selfdrive/controls/radard.py index d51eb6edb0..5db5865e75 100755 --- a/selfdrive/controls/radard.py +++ b/openpilot/selfdrive/controls/radard.py @@ -5,7 +5,8 @@ from collections import deque from typing import Any import capnp -from cereal import messaging, log, car, custom +from openpilot.cereal import messaging, log, custom +from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process @@ -26,7 +27,6 @@ SPEED, ACCEL = 0, 1 # Kalman filter states enum # stationary qualification parameters V_EGO_STATIONARY = 4. # no stationary object flag below this speed -RADAR_TO_CENTER = 2.7 # (deprecated) RADAR is ~ 2.7m ahead from center of car RADAR_TO_CAMERA = 1.52 # RADAR is ~ 1.5m ahead from center of mesh frame @@ -62,13 +62,12 @@ class Track: self.K_K = kalman_params.K self.kf = KF1D([[v_lead], [0.0]], self.K_A, self.K_C, self.K_K) - def update(self, d_rel: float, y_rel: float, v_rel: float, v_lead: float, measured: float): + def update(self, d_rel: float, y_rel: float, v_rel: float, v_lead: float): # relative values, copy 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 # computed velocity and accelerations if self.cnt > 0: @@ -94,8 +93,7 @@ class Track: "vLeadK": float(self.vLeadK), "aLeadK": float(self.aLeadK), "aLeadTau": float(self.aLeadTau.x), - "status": True, - "fcw": self.is_potential_fcw(model_prob), + "present": True, "modelProb": model_prob, "radar": True, "radarTrackId": self.identifier, @@ -106,9 +104,6 @@ class Track: # Radar points closer than 0.75, are almost always glitches on toyota radars return abs(self.yRel) < 1.0 and (v_ego < V_EGO_STATIONARY) and (0.75 < self.dRel < 25) - def is_potential_fcw(self, model_prob: float): - return model_prob > .9 - def __str__(self): ret = f"x: {self.dRel:4.1f} y: {self.yRel:4.1f} v: {self.vRel:4.1f} a: {self.aLeadK:4.1f}" return ret @@ -152,9 +147,8 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa "vLeadK": float(v_ego + lead_v_rel_pred), "aLeadK": float(lead_msg.a[0]), "aLeadTau": 0.3, - "fcw": False, "modelProb": float(lead_prob), - "status": True, + "present": True, "radar": False, "radarTrackId": -1, } @@ -169,7 +163,7 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn else: track = None - lead_dict = {'status': False} + lead_dict = {'present': False} if track is not None: lead_dict = track.get_RadarState(lead_prob) lead_dict = get_custom_yrel(CP, CP_SP, lead_dict, lead_msg) @@ -182,7 +176,7 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn closest_track = min(low_speed_tracks, key=lambda c: c.dRel) # Only choose new track if it is actually closer than the previous one - if (not lead_dict['status']) or (closest_track.dRel < lead_dict['dRel']): + if (not lead_dict['present']) or (closest_track.dRel < lead_dict['dRel']): lead_dict = closest_track.get_RadarState() return lead_dict @@ -226,7 +220,7 @@ class RadarD: self.v_ego_hist.append(self.v_ego) self.last_v_ego_frame = sm.recv_frame['carState'] - ar_pts = {pt.trackId: [pt.dRel, pt.yRel, pt.vRel, pt.measured] for pt in rr.points} + ar_pts = {pt.trackId: [pt.dRel, pt.yRel, pt.vRel] for pt in rr.points} # *** remove missing points from meta data *** for ids in list(self.tracks.keys()): @@ -243,14 +237,13 @@ class RadarD: # 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]) + self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead) # *** publish radarState *** self.radar_state_valid = sm.all_checks() self.radar_state = log.RadarState.new_message() self.radar_state.mdMonoTime = sm.logMonoTime['modelV2'] self.radar_state.radarErrors = rr.errors - self.radar_state.carStateMonoTime = sm.logMonoTime['carState'] if len(sm['modelV2'].velocity.x): model_v_ego = sm['modelV2'].velocity.x[0] diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py b/openpilot/selfdrive/controls/tests/__init__.py similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py rename to openpilot/selfdrive/controls/tests/__init__.py diff --git a/selfdrive/controls/tests/test_following_distance.py b/openpilot/selfdrive/controls/tests/test_following_distance.py similarity index 98% rename from selfdrive/controls/tests/test_following_distance.py rename to openpilot/selfdrive/controls/tests/test_following_distance.py index 1eb88d7206..fcabce0387 100644 --- a/selfdrive/controls/tests/test_following_distance.py +++ b/openpilot/selfdrive/controls/tests/test_following_distance.py @@ -2,7 +2,7 @@ import pytest import itertools from openpilot.common.parameterized import parameterized_class -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import get_safe_obstacle_distance, get_stopped_equivalence_factor, get_T_FOLLOW from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver diff --git a/selfdrive/controls/tests/test_latcontrol.py b/openpilot/selfdrive/controls/tests/test_latcontrol.py similarity index 97% rename from selfdrive/controls/tests/test_latcontrol.py rename to openpilot/selfdrive/controls/tests/test_latcontrol.py index d36ed52192..52e6912d6d 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/openpilot/selfdrive/controls/tests/test_latcontrol.py @@ -1,6 +1,7 @@ from openpilot.common.parameterized import parameterized -from cereal import car, log +from openpilot.cereal import log +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.honda.values import CAR as HONDA from opendbc.car.toyota.values import CAR as TOYOTA diff --git a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py b/openpilot/selfdrive/controls/tests/test_latcontrol_torque_buffer.py similarity index 96% rename from selfdrive/controls/tests/test_latcontrol_torque_buffer.py rename to openpilot/selfdrive/controls/tests/test_latcontrol_torque_buffer.py index b13576a6cf..dc634f20fd 100644 --- a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py +++ b/openpilot/selfdrive/controls/tests/test_latcontrol_torque_buffer.py @@ -1,6 +1,7 @@ from openpilot.common.parameterized import parameterized -from cereal import car, log +from openpilot.cereal import log +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.toyota.values import CAR as TOYOTA from opendbc.car.vehicle_model import VehicleModel diff --git a/selfdrive/controls/tests/test_leads.py b/openpilot/selfdrive/controls/tests/test_leads.py similarity index 96% rename from selfdrive/controls/tests/test_leads.py rename to openpilot/selfdrive/controls/tests/test_leads.py index 77384fea20..1956bb34ec 100644 --- a/selfdrive/controls/tests/test_leads.py +++ b/openpilot/selfdrive/controls/tests/test_leads.py @@ -1,4 +1,4 @@ -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.toyota.values import CAR as TOYOTA from openpilot.selfdrive.test.process_replay import replay_process_with_name diff --git a/selfdrive/controls/tests/test_longcontrol.py b/openpilot/selfdrive/controls/tests/test_longcontrol.py similarity index 97% rename from selfdrive/controls/tests/test_longcontrol.py rename to openpilot/selfdrive/controls/tests/test_longcontrol.py index cf0ab24e0b..210384a3ea 100644 --- a/selfdrive/controls/tests/test_longcontrol.py +++ b/openpilot/selfdrive/controls/tests/test_longcontrol.py @@ -1,4 +1,5 @@ -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState, long_control_state_trans diff --git a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py b/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py similarity index 98% rename from selfdrive/controls/tests/test_torqued_lat_accel_offset.py rename to openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py index 2f95d7c14f..93a57d7f60 100644 --- a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py +++ b/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py @@ -1,5 +1,6 @@ import numpy as np -from cereal import car, messaging +from openpilot.cereal import messaging +from opendbc.car.structs import car from opendbc.car import ACCELERATION_DUE_TO_GRAVITY from opendbc.car import structs from opendbc.car.lateral import get_friction, FRICTION_THRESHOLD diff --git a/selfdrive/locationd/SConscript b/openpilot/selfdrive/locationd/SConscript similarity index 100% rename from selfdrive/locationd/SConscript rename to openpilot/selfdrive/locationd/SConscript diff --git a/selfdrive/controls/tests/__init__.py b/openpilot/selfdrive/locationd/__init__.py similarity index 100% rename from selfdrive/controls/tests/__init__.py rename to openpilot/selfdrive/locationd/__init__.py diff --git a/selfdrive/locationd/calibrationd.py b/openpilot/selfdrive/locationd/calibrationd.py similarity index 98% rename from selfdrive/locationd/calibrationd.py rename to openpilot/selfdrive/locationd/calibrationd.py index c444d43983..b9616bf632 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/openpilot/selfdrive/locationd/calibrationd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ''' This process finds calibration values. More info on what these calibration values -are can be found here https://github.com/commaai/openpilot/tree/master/common/transformations +are can be found here https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations While the roll calibration is a real value that can be estimated, here we assume it's zero, and the image input into the neural network is not corrected for roll. ''' @@ -11,8 +11,9 @@ import capnp import numpy as np from typing import NoReturn -from cereal import log, car -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.hardware import HARDWARE from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/selfdrive/locationd/helpers.py b/openpilot/selfdrive/locationd/helpers.py similarity index 99% rename from selfdrive/locationd/helpers.py rename to openpilot/selfdrive/locationd/helpers.py index 73c4d8bf35..fe7930c509 100644 --- a/selfdrive/locationd/helpers.py +++ b/openpilot/selfdrive/locationd/helpers.py @@ -2,7 +2,7 @@ import numpy as np from typing import Any from functools import cache -from cereal import log +from openpilot.cereal import log from openpilot.common.transformations.orientation import rot_from_euler, euler_from_rot diff --git a/selfdrive/locationd/lagd.py b/openpilot/selfdrive/locationd/lagd.py similarity index 98% rename from selfdrive/locationd/lagd.py rename to openpilot/selfdrive/locationd/lagd.py index a9377f3366..da2c53fd11 100755 --- a/selfdrive/locationd/lagd.py +++ b/openpilot/selfdrive/locationd/lagd.py @@ -5,9 +5,10 @@ import capnp from collections import deque from functools import partial -import cereal.messaging as messaging -from cereal import car, log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process @@ -25,7 +26,7 @@ MIN_VEGO = 50.0 * CV.MPH_TO_MS MIN_ABS_YAW_RATE = 0.0 MAX_YAW_RATE_SANITY_CHECK = 1.0 MIN_NCC = 0.95 -MAX_LAG = 1.0 +MAX_LAG = 0.65 MIN_LAG = 0.15 MAX_LAG_STD = 0.1 MAX_LAT_ACCEL = 2.0 diff --git a/selfdrive/locationd/locationd.py b/openpilot/selfdrive/locationd/locationd.py similarity index 99% rename from selfdrive/locationd/locationd.py rename to openpilot/selfdrive/locationd/locationd.py index 41b80a1c41..8e03995d13 100755 --- a/selfdrive/locationd/locationd.py +++ b/openpilot/selfdrive/locationd/locationd.py @@ -6,8 +6,8 @@ import numpy as np from enum import Enum from collections import defaultdict -from cereal import log, messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log, messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.transformations.orientation import rot_from_euler from openpilot.common.realtime import config_realtime_process from openpilot.common.params import Params diff --git a/selfdrive/locationd/models/.gitignore b/openpilot/selfdrive/locationd/models/.gitignore similarity index 100% rename from selfdrive/locationd/models/.gitignore rename to openpilot/selfdrive/locationd/models/.gitignore diff --git a/selfdrive/locationd/__init__.py b/openpilot/selfdrive/locationd/models/__init__.py similarity index 100% rename from selfdrive/locationd/__init__.py rename to openpilot/selfdrive/locationd/models/__init__.py diff --git a/selfdrive/locationd/models/car_kf.py b/openpilot/selfdrive/locationd/models/car_kf.py similarity index 100% rename from selfdrive/locationd/models/car_kf.py rename to openpilot/selfdrive/locationd/models/car_kf.py diff --git a/selfdrive/locationd/models/constants.py b/openpilot/selfdrive/locationd/models/constants.py similarity index 100% rename from selfdrive/locationd/models/constants.py rename to openpilot/selfdrive/locationd/models/constants.py diff --git a/selfdrive/locationd/models/pose_kf.py b/openpilot/selfdrive/locationd/models/pose_kf.py similarity index 100% rename from selfdrive/locationd/models/pose_kf.py rename to openpilot/selfdrive/locationd/models/pose_kf.py diff --git a/selfdrive/locationd/paramsd.py b/openpilot/selfdrive/locationd/paramsd.py similarity index 99% rename from selfdrive/locationd/paramsd.py rename to openpilot/selfdrive/locationd/paramsd.py index 02d09c506e..a32773bf0c 100755 --- a/selfdrive/locationd/paramsd.py +++ b/openpilot/selfdrive/locationd/paramsd.py @@ -3,8 +3,9 @@ import os import numpy as np import capnp -import cereal.messaging as messaging -from cereal import car, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_MDL from openpilot.selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States diff --git a/selfdrive/locationd/models/__init__.py b/openpilot/selfdrive/locationd/test/__init__.py similarity index 100% rename from selfdrive/locationd/models/__init__.py rename to openpilot/selfdrive/locationd/test/__init__.py diff --git a/selfdrive/locationd/test/test_calibrationd.py b/openpilot/selfdrive/locationd/test/test_calibrationd.py similarity index 98% rename from selfdrive/locationd/test/test_calibrationd.py rename to openpilot/selfdrive/locationd/test/test_calibrationd.py index c90ce506ab..f862b369fe 100644 --- a/selfdrive/locationd/test/test_calibrationd.py +++ b/openpilot/selfdrive/locationd/test/test_calibrationd.py @@ -2,8 +2,8 @@ import random import numpy as np -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from openpilot.common.params import Params from openpilot.selfdrive.locationd.calibrationd import Calibrator, INPUTS_NEEDED, INPUTS_WANTED, BLOCK_SIZE, MIN_SPEED_FILTER, \ MAX_YAW_RATE_FILTER, SMOOTH_CYCLES, HEIGHT_INIT, MAX_ALLOWED_PITCH_SPREAD, MAX_ALLOWED_YAW_SPREAD diff --git a/selfdrive/locationd/test/test_lagd.py b/openpilot/selfdrive/locationd/test/test_lagd.py similarity index 91% rename from selfdrive/locationd/test/test_lagd.py rename to openpilot/selfdrive/locationd/test/test_lagd.py index 63ea2b5fab..128c19332f 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/openpilot/selfdrive/locationd/test/test_lagd.py @@ -3,9 +3,10 @@ import numpy as np import time import pytest -from cereal import messaging, log, car +from openpilot.cereal import messaging, log +from opendbc.car.structs import car from openpilot.selfdrive.locationd.lagd import LateralLagEstimator, retrieve_initial_lag, masked_normalized_cross_correlation, \ - BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION + BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION, MIN_LAG, MAX_LAG from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_carParams from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE from openpilot.common.params import Params @@ -14,6 +15,7 @@ from openpilot.common.hardware import PC MAX_ERR_FRAMES = 1 DT = 0.05 +LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES = int(round(MIN_LAG / DT)), int(round(MAX_LAG / DT)) def process_messages(estimator, lag_frames, n_frames, vego=25.0, rejection_threshold=0.0): @@ -102,7 +104,7 @@ class TestLagd: assert np.argmax(corr) in range(lag_frames - MAX_ERR_FRAMES, lag_frames + MAX_ERR_FRAMES + 1) def test_empty_estimator(self): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT) msg = estimator.get_msg(True) assert msg.liveDelay.status == 'unestimated' @@ -112,9 +114,9 @@ class TestLagd: assert msg.liveDelay.calPerc == 0 def test_estimator_basics(self, subtests): - for lag_frames in range(3, 10): + for lag_frames in range(LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES - 1): with subtests.test(msg=f"lag_frames={lag_frames}"): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT, min_recovery_buffer_sec=0.0, min_yr=0.0) process_messages(estimator, lag_frames, int(MIN_OKAY_WINDOW_SEC / DT) + BLOCK_NUM_NEEDED * BLOCK_SIZE) msg = estimator.get_msg(True) @@ -126,7 +128,7 @@ class TestLagd: assert msg.liveDelay.calPerc == 100 def test_estimator_masking(self): - mocked_CP, lag_frames = car.CarParams(steerActuatorDelay=0.8), random.randint(3, 19) + mocked_CP, lag_frames = car.CarParams(steerActuatorDelay=0.5), random.randint(LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES - 1) estimator = LateralLagEstimator(mocked_CP, DT, min_recovery_buffer_sec=0.0, min_yr=0.0, min_valid_block_count=1) process_messages(estimator, lag_frames, (int(MIN_OKAY_WINDOW_SEC / DT) + BLOCK_SIZE) * 2, rejection_threshold=0.4) msg = estimator.get_msg(True) @@ -136,7 +138,7 @@ class TestLagd: @pytest.mark.skipif(PC, reason="only on device") def test_estimator_performance(self): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT) ds = [] diff --git a/selfdrive/locationd/test/test_locationd_scenarios.py b/openpilot/selfdrive/locationd/test/test_locationd_scenarios.py similarity index 100% rename from selfdrive/locationd/test/test_locationd_scenarios.py rename to openpilot/selfdrive/locationd/test/test_locationd_scenarios.py diff --git a/selfdrive/locationd/test/test_paramsd.py b/openpilot/selfdrive/locationd/test/test_paramsd.py similarity index 98% rename from selfdrive/locationd/test/test_paramsd.py rename to openpilot/selfdrive/locationd/test/test_paramsd.py index 1a4d348e94..28c3f4acf7 100644 --- a/selfdrive/locationd/test/test_paramsd.py +++ b/openpilot/selfdrive/locationd/test/test_paramsd.py @@ -1,7 +1,7 @@ import random import numpy as np -from cereal import messaging +from openpilot.cereal import messaging from openpilot.selfdrive.locationd.paramsd import retrieve_initial_vehicle_params, migrate_cached_vehicle_params_if_needed from openpilot.selfdrive.locationd.models.car_kf import CarKalman from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE diff --git a/selfdrive/locationd/test/test_torqued.py b/openpilot/selfdrive/locationd/test/test_torqued.py similarity index 96% rename from selfdrive/locationd/test/test_torqued.py rename to openpilot/selfdrive/locationd/test/test_torqued.py index 53f3120c36..ac8e40fc30 100644 --- a/selfdrive/locationd/test/test_torqued.py +++ b/openpilot/selfdrive/locationd/test/test_torqued.py @@ -1,4 +1,4 @@ -from cereal import car +from opendbc.car.structs import car from openpilot.selfdrive.locationd.torqued import TorqueEstimator diff --git a/selfdrive/locationd/torqued.py b/openpilot/selfdrive/locationd/torqued.py similarity index 99% rename from selfdrive/locationd/torqued.py rename to openpilot/selfdrive/locationd/torqued.py index a0f16f303a..329d767610 100755 --- a/selfdrive/locationd/torqued.py +++ b/openpilot/selfdrive/locationd/torqued.py @@ -3,8 +3,9 @@ import os import numpy as np from collections import deque, defaultdict -import cereal.messaging as messaging -from cereal import car, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_MDL diff --git a/selfdrive/modeld/SConscript b/openpilot/selfdrive/modeld/SConscript similarity index 91% rename from selfdrive/modeld/SConscript rename to openpilot/selfdrive/modeld/SConscript index 4a40173629..5f6281556f 100644 --- a/selfdrive/modeld/SConscript +++ b/openpilot/selfdrive/modeld/SConscript @@ -16,7 +16,7 @@ CAMERA_CONFIGS = [ ] Import('env', 'arch') -chunker_file = File("#common/file_chunker.py") +chunker_file = File("#openpilot/common/file_chunker.py") lenv = env.Clone() tinygrad_root = env.Dir("#").abspath @@ -45,11 +45,11 @@ else: tg_flags = f'DEV=CPU' if arch == 'Darwin' else 'DEV=CPU:LLVM' tg_devices = { # which device to put jit inputs to at runtime - 'selfdrive.modeld.modeld': { + 'openpilot.selfdrive.modeld.modeld': { 'default': {'WARP_DEV': tg_backend, 'QUEUE_DEV': tg_backend}, 'usbgpu': {'WARP_DEV': tg_backend, 'QUEUE_DEV': 'AMD'} }, - 'selfdrive.modeld.dmonitoringmodeld': { + 'openpilot.selfdrive.modeld.dmonitoringmodeld': { 'default': {'DEV': tg_backend} }, } @@ -74,12 +74,12 @@ tg_devices_node = lenv.Command( # tinygrad calls brew which needs a $HOME in the env mac_brew_string = f'HOME={os.path.expanduser("~")}' if arch == 'Darwin' else '' -modeld_dir = Dir("#selfdrive/modeld").abspath +modeld_dir = Dir("#openpilot/selfdrive/modeld").abspath compile_modeld_script = [ File(f"{modeld_dir}/compile_modeld.py"), File(f"{modeld_dir}/get_model_metadata.py"), - File("#system/camerad/cameras/nv12_info.py"), - File("#common/hardware/hw.py"), + File("#openpilot/system/camerad/cameras/nv12_info.py"), + File("#openpilot/common/hardware/hw.py"), ] model_w, model_h = MEDMODEL_INPUT_SIZE frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ @@ -109,8 +109,8 @@ for usbgpu in [False, True] if USBGPU else [False]: # get model metadata fn = File(f"models/dmonitoring_model").abspath -script_files = [File(Dir("#selfdrive/modeld").File("get_model_metadata.py").abspath)] -cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' +script_files = [File(Dir("#openpilot/selfdrive/modeld").File("get_model_metadata.py").abspath)] +cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#openpilot/selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' lenv.Command(fn + "_metadata.pkl", [fn + ".onnx"] + tinygrad_files + script_files + [tg_devices_node], cmd) dm_w, dm_h = DM_INPUT_SIZE diff --git a/selfdrive/locationd/test/__init__.py b/openpilot/selfdrive/modeld/__init__.py similarity index 100% rename from selfdrive/locationd/test/__init__.py rename to openpilot/selfdrive/modeld/__init__.py diff --git a/selfdrive/modeld/compile_dm_warp.py b/openpilot/selfdrive/modeld/compile_dm_warp.py similarity index 100% rename from selfdrive/modeld/compile_dm_warp.py rename to openpilot/selfdrive/modeld/compile_dm_warp.py diff --git a/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py similarity index 85% rename from selfdrive/modeld/compile_modeld.py rename to openpilot/selfdrive/modeld/compile_modeld.py index 35f92d344f..769fb69eb3 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -6,11 +6,14 @@ import os import pickle import tempfile import time +import shutil from functools import partial from collections import namedtuple import numpy as np +from openpilot.selfdrive.modeld.helpers import dump_oob, load_oob + def _patch_tinygrad_fetch_fw(): import hashlib import pathlib @@ -27,6 +30,23 @@ def _patch_tinygrad_fetch_fw(): helpers.fetch_fw = fetch_fw _patch_tinygrad_fetch_fw() +def _patch_tinygrad_buffer_reduce(): + from tinygrad.device import Buffer + def __reduce_ex__(self, protocol): + buf = None + if self._base is not None: + return self.__class__, (self.device, self.size, self.dtype, None, None, None, 0, self.base, self.offset, self.is_allocated()) + if self.device == "NPY": + return self.__class__, (self.device, self.size, self.dtype, self._buf, self.options, None, self.uop_refcount) + if self.is_allocated(): + buf = bytearray(self.nbytes) + self.copyout(memoryview(buf)) + if protocol >= 5: + buf = pickle.PickleBuffer(buf) + return self.__class__, (self.device, self.size, self.dtype, None, self.options, buf, self.uop_refcount) + Buffer.__reduce_ex__ = __reduce_ex__ +_patch_tinygrad_buffer_reduce() + from tinygrad.tensor import Tensor from tinygrad.helpers import Context from tinygrad.device import Device @@ -34,8 +54,8 @@ from tinygrad.engine.jit import TinyJit NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) -WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm'] -POLICY_INPUTS = ['feat_q', 'desire_q', 'packed_npy_inputs'] +WARP_INPUTS = ['tfm', 'big_tfm'] +POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -175,20 +195,17 @@ def sample_desire(buf, frame_skip): def make_warp(nv12, model_w, model_h, frame_skip): frame_prepare = make_frame_prepare(nv12, model_w, model_h) - sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) - def warp_enqueue(img_q, big_img_q, tfm, big_tfm, frame, big_frame): + def warp(tfm, big_tfm, frame, big_frame): tfm = tfm.to(WARP_DEV) big_tfm = big_tfm.to(WARP_DEV) Tensor.realize(tfm, big_tfm) warped_frame = frame_prepare(frame, tfm).unsqueeze(0) warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0) - warped = Tensor.cat(warped_frame, warped_big_frame).to(Device.DEFAULT) - img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) - big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - return img, big_img - return warp_enqueue + return Tensor.cat(warped_frame, warped_big_frame) + + return warp def make_run_policy(model_runner, model_metadata, frame_skip): @@ -196,8 +213,14 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): - packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() + def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): + packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) + warped = warped.to(Device.DEFAULT) + Tensor.realize(packed_npy_inputs, warped) + + img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) + big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) + desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) @@ -252,7 +275,10 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): print('capture + replay') test_val, test_buffers = random_inputs_run(jit, SEED) print('pickle round trip') - jit = pickle.loads(pickle.dumps(jit)) + with tempfile.TemporaryFile(dir=".") as f: + dump_oob(jit, f) + f.seek(0) + jit = load_oob(f) random_inputs_run(jit, SEED, test_val, test_buffers, expect_match=True) random_inputs_run(jit, SEED+1, test_val, test_buffers, expect_match=False) return jit @@ -263,12 +289,11 @@ def _parse_size(s): return int(w), int(h) -def read_file_chunked_to_shm(path): - from openpilot.common.file_chunker import read_file_chunked - from openpilot.common.hardware.hw import Paths - with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: - f.write(read_file_chunked(path)) - tmp_path = f.name +def read_file_chunked_to_disk(path): + from openpilot.common.file_chunker import open_file_chunked + tmp_path = f'{path}.unchunked' + with open(tmp_path, 'wb') as f, open_file_chunked(path) as src: + shutil.copyfileobj(src, f) atexit.register(lambda: os.path.exists(tmp_path) and os.remove(tmp_path)) return tmp_path @@ -286,7 +311,7 @@ if __name__ == "__main__": p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - model_path = read_file_chunked_to_shm(args.onnx) + model_path = read_file_chunked_to_disk(args.onnx) model_w, model_h = args.model_size model_runner = OnnxRunner(model_path) @@ -295,17 +320,17 @@ if __name__ == "__main__": run_policy_jit = TinyJit(make_run_policy(model_runner, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['input_shapes'], args.frame_skip) - make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['input_shapes']['img']) + make_random_model_inputs = partial(make_random_images, keys=['warped'], shape=(2, 6, *out['metadata']['input_shapes']['img'][2:]), device=WARP_DEV) out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, make_policy_queues) for cam_w, cam_h in args.camera_resolutions: nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) - warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) + warp = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) make_warp_queues = partial(make_warp_input_queues, out['metadata']['input_shapes'], args.frame_skip) - out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) + out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: - pickle.dump(out, f) + dump_oob(out, f) print(f"Saved JITs to {args.output} ({os.path.getsize(args.output) / 1e6:.2f} MB)") diff --git a/selfdrive/modeld/constants.py b/openpilot/selfdrive/modeld/constants.py similarity index 100% rename from selfdrive/modeld/constants.py rename to openpilot/selfdrive/modeld/constants.py diff --git a/selfdrive/modeld/dmonitoringmodeld.py b/openpilot/selfdrive/modeld/dmonitoringmodeld.py similarity index 95% rename from selfdrive/modeld/dmonitoringmodeld.py rename to openpilot/selfdrive/modeld/dmonitoringmodeld.py index eaf423e7be..554407a223 100755 --- a/selfdrive/modeld/dmonitoringmodeld.py +++ b/openpilot/selfdrive/modeld/dmonitoringmodeld.py @@ -6,18 +6,18 @@ import time import pickle import numpy as np -from cereal import messaging -from cereal.messaging import PubMaster, SubMaster +from openpilot.cereal import messaging +from openpilot.cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from openpilot.common.swaglog import cloudlog from openpilot.common.realtime import config_realtime_process from openpilot.common.transformations.model import dmonitoringmodel_intrinsics from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.file_chunker import read_file_chunked +from openpilot.common.file_chunker import open_file_chunked from openpilot.selfdrive.modeld.parse_model_outputs import sigmoid, safe_exp -PROCESS_NAME = "selfdrive.modeld.dmonitoringmodeld" +PROCESS_NAME = "openpilot.selfdrive.modeld.dmonitoringmodeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') MODEL_PKL_PATH = MODELS_DIR / 'dmonitoring_model_tinygrad.pkl' METADATA_PATH = MODELS_DIR / 'dmonitoring_model_metadata.pkl' @@ -43,7 +43,7 @@ class ModelState: self.frame_buf_params = get_nv12_info(cam_w, cam_h) self.tensor_inputs = {k: Tensor(v, device='NPY').realize() for k,v in self.numpy_inputs.items()} self._blob_cache : dict[int, Tensor] = {} - self.model_run = pickle.loads(read_file_chunked(str(MODEL_PKL_PATH))) + self.model_run = pickle.load(open_file_chunked(str(MODEL_PKL_PATH))) with open(MODELS_DIR / f'dm_warp_{cam_w}x{cam_h}_tinygrad.pkl', "rb") as f: self.image_warp = pickle.load(f) diff --git a/selfdrive/modeld/fill_model_msg.py b/openpilot/selfdrive/modeld/fill_model_msg.py similarity index 99% rename from selfdrive/modeld/fill_model_msg.py rename to openpilot/selfdrive/modeld/fill_model_msg.py index b7a48ee01c..c4c973bb78 100644 --- a/selfdrive/modeld/fill_model_msg.py +++ b/openpilot/selfdrive/modeld/fill_model_msg.py @@ -1,7 +1,7 @@ import os import capnp import numpy as np -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.modeld.constants import ModelConstants, Plan, Meta from openpilot.sunnypilot.models.helpers import plan_x_idxs_helper diff --git a/selfdrive/modeld/get_model_metadata.py b/openpilot/selfdrive/modeld/get_model_metadata.py similarity index 100% rename from selfdrive/modeld/get_model_metadata.py rename to openpilot/selfdrive/modeld/get_model_metadata.py diff --git a/openpilot/selfdrive/modeld/helpers.py b/openpilot/selfdrive/modeld/helpers.py new file mode 100644 index 0000000000..608bc6aa64 --- /dev/null +++ b/openpilot/selfdrive/modeld/helpers.py @@ -0,0 +1,59 @@ +import io +import json +import pickle +import shutil +import struct +import tempfile +from pathlib import Path + +MODELS_DIR = Path(__file__).resolve().parent / 'models' +TG_INPUT_DEVICES_PATH = MODELS_DIR / 'tg_input_devices.json' +USBGPU_VID = 0xADD1 +USBGPU_PID = 0x0001 + + +def get_tg_input_devices(process_name: str, usbgpu: bool): + with open(TG_INPUT_DEVICES_PATH) as f: + return json.load(f)[process_name]['default' if not usbgpu else 'usbgpu'] + +def modeld_pkl_path(usbgpu: bool): + prefix = 'big_' if usbgpu else '' + return MODELS_DIR / f'{prefix}driving_tinygrad.pkl' + +def dump_oob(obj, f): + with tempfile.TemporaryFile(dir=".") as tmp: + def buffer_callback(pb: pickle.PickleBuffer): + m = pb.raw() + tmp.write(struct.pack(' bool: + for d in Path("/sys/bus/usb/devices").glob("*"): + try: + if int((d / "idVendor").read_text(), 16) == USBGPU_VID and \ + int((d / "idProduct").read_text(), 16) == USBGPU_PID: + return True + except Exception: + pass + return False diff --git a/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py similarity index 93% rename from selfdrive/modeld/modeld.py rename to openpilot/selfdrive/modeld/modeld.py index 2b276479df..bd4e693fa6 100755 --- a/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -3,11 +3,11 @@ import os os.environ['GMMU'] = '0' # for usbgpu fast loading, noop for qcom from tinygrad.tensor import Tensor import time -import pickle import numpy as np -import cereal.messaging as messaging -from cereal import car, log -from cereal.messaging import PubMaster, SubMaster +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +from openpilot.cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.swaglog import cloudlog @@ -22,14 +22,14 @@ from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState -from openpilot.common.file_chunker import read_file_chunked, get_manifest_path +from openpilot.common.file_chunker import open_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan -from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices +from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices, load_oob from openpilot.sunnypilot.livedelay.helpers import get_lat_delay from openpilot.sunnypilot.modeld_v2.modeld_base import ModelStateBase -PROCESS_NAME = "selfdrive.modeld.modeld" +PROCESS_NAME = "openpilot.selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') LAT_SMOOTH_SECONDS = 0.0 @@ -83,7 +83,7 @@ class ModelState(ModelStateBase): self.LAT_SMOOTH_SECONDS = LAT_SMOOTH_SECONDS input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu) self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV'] - jits = pickle.loads(read_file_chunked(modeld_pkl_path(usbgpu))) + jits = load_oob(open_file_chunked(modeld_pkl_path(usbgpu))) metadata = jits['metadata'] self.input_shapes = metadata['input_shapes'] self.vision_input_names = [k for k in self.input_shapes if 'img' in k] @@ -98,14 +98,14 @@ class ModelState(ModelStateBase): self.parser = Parser() self.frame_buf_params = {k: get_nv12_info(cam_w, cam_h) for k in ('img', 'big_img')} self.run_policy = jits['run_policy'] - self.warp_enqueue = jits[(cam_w,cam_h)] + self.warp = jits[(cam_w,cam_h)] def slice_outputs(self, model_outputs: np.ndarray, output_slices: dict[str, slice]) -> dict[str, np.ndarray]: parsed_model_outputs = {k: model_outputs[np.newaxis, v] for k,v in output_slices.items()} return parsed_model_outputs def run(self, bufs: dict[str, VisionBuf], transforms: dict[str, np.ndarray], - inputs: dict[str, np.ndarray], prepare_only: bool) -> dict[str, np.ndarray] | None: + inputs: dict[str, np.ndarray]) -> dict[str, np.ndarray] | None: for key in bufs.keys(): ptr = np.frombuffer(bufs[key].data, dtype=np.uint8).ctypes.data yuv_size = self.frame_buf_params[key][3] @@ -124,13 +124,10 @@ class ModelState(ModelStateBase): self.npy['tfm'][:,:] = transforms['img'][:,:] self.npy['big_tfm'][:,:] = transforms['big_img'][:,:] - img, big_img = self.warp_enqueue(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) - - if prepare_only: - return None + warped = self.warp(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) outs, = self.run_policy( - **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img + **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, warped=warped ) model_output = outs.numpy()[0] outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) @@ -259,7 +256,8 @@ def main(demo=False): device_from_calib_euler = np.array(sm["liveCalibration"].rpyCalib, dtype=np.float32) dc = DEVICE_CAMERAS[(str(sm['deviceState'].deviceType), str(sm['roadCameraState'].sensor))] model_transform_main = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if main_wide_camera else dc.fcam.intrinsics, False).astype(np.float32) - model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics, True).astype(np.float32) + has_wide_camera = use_extra_client or main_wide_camera + model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if has_wide_camera else dc.fcam.intrinsics, True).astype(np.float32) live_calib_seen = True traffic_convention = np.zeros(2) @@ -278,9 +276,6 @@ def main(demo=False): run_count = run_count + 1 frame_drop_ratio = frames_dropped / (1 + frames_dropped) - prepare_only = vipc_dropped_frames > 0 - if prepare_only: - cloudlog.error(f"skipping model eval. Dropped {vipc_dropped_frames} frames") bufs = {name: buf_extra if 'big' in name else buf_main for name in model.vision_input_names} transforms = {name: model_transform_extra if 'big' in name else model_transform_main for name in model.vision_input_names} @@ -295,7 +290,7 @@ def main(demo=False): } mt1 = time.perf_counter() - model_output = model.run(bufs, transforms, inputs, prepare_only) + model_output = model.run(bufs, transforms, inputs) mt2 = time.perf_counter() model_execution_time = mt2 - mt1 diff --git a/openpilot/selfdrive/modeld/models/README.md b/openpilot/selfdrive/modeld/models/README.md new file mode 100644 index 0000000000..0055a0f1e3 --- /dev/null +++ b/openpilot/selfdrive/modeld/models/README.md @@ -0,0 +1,2 @@ +## Neural networks in openpilot +To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) diff --git a/selfdrive/modeld/__init__.py b/openpilot/selfdrive/modeld/models/__init__.py similarity index 100% rename from selfdrive/modeld/__init__.py rename to openpilot/selfdrive/modeld/models/__init__.py diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx new file mode 100644 index 0000000000..4a04bd7833 --- /dev/null +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a501760a9d1d5fef0eab2b8c5d122d06124fc26dc8e0782e0aa94b82a208f0ff +size 1757355221 diff --git a/selfdrive/modeld/models/dmonitoring_model.onnx b/openpilot/selfdrive/modeld/models/dmonitoring_model.onnx similarity index 100% rename from selfdrive/modeld/models/dmonitoring_model.onnx rename to openpilot/selfdrive/modeld/models/dmonitoring_model.onnx diff --git a/selfdrive/modeld/models/driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/driving_supercombo.onnx similarity index 100% rename from selfdrive/modeld/models/driving_supercombo.onnx rename to openpilot/selfdrive/modeld/models/driving_supercombo.onnx diff --git a/selfdrive/modeld/parse_model_outputs.py b/openpilot/selfdrive/modeld/parse_model_outputs.py similarity index 100% rename from selfdrive/modeld/parse_model_outputs.py rename to openpilot/selfdrive/modeld/parse_model_outputs.py diff --git a/selfdrive/monitoring/dmonitoringd.py b/openpilot/selfdrive/monitoring/dmonitoringd.py similarity index 97% rename from selfdrive/monitoring/dmonitoringd.py rename to openpilot/selfdrive/monitoring/dmonitoringd.py index bedad967b6..085a13fcb1 100755 --- a/selfdrive/monitoring/dmonitoringd.py +++ b/openpilot/selfdrive/monitoring/dmonitoringd.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process from openpilot.selfdrive.monitoring.policy import DriverMonitoring diff --git a/selfdrive/monitoring/policy.py b/openpilot/selfdrive/monitoring/policy.py similarity index 88% rename from selfdrive/monitoring/policy.py rename to openpilot/selfdrive/monitoring/policy.py index 728d4881cd..bfca76ff30 100644 --- a/selfdrive/monitoring/policy.py +++ b/openpilot/selfdrive/monitoring/policy.py @@ -2,8 +2,9 @@ from collections import defaultdict from math import atan2, radians import numpy as np -from cereal import car, log -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_DMON from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params @@ -24,21 +25,27 @@ def to_percent(v): class DRIVER_MONITOR_SETTINGS: def __init__(self): - # https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2 - self._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT = 15. - self._WHEELTOUCH_POLICY_ALERT_2_TIMEOUT = 24. - self._WHEELTOUCH_POLICY_ALERT_3_TIMEOUT = 30. - # https://cdn.euroncap.com/cars/assets/euro_ncap_protocol_safe_driving_driver_engagement_v11_a30e874152.pdf - self._VISION_POLICY_ALERT_1_TIMEOUT = 3. - self._VISION_POLICY_ALERT_2_TIMEOUT = 5. - self._VISION_POLICY_ALERT_3_TIMEOUT = 11. + # https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=OJ:L_202501899 + self._ALERT_MIN_SPEED = 2.8 # 10 km/h + + self._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT = 5. + self._WHEELTOUCH_POLICY_ALERT_2_TIMEOUT = 15. + self._WHEELTOUCH_POLICY_ALERT_3_TIMEOUT = 25. + self._VISION_POLICY_ALERT_1_TIMEOUT = 5. + self._VISION_POLICY_ALERT_2_TIMEOUT = 8. + self._VISION_POLICY_ALERT_3_TIMEOUT = 13. + + # no response = alert_3 sustained for certain amount of time + self._NO_RESPONSE_TIMEOUT = 5. + + # lockout specs + self._MAX_ALERT_3 = 2 + self._MAX_NO_RESPONSE = 1 + self._LOCKOUT_TIME = int(1800 / DT_DMON) self._TIMEOUT_RECOVERY_FACTOR_MAX = 5. self._TIMEOUT_RECOVERY_FACTOR_MIN = 1.25 - self._MAX_TERMINAL_ALERTS = 3 # not allowed to engage after 3 terminal alerts - self._MAX_TERMINAL_DURATION = int(30 / DT_DMON) # not allowed to engage after 30s of terminal alerts - self._FACE_THRESHOLD = 0.7 self._EYE_THRESHOLD = 0.65 self._SG_THRESHOLD = 0.9 @@ -141,8 +148,11 @@ class DriverMonitoring: self.wheel_on_right_last = None self.wheel_on_right_default = rhd_saved self.face_detected = False - self.terminal_alert_cnt = 0 - self.terminal_time = 0 + self.alert_3_cnt = 0 + self.cnt_since_alert_3 = 0 + self.no_response_timeout = int(self.settings._NO_RESPONSE_TIMEOUT / DT_DMON) + self.no_response_cnt = 0 + self.lockout_time = 0 self.step_change = 0. self.active_policy = MonitoringPolicy.vision self.driver_interacting = False @@ -229,7 +239,7 @@ class DriverMonitoring: self.distracted_types['eye'] = bool((self.blink.left + self.blink.right)*0.5 > self.settings._BLINK_THRESHOLD) self.distracted_types['phone'] = bool(self.phone_prob > self.settings._PHONE_THRESH) - def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, standstill, demo_mode=False, steering_angle_deg=0.): + def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, lowspeed, demo_mode=False, steering_angle_deg=0.): rhd_pred = driver_state.wheelOnRightProb # calibrates only when there's movement and either face detected if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or @@ -280,7 +290,7 @@ class DriverMonitoring: if self.face_detected and not self.driver_distracted: dcam_uncertain = self.model_std_max > self.settings._DCAM_UNCERTAIN_ALERT_THRESHOLD - if dcam_uncertain and not standstill: + if dcam_uncertain and not lowspeed: self.dcam_uncertain_cnt += 1 self.dcam_reset_cnt = 0 else: @@ -295,14 +305,22 @@ class DriverMonitoring: elif self.face_detected and self.pose.low_std: self.hi_stds = 0 - def _update_events(self, driver_engaged, op_engaged, standstill, wrong_gear): + def _update_events(self, driver_engaged, op_engaged, lowspeed, wrong_gear): self.alert_level = AlertLevel.none self.driver_interacting = driver_engaged - if self.terminal_alert_cnt >= self.settings._MAX_TERMINAL_ALERTS or \ - self.terminal_time >= self.settings._MAX_TERMINAL_DURATION: + if self.alert_3_cnt >= self.settings._MAX_ALERT_3 or self.no_response_cnt >= self.settings._MAX_NO_RESPONSE: self.too_distracted = True + if self.too_distracted: + self.lockout_time += 1 + if self.lockout_time > self.settings._LOCKOUT_TIME: + self.too_distracted = False + self.alert_3_cnt = 0 + self.cnt_since_alert_3 = 0 + self.no_response_cnt = 0 + self.lockout_time = 0 + always_on_valid = self.always_on and not wrong_gear if (self.driver_interacting and self.awareness > 0 and self.active_policy == MonitoringPolicy.wheeltouch) or \ (not always_on_valid and not op_engaged) or \ @@ -314,11 +332,11 @@ class DriverMonitoring: awareness_prev = self.awareness _reaching_alert_1 = self.awareness - self.step_change <= self.threshold_alert_1 _reaching_alert_3 = self.awareness - self.step_change <= 0 - standstill_exemption = standstill and _reaching_alert_1 + lowspeed_exemption = lowspeed and _reaching_alert_1 always_on_exemption = always_on_valid and not op_engaged and _reaching_alert_3 if self.awareness > 0 and \ - ((self.driver_distraction_filter.x < 0.37 and self.face_detected and self.pose.low_std) or standstill_exemption): + ((self.driver_distraction_filter.x < 0.37 and self.face_detected and self.pose.low_std) or lowspeed_exemption): if self.driver_interacting: self._reset_awareness() return @@ -335,21 +353,26 @@ class DriverMonitoring: maybe_distracted = self.is_model_uncertain or not self.face_detected if certainly_distracted or maybe_distracted: - # should always be counting if distracted unless at standstill and reaching green + # should always be counting if distracted unless at low speed and reaching green # also will not be reaching 0 if DM is active when not engaged - if not (standstill_exemption or always_on_exemption): + if not (lowspeed_exemption or always_on_exemption): self.awareness = max(self.awareness - self.step_change, -0.1) if self.awareness <= 0.: # terminal alert: disengagement required self.alert_level = AlertLevel.three - self.terminal_time += 1 if awareness_prev > 0.: - self.terminal_alert_cnt += 1 - elif self.awareness <= self.threshold_alert_2: - self.alert_level = AlertLevel.two - elif self.awareness <= self.threshold_alert_1: - self.alert_level = AlertLevel.one + self.alert_3_cnt += 1 + self.cnt_since_alert_3 = 0 + else: + self.cnt_since_alert_3 += 1 + if self.cnt_since_alert_3 == self.no_response_timeout: + self.no_response_cnt += 1 + else: + if self.awareness <= self.threshold_alert_2: + self.alert_level = AlertLevel.two + elif self.awareness <= self.threshold_alert_1: + self.alert_level = AlertLevel.one def get_state_packet(self, valid=True): # build driverMonitoringState packet @@ -357,8 +380,10 @@ class DriverMonitoring: dm = dat.driverMonitoringState dm.lockout = self.too_distracted - dm.alertCountLockoutPercent = to_percent(self.terminal_alert_cnt / self.settings._MAX_TERMINAL_ALERTS) - dm.alertTimeLockoutPercent = to_percent(self.terminal_time / self.settings._MAX_TERMINAL_DURATION) + dm.lockoutRecoveryPercent = to_percent(self.lockout_time / self.settings._LOCKOUT_TIME) + dm.alert3Count = self.alert_3_cnt + dm.noResponseCount = self.no_response_cnt + dm.noResponseForceDecel = self.alert_level == AlertLevel.three and self.cnt_since_alert_3 >= self.no_response_timeout dm.alwaysOn = self.always_on dm.alwaysOnLockout = self.always_on and self.awareness <= self.threshold_alert_2 dm.alertLevel = self.alert_level @@ -395,7 +420,7 @@ class DriverMonitoring: car_speed = 30 enabled = True wrong_gear = False - standstill = False + lowspeed = False driver_engaged = False brake_disengage_prob = 1.0 steering_angle_deg = 0.0 @@ -404,7 +429,7 @@ class DriverMonitoring: car_speed = sm['carState'].vEgo enabled = sm['selfdriveState'].enabled or sm['carControl'].latActive wrong_gear = sm['carState'].gearShifter not in (car.CarState.GearShifter.drive, car.CarState.GearShifter.low) - standstill = sm['carState'].standstill + lowspeed = car_speed < self.settings._ALERT_MIN_SPEED driver_engaged = sm['carState'].steeringPressed or (sm['selfdriveState'].enabled and sm['carState'].gasPressed) brake_disengage_prob = sm['modelV2'].meta.disengagePredictions.brakeDisengageProbs[0] # brake disengage prob in next 2s steering_angle_deg = sm['carState'].steeringAngleDeg @@ -421,7 +446,7 @@ class DriverMonitoring: cal_rpy=rpyCalib, car_speed=car_speed, op_engaged=enabled, - standstill=standstill, + lowspeed=lowspeed, demo_mode=demo, steering_angle_deg=steering_angle_deg, ) @@ -430,6 +455,6 @@ class DriverMonitoring: self._update_events( driver_engaged=driver_engaged, op_engaged=enabled, - standstill=standstill, + lowspeed=lowspeed, wrong_gear=wrong_gear, ) diff --git a/selfdrive/monitoring/test_monitoring.py b/openpilot/selfdrive/monitoring/test_monitoring.py similarity index 81% rename from selfdrive/monitoring/test_monitoring.py rename to openpilot/selfdrive/monitoring/test_monitoring.py index f933facdee..e42e72d645 100644 --- a/selfdrive/monitoring/test_monitoring.py +++ b/openpilot/selfdrive/monitoring/test_monitoring.py @@ -1,7 +1,7 @@ -import numpy as np import pytest -from cereal import log, car +from openpilot.cereal import log +from opendbc.car.structs import car from openpilot.common.realtime import DT_DMON from openpilot.selfdrive.monitoring.policy import DriverMonitoring, DRIVER_MONITOR_SETTINGS @@ -50,15 +50,15 @@ always_true = [True] * int(TEST_TIMESPAN / DT_DMON) always_false = [False] * int(TEST_TIMESPAN / DT_DMON) class TestMonitoring: - def _run_seq(self, msgs, interaction, engaged, standstill): + def _run_seq(self, msgs, interaction, engaged, lowspeed): DM = DriverMonitoring() alert_lvls = [] for idx in range(len(msgs)): - DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], standstill[idx]) + DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], lowspeed[idx]) # cal_rpy and car_speed don't matter here # evaluate events at 10Hz for tests - DM._update_events(interaction[idx], engaged[idx], standstill[idx], 0) + DM._update_events(interaction[idx], engaged[idx], lowspeed[idx], 0) alert_lvls.append(DM.alert_level) assert len(alert_lvls) == len(msgs), f"got {len(alert_lvls)} for {len(msgs)} driverState input msgs" return alert_lvls, DM @@ -83,6 +83,25 @@ class TestMonitoring: (TEST_TIMESPAN - 10 - s._VISION_POLICY_ALERT_3_TIMEOUT) / 2) / DT_DMON)] == 3 assert isinstance(d_status.awareness, float) + # engaged, distracted past red and beyond the no-response window -> unavailability response + lockout + def test_distracted_lockout(self): + alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, always_false) + s = d_status.settings + assert alert_lvls[int(DISTRACTED_SECONDS_TO_RED / DT_DMON)] == 3 + assert d_status.alert_3_cnt == 1 + assert d_status.no_response_cnt == s._MAX_NO_RESPONSE + assert d_status.too_distracted + assert d_status.lockout_time > 0 + + # no face -> wheeltouch red, sustained past the no-response timeout -> unavailability response + lockout + def test_invisible_lockout(self): + _, d_status = self._run_seq(always_no_face, always_false, always_true, always_false) + s = d_status.settings + assert d_status.active_policy == log.DriverMonitoringState.MonitoringPolicy.wheeltouch + assert d_status.alert_3_cnt == 1 + assert d_status.no_response_cnt == s._MAX_NO_RESPONSE + assert d_status.too_distracted + # engaged, no face detected the whole time, no action def test_fully_invisible_driver(self): alert_lvls, d_status = self._run_seq(always_no_face, always_false, always_true, always_false) @@ -138,22 +157,22 @@ class TestMonitoring: # engaged, invisible driver, down to orange, driver touches wheel; then down to orange again, driver appears # - both actions should clear the alert, but momentary appearance should not def test_sometimes_transparent_commuter(self): - _visible_time = np.random.choice([0.5, 10]) - ds_vector = always_no_face[:]*2 - interaction_vector = always_false[:]*2 - ds_vector[int((2*INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON):int((2*INVISIBLE_SECONDS_TO_ORANGE+1+_visible_time)/DT_DMON)] = \ - [msg_ATTENTIVE] * int(_visible_time/DT_DMON) - interaction_vector[int((INVISIBLE_SECONDS_TO_ORANGE)/DT_DMON):int((INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON)] = [True] * int(1/DT_DMON) - alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, 2*always_true, 2*always_false) - assert alert_lvls[int(INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)] == 0 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE+0.1)/DT_DMON)] == 0 - if _visible_time == 0.5: - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 1 - elif _visible_time == 10: - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 0 + for _visible_time in (0.5, 10): + ds_vector = always_no_face[:]*2 + interaction_vector = always_false[:]*2 + ds_vector[int((2*INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON):int((2*INVISIBLE_SECONDS_TO_ORANGE+1+_visible_time)/DT_DMON)] = \ + [msg_ATTENTIVE] * int(_visible_time/DT_DMON) + interaction_vector[int((INVISIBLE_SECONDS_TO_ORANGE)/DT_DMON):int((INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON)] = [True] * int(1/DT_DMON) + alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, 2*always_true, 2*always_false) + assert alert_lvls[int(dm_settings._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT/2/DT_DMON)] == 0 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE+0.1)/DT_DMON)] == 0 + if _visible_time == 0.5: + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 2 + elif _visible_time == 10: + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 0 # engaged, invisible driver, down to red, driver appears and then touches wheel, then disengages/reengages # - only disengage will clear the alert @@ -166,7 +185,7 @@ class TestMonitoring: interaction_vector[int((INVISIBLE_SECONDS_TO_RED+_visible_time)/DT_DMON):int((INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON)] = [True] * int(1/DT_DMON) op_vector[int((INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON):int((INVISIBLE_SECONDS_TO_RED+_visible_time+0.5)/DT_DMON)] = [False] * int(0.5/DT_DMON) alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, op_vector, always_false) - assert alert_lvls[int(INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)] == 0 + assert alert_lvls[int(dm_settings._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT/2/DT_DMON)] == 0 assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 assert alert_lvls[int((INVISIBLE_SECONDS_TO_RED-0.1)/DT_DMON)] == 3 assert alert_lvls[int((INVISIBLE_SECONDS_TO_RED+0.5*_visible_time)/DT_DMON)] == 3 @@ -183,9 +202,9 @@ class TestMonitoring: # - should only reach green when stopped, but continues counting down on launch def test_long_traffic_light_victim(self): _redlight_time = 60 # seconds - standstill_vector = always_true[:] - standstill_vector[int(_redlight_time/DT_DMON):] = [False] * int((TEST_TIMESPAN-_redlight_time)/DT_DMON) - alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, standstill_vector) + lowspeed_vector = always_true[:] + lowspeed_vector[int(_redlight_time/DT_DMON):] = [False] * int((TEST_TIMESPAN-_redlight_time)/DT_DMON) + alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, lowspeed_vector) s = d_status.settings assert alert_lvls[int((_redlight_time-0.1)/DT_DMON)] == 0 _alert_1_to_2 = s._VISION_POLICY_ALERT_2_TIMEOUT - s._VISION_POLICY_ALERT_1_TIMEOUT @@ -193,12 +212,12 @@ class TestMonitoring: assert alert_lvls[int((_redlight_time+_alert_1_to_2+0.5)/DT_DMON)] == 2 # engaged, distracted while moving, then car stops after reaching orange - # - should reset timer to pre green at standstill + # - should reset timer to pre green at low speed def test_distracted_then_stops(self): _stop_time = DISTRACTED_SECONDS_TO_ORANGE + 1 # stop 1 second after reaching orange - standstill_vector = always_false[:] - standstill_vector[int(_stop_time/DT_DMON):] = [True] * int((TEST_TIMESPAN-_stop_time)/DT_DMON) - alert_lvls, _ = self._run_seq(always_distracted, always_false, always_true, standstill_vector) + lowspeed_vector = always_false[:] + lowspeed_vector[int(_stop_time/DT_DMON):] = [True] * int((TEST_TIMESPAN-_stop_time)/DT_DMON) + alert_lvls, _ = self._run_seq(always_distracted, always_false, always_true, lowspeed_vector) # just before and briefly after stopping: orange alert; goes away quickly after stopped assert alert_lvls[int((_stop_time+0.1)/DT_DMON)] == 2 assert alert_lvls[int((_stop_time+0.5)/DT_DMON)] == 0 @@ -251,10 +270,10 @@ def test_run_step_engagement(selfdrive_enabled, lat_active, steering, gas, captured = {} orig = dm._update_events - def spy(driver_engaged, op_engaged, standstill, wrong_gear): + def spy(driver_engaged, op_engaged, lowspeed, wrong_gear): captured['driver_engaged'] = driver_engaged captured['op_engaged'] = op_engaged - return orig(driver_engaged, op_engaged, standstill, wrong_gear) + return orig(driver_engaged, op_engaged, lowspeed, wrong_gear) dm._update_events = spy dm.run_step(sm, demo=False) diff --git a/selfdrive/pandad/.gitignore b/openpilot/selfdrive/pandad/.gitignore similarity index 100% rename from selfdrive/pandad/.gitignore rename to openpilot/selfdrive/pandad/.gitignore diff --git a/selfdrive/pandad/SConscript b/openpilot/selfdrive/pandad/SConscript similarity index 100% rename from selfdrive/pandad/SConscript rename to openpilot/selfdrive/pandad/SConscript diff --git a/selfdrive/pandad/__init__.py b/openpilot/selfdrive/pandad/__init__.py similarity index 100% rename from selfdrive/pandad/__init__.py rename to openpilot/selfdrive/pandad/__init__.py diff --git a/selfdrive/pandad/main.cc b/openpilot/selfdrive/pandad/main.cc similarity index 100% rename from selfdrive/pandad/main.cc rename to openpilot/selfdrive/pandad/main.cc diff --git a/selfdrive/pandad/panda.cc b/openpilot/selfdrive/pandad/panda.cc similarity index 98% rename from selfdrive/pandad/panda.cc rename to openpilot/selfdrive/pandad/panda.cc index acb472ab57..cb5266d253 100644 --- a/selfdrive/pandad/panda.cc +++ b/openpilot/selfdrive/pandad/panda.cc @@ -6,7 +6,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" #include "common/util.h" @@ -116,7 +116,7 @@ std::optional Panda::get_serial() { bool Panda::up_to_date() { if (auto fw_sig = get_firmware_version()) { for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed" }) { - auto content = util::read_file(std::string("../../panda/board/obj/") + fn); + auto content = util::read_file(std::string("../../../panda/board/obj/") + fn); if (content.size() >= fw_sig->size() && memcmp(content.data() + content.size() - fw_sig->size(), fw_sig->data(), fw_sig->size()) == 0) { return true; diff --git a/selfdrive/pandad/panda.h b/openpilot/selfdrive/pandad/panda.h similarity index 96% rename from selfdrive/pandad/panda.h rename to openpilot/selfdrive/pandad/panda.h index 9877e5f739..1c5e4a5504 100644 --- a/selfdrive/pandad/panda.h +++ b/openpilot/selfdrive/pandad/panda.h @@ -9,8 +9,8 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "panda/board/health.h" #include "panda/board/can.h" #include "selfdrive/pandad/panda_comms.h" diff --git a/selfdrive/pandad/panda_comms.h b/openpilot/selfdrive/pandad/panda_comms.h similarity index 100% rename from selfdrive/pandad/panda_comms.h rename to openpilot/selfdrive/pandad/panda_comms.h diff --git a/selfdrive/pandad/panda_safety.cc b/openpilot/selfdrive/pandad/panda_safety.cc similarity index 98% rename from selfdrive/pandad/panda_safety.cc rename to openpilot/selfdrive/pandad/panda_safety.cc index 8381256f46..bcec99190a 100644 --- a/selfdrive/pandad/panda_safety.cc +++ b/openpilot/selfdrive/pandad/panda_safety.cc @@ -1,5 +1,5 @@ #include "selfdrive/pandad/pandad.h" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" void PandaSafety::configureSafetyMode(bool is_onroad) { diff --git a/selfdrive/pandad/pandad.cc b/openpilot/selfdrive/pandad/pandad.cc similarity index 99% rename from selfdrive/pandad/pandad.cc rename to openpilot/selfdrive/pandad/pandad.cc index 7ca074dae9..250ad5a481 100644 --- a/selfdrive/pandad/pandad.cc +++ b/openpilot/selfdrive/pandad/pandad.cc @@ -8,9 +8,9 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/messaging/messaging.h" -#include "cereal/services.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" #include "common/ratekeeper.h" #include "common/swaglog.h" #include "common/timing.h" diff --git a/selfdrive/pandad/pandad.h b/openpilot/selfdrive/pandad/pandad.h similarity index 100% rename from selfdrive/pandad/pandad.h rename to openpilot/selfdrive/pandad/pandad.h diff --git a/selfdrive/pandad/pandad.py b/openpilot/selfdrive/pandad/pandad.py similarity index 99% rename from selfdrive/pandad/pandad.py rename to openpilot/selfdrive/pandad/pandad.py index 1b5de9f87e..a618dacccd 100755 --- a/selfdrive/pandad/pandad.py +++ b/openpilot/selfdrive/pandad/pandad.py @@ -129,7 +129,7 @@ def main() -> None: # run real pandad os.environ['MANAGER_DAEMON'] = 'pandad' - process = subprocess.Popen(["./pandad"], cwd=os.path.join(BASEDIR, "selfdrive/pandad")) + process = subprocess.Popen(["./pandad"], cwd=os.path.join(BASEDIR, "openpilot/selfdrive/pandad")) process.wait() # TODO: wrap all panda exceptions in a base panda exception except (usb1.USBErrorNoDevice, usb1.USBErrorPipe): diff --git a/selfdrive/pandad/pandad_api_impl.py b/openpilot/selfdrive/pandad/pandad_api_impl.py similarity index 98% rename from selfdrive/pandad/pandad_api_impl.py rename to openpilot/selfdrive/pandad/pandad_api_impl.py index 75a7ba484e..9da277d73a 100644 --- a/selfdrive/pandad/pandad_api_impl.py +++ b/openpilot/selfdrive/pandad/pandad_api_impl.py @@ -1,5 +1,5 @@ import time -from cereal import log +from openpilot.cereal import log NO_TRAVERSAL_LIMIT = 2**64 - 1 diff --git a/selfdrive/pandad/spi.cc b/openpilot/selfdrive/pandad/spi.cc similarity index 100% rename from selfdrive/pandad/spi.cc rename to openpilot/selfdrive/pandad/spi.cc diff --git a/selfdrive/modeld/models/__init__.py b/openpilot/selfdrive/pandad/tests/__init__.py similarity index 100% rename from selfdrive/modeld/models/__init__.py rename to openpilot/selfdrive/pandad/tests/__init__.py diff --git a/selfdrive/pandad/tests/bootstub.panda_h7.bin b/openpilot/selfdrive/pandad/tests/bootstub.panda_h7.bin similarity index 100% rename from selfdrive/pandad/tests/bootstub.panda_h7.bin rename to openpilot/selfdrive/pandad/tests/bootstub.panda_h7.bin diff --git a/selfdrive/pandad/tests/test_pandad.py b/openpilot/selfdrive/pandad/tests/test_pandad.py similarity index 96% rename from selfdrive/pandad/tests/test_pandad.py rename to openpilot/selfdrive/pandad/tests/test_pandad.py index 88022dda8d..e7a7107dcd 100644 --- a/selfdrive/pandad/tests/test_pandad.py +++ b/openpilot/selfdrive/pandad/tests/test_pandad.py @@ -2,8 +2,8 @@ import os import pytest import time -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from openpilot.common.gpio import gpio_set, gpio_init from panda import Panda, PandaDFU from openpilot.system.manager.process_config import managed_processes diff --git a/selfdrive/pandad/tests/test_pandad_canprotocol.cc b/openpilot/selfdrive/pandad/tests/test_pandad_canprotocol.cc similarity index 98% rename from selfdrive/pandad/tests/test_pandad_canprotocol.cc rename to openpilot/selfdrive/pandad/tests/test_pandad_canprotocol.cc index 8499a1aab8..83339a4c1c 100644 --- a/selfdrive/pandad/tests/test_pandad_canprotocol.cc +++ b/openpilot/selfdrive/pandad/tests/test_pandad_canprotocol.cc @@ -4,7 +4,7 @@ #include #include "catch2/catch.hpp" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/util.h" #include "selfdrive/pandad/panda.h" diff --git a/selfdrive/pandad/tests/test_pandad_loopback.py b/openpilot/selfdrive/pandad/tests/test_pandad_loopback.py similarity index 97% rename from selfdrive/pandad/tests/test_pandad_loopback.py rename to openpilot/selfdrive/pandad/tests/test_pandad_loopback.py index bc90f42a83..0d0aa80046 100644 --- a/selfdrive/pandad/tests/test_pandad_loopback.py +++ b/openpilot/selfdrive/pandad/tests/test_pandad_loopback.py @@ -6,8 +6,9 @@ import pytest from collections import defaultdict from pprint import pprint -import cereal.messaging as messaging -from cereal import car, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car from opendbc.car.can_definitions import CanData from openpilot.common.utils import retry from openpilot.common.params import Params diff --git a/selfdrive/pandad/tests/test_pandad_spi.py b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py similarity index 87% rename from selfdrive/pandad/tests/test_pandad_spi.py rename to openpilot/selfdrive/pandad/tests/test_pandad_spi.py index 50021d8998..02f5accfd6 100644 --- a/selfdrive/pandad/tests/test_pandad_spi.py +++ b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py @@ -4,8 +4,9 @@ import numpy as np import pytest import random -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST +from openpilot.common.timeout import Timeout from openpilot.selfdrive.test.helpers import with_processes from openpilot.selfdrive.pandad.tests.test_pandad_loopback import setup_pandad, send_random_can_messages @@ -26,9 +27,14 @@ class TestBoarddSpi: sendcan = messaging.pub_sock('sendcan') socks = {s: messaging.sub_sock(s, conflate=False, timeout=100) for s in ('can', 'pandaStates', 'peripheralState')} - time.sleep(2) - for s in socks.values(): - messaging.drain_sock_raw(s) + readiness_services = {'pandaStates', 'peripheralState'} + ready = set() + with Timeout(2, "pandad services didn't become ready"): + while not readiness_services <= ready: + for service, sock in socks.items(): + if messaging.drain_sock_raw(sock): + ready.add(service) + time.sleep(0.01) total_recv_count = 0 total_sent_count = 0 diff --git a/selfdrive/selfdrived/alertmanager.py b/openpilot/selfdrive/selfdrived/alertmanager.py similarity index 95% rename from selfdrive/selfdrived/alertmanager.py rename to openpilot/selfdrive/selfdrived/alertmanager.py index c148c62d32..3be56381cf 100644 --- a/selfdrive/selfdrived/alertmanager.py +++ b/openpilot/selfdrive/selfdrived/alertmanager.py @@ -10,7 +10,7 @@ from openpilot.selfdrive.selfdrived.events import Alert from openpilot.sunnypilot.selfdrive.selfdrived.events_base import EmptyAlert -with open(os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json")) as f: +with open(os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json")) as f: OFFROAD_ALERTS = json.load(f) diff --git a/selfdrive/selfdrived/alerts_offroad.json b/openpilot/selfdrive/selfdrived/alerts_offroad.json similarity index 95% rename from selfdrive/selfdrived/alerts_offroad.json rename to openpilot/selfdrive/selfdrived/alerts_offroad.json index 917b0b6ab7..c90497e8c1 100644 --- a/selfdrive/selfdrived/alerts_offroad.json +++ b/openpilot/selfdrive/selfdrived/alerts_offroad.json @@ -17,10 +17,6 @@ "severity": 1, "_comment": "Set extra field to the failed reason." }, - "Offroad_IsTakingSnapshot": { - "text": "Taking camera snapshots. System won't start until finished.", - "severity": 0 - }, "Offroad_NeosUpdate": { "text": "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.", "severity": 0 diff --git a/selfdrive/selfdrived/events.py b/openpilot/selfdrive/selfdrived/events.py similarity index 96% rename from selfdrive/selfdrived/events.py rename to openpilot/selfdrive/selfdrived/events.py index ea9d47d714..d2252e4bd4 100755 --- a/selfdrive/selfdrived/events.py +++ b/openpilot/selfdrive/selfdrived/events.py @@ -2,12 +2,14 @@ import math import os -from cereal import log, car -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.git import get_short_branch -from openpilot.common.realtime import DT_CTRL +from openpilot.common.realtime import DT_CTRL, DT_DMON from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER +from openpilot.selfdrive.monitoring.policy import DRIVER_MONITOR_SETTINGS from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER from openpilot.selfdrive.ui.feedback.feedbackd import FEEDBACK_MAX_DURATION from openpilot.common.hardware import HARDWARE @@ -20,9 +22,10 @@ from openpilot.sunnypilot.selfdrive.selfdrived.events_base import EventsBase, Pr AlertSize = log.SelfdriveState.AlertSize AlertStatus = log.SelfdriveState.AlertStatus VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert EventName = log.OnroadEvent.EventName +DMON_LOCKOUT_TIME = DRIVER_MONITOR_SETTINGS()._LOCKOUT_TIME # get event name from enum EVENT_NAME = {v: k for k, v in EventName.schema.enumerants.items()} @@ -96,6 +99,13 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2) +def too_distracted_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: + if sm['driverMonitoringState'].lockout: + mins_left = max(1, round((100 - sm['driverMonitoringState'].lockoutRecoveryPercent) / 100 * DMON_LOCKOUT_TIME * DT_DMON / 60.)) + return NoEntryAlert("Too Distracted", f"{mins_left} minute{'s' if mins_left != 1 else ''} Left", priority=Priority.HIGH) + return NoEntryAlert("Pay Attention to Engage", priority=Priority.HIGH) + + def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: duration = FEEDBACK_MAX_DURATION - ((sm['audioFeedback'].blockNum + 1) * SAMPLE_BUFFER / SAMPLE_RATE) return NormalPermanentAlert( @@ -343,7 +353,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { "Pay Attention", "", AlertStatus.normal, AlertSize.small, - Priority.LOW, VisualAlert.none, AudibleAlert.none, .1), + Priority.LOW, VisualAlert.none, AudibleAlert.preAlert, .1), }, EventName.driverDistracted2: { @@ -610,7 +620,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { }, EventName.tooDistracted: { - ET.NO_ENTRY: NoEntryAlert("Distraction Level Too High"), + ET.NO_ENTRY: too_distracted_alert, }, EventName.excessiveActuation: { @@ -863,7 +873,7 @@ if HARDWARE.get_device_type() == 'mici': "Pay Attention", "", AlertStatus.normal, AlertSize.small, - Priority.LOW, VisualAlert.none, AudibleAlert.none, 2), + Priority.LOW, VisualAlert.none, AudibleAlert.preAlert, 2), }, EventName.driverDistracted2: { ET.PERMANENT: Alert( @@ -926,7 +936,7 @@ if HARDWARE.get_device_type() == 'mici': if __name__ == '__main__': # print all alerts by type and priority - from cereal.services import SERVICE_LIST + from openpilot.cereal.services import SERVICE_LIST from collections import defaultdict event_names = {v: k for k, v in EventName.schema.enumerants.items()} diff --git a/selfdrive/selfdrived/helpers.py b/openpilot/selfdrive/selfdrived/helpers.py similarity index 96% rename from selfdrive/selfdrived/helpers.py rename to openpilot/selfdrive/selfdrived/helpers.py index f7468cbe43..3b3c44ecaf 100644 --- a/selfdrive/selfdrived/helpers.py +++ b/openpilot/selfdrive/selfdrived/helpers.py @@ -1,7 +1,8 @@ import math from enum import StrEnum, auto -from cereal import car, messaging +from openpilot.cereal import messaging +from opendbc.car.structs import car from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.helpers import Pose from opendbc.car import ACCELERATION_DUE_TO_GRAVITY diff --git a/selfdrive/selfdrived/selfdrived.py b/openpilot/selfdrive/selfdrived/selfdrived.py similarity index 98% rename from selfdrive/selfdrived/selfdrived.py rename to openpilot/selfdrive/selfdrived/selfdrived.py index fcd9461f30..2edc0bce18 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/openpilot/selfdrive/selfdrived/selfdrived.py @@ -3,9 +3,10 @@ import os import time import threading -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging -from cereal import car, log, custom +from openpilot.cereal import log, custom +from opendbc.car.structs import car from msgq.visionipc import VisionIpcClient, VisionStreamType @@ -21,7 +22,7 @@ from openpilot.selfdrive.selfdrived.helpers import ExcessiveActuationCheck from openpilot.selfdrive.selfdrived.state import StateMachine from openpilot.selfdrive.selfdrived.alertmanager import AlertManager, set_offroad_alert -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware import HARDWARE from openpilot.sunnypilot.mads.mads import ModularAssistiveDrivingSystem @@ -222,10 +223,13 @@ class SelfdriveD(CruiseHelper): # Handle DM if not self.CP.notCar: - # Block engaging until ignition cycle after max number or time of distractions + # Block engaging until lockout times out or ignition reset if self.sm['driverMonitoringState'].lockout and not self.dm_lockout_set: self.params.put_bool("DriverTooDistracted", True) self.dm_lockout_set = True + elif not self.sm['driverMonitoringState'].lockout and self.dm_lockout_set: + self.params.remove("DriverTooDistracted") + self.dm_lockout_set = False # No entry conditions if self.sm['driverMonitoringState'].lockout or self.sm['driverMonitoringState'].alwaysOnLockout: self.events.add(EventName.tooDistracted) diff --git a/selfdrive/selfdrived/state.py b/openpilot/selfdrive/selfdrived/state.py similarity index 99% rename from selfdrive/selfdrived/state.py rename to openpilot/selfdrive/selfdrived/state.py index 25c22684ad..eca0019503 100644 --- a/selfdrive/selfdrived/state.py +++ b/openpilot/selfdrive/selfdrived/state.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.selfdrived.events import Events, ET from openpilot.common.realtime import DT_CTRL diff --git a/selfdrive/selfdrived/tests/test_alertmanager.py b/openpilot/selfdrive/selfdrived/tests/test_alertmanager.py similarity index 100% rename from selfdrive/selfdrived/tests/test_alertmanager.py rename to openpilot/selfdrive/selfdrived/tests/test_alertmanager.py diff --git a/selfdrive/selfdrived/tests/test_alerts.py b/openpilot/selfdrive/selfdrived/tests/test_alerts.py similarity index 93% rename from selfdrive/selfdrived/tests/test_alerts.py rename to openpilot/selfdrive/selfdrived/tests/test_alerts.py index 4cad9990be..0210c138da 100644 --- a/selfdrive/selfdrived/tests/test_alerts.py +++ b/openpilot/selfdrive/selfdrived/tests/test_alerts.py @@ -4,8 +4,9 @@ import os import random from PIL import Image, ImageDraw, ImageFont -from cereal import log, car -from cereal.messaging import SubMaster +from openpilot.cereal import log +from opendbc.car.structs import car +from openpilot.cereal.messaging import SubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.events import Alert, EVENTS, ET @@ -14,7 +15,7 @@ from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS AlertSize = log.SelfdriveState.AlertSize -OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json") +OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json") # TODO: add callback alerts ALERTS = [] @@ -47,7 +48,7 @@ class TestAlerts: # ensure alert text doesn't exceed allowed width def test_alert_text_length(self): - font_path = os.path.join(BASEDIR, "selfdrive/assets/fonts") + font_path = os.path.join(BASEDIR, "openpilot/selfdrive/assets/fonts") regular_font_path = os.path.join(font_path, "Inter-SemiBold.ttf") bold_font_path = os.path.join(font_path, "Inter-Bold.ttf") semibold_font_path = os.path.join(font_path, "Inter-SemiBold.ttf") diff --git a/selfdrive/selfdrived/tests/test_state_machine.py b/openpilot/selfdrive/selfdrived/tests/test_state_machine.py similarity index 99% rename from selfdrive/selfdrived/tests/test_state_machine.py rename to openpilot/selfdrive/selfdrived/tests/test_state_machine.py index b720f48f1e..8139e53d2e 100644 --- a/selfdrive/selfdrived/tests/test_state_machine.py +++ b/openpilot/selfdrive/selfdrived/tests/test_state_machine.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.selfdrived.state import StateMachine, SOFT_DISABLE_TIME from openpilot.selfdrive.selfdrived.events import Events, ET, EVENTS, NormalPermanentAlert diff --git a/selfdrive/test/.gitignore b/openpilot/selfdrive/test/.gitignore similarity index 100% rename from selfdrive/test/.gitignore rename to openpilot/selfdrive/test/.gitignore diff --git a/selfdrive/pandad/tests/__init__.py b/openpilot/selfdrive/test/__init__.py similarity index 100% rename from selfdrive/pandad/tests/__init__.py rename to openpilot/selfdrive/test/__init__.py diff --git a/selfdrive/test/cpp_harness.py b/openpilot/selfdrive/test/cpp_harness.py similarity index 100% rename from selfdrive/test/cpp_harness.py rename to openpilot/selfdrive/test/cpp_harness.py diff --git a/selfdrive/test/fuzzy_generation.py b/openpilot/selfdrive/test/fuzzy_generation.py similarity index 99% rename from selfdrive/test/fuzzy_generation.py rename to openpilot/selfdrive/test/fuzzy_generation.py index 9f028a8fc8..c97221ae9e 100644 --- a/selfdrive/test/fuzzy_generation.py +++ b/openpilot/selfdrive/test/fuzzy_generation.py @@ -4,7 +4,7 @@ from typing import Any from collections.abc import Callable from functools import cache -from cereal import log +from openpilot.cereal import log DrawType = Callable[[st.SearchStrategy], Any] diff --git a/selfdrive/test/helpers.py b/openpilot/selfdrive/test/helpers.py similarity index 97% rename from selfdrive/test/helpers.py rename to openpilot/selfdrive/test/helpers.py index 49a8ec60a3..9d954216b8 100644 --- a/selfdrive/test/helpers.py +++ b/openpilot/selfdrive/test/helpers.py @@ -7,10 +7,10 @@ import pytest from functools import wraps -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes -from openpilot.system.version import training_version, terms_version +from openpilot.common.version import training_version, terms_version def set_params_enabled(): diff --git a/selfdrive/test/longitudinal_maneuvers/.gitignore b/openpilot/selfdrive/test/longitudinal_maneuvers/.gitignore similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/.gitignore rename to openpilot/selfdrive/test/longitudinal_maneuvers/.gitignore diff --git a/selfdrive/test/__init__.py b/openpilot/selfdrive/test/longitudinal_maneuvers/__init__.py similarity index 100% rename from selfdrive/test/__init__.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/__init__.py diff --git a/selfdrive/test/longitudinal_maneuvers/maneuver.py b/openpilot/selfdrive/test/longitudinal_maneuvers/maneuver.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/maneuver.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/maneuver.py diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py similarity index 98% rename from selfdrive/test/longitudinal_maneuvers/plant.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/plant.py index 1431e60019..abbd6be1d6 100755 --- a/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py @@ -2,8 +2,8 @@ import time import numpy as np -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import Ratekeeper, DT_MDL from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState from openpilot.selfdrive.modeld.constants import ModelConstants @@ -94,14 +94,14 @@ class Plant: lead.dRel = float(d_rel) lead.yRel = 0.0 lead.vRel = float(v_rel) - lead.aRel = float(a_lead - self.acceleration) lead.vLead = float(v_lead) lead.vLeadK = float(v_lead) lead.aLeadK = float(a_lead) # TODO use real radard logic for this lead.aLeadTau = float(_LEAD_ACCEL_TAU) - lead.status = status + lead.present = status lead.modelProb = float(prob_lead) + lead.radar = True if not self.only_lead2: radar.radarState.leadOne = lead radar.radarState.leadTwo = lead diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/openpilot/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/test_longitudinal.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py diff --git a/openpilot/selfdrive/test/mem_usage.py b/openpilot/selfdrive/test/mem_usage.py new file mode 100644 index 0000000000..1446d0b4dc --- /dev/null +++ b/openpilot/selfdrive/test/mem_usage.py @@ -0,0 +1,209 @@ +import os +from collections import defaultdict + +import numpy as np + +from openpilot.common.utils import tabulate + +DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496" +MB = 1024 * 1024 +TABULATE_OPTS = dict(tablefmt="simple_grid", stralign="center", numalign="center") + + +def _get_procs(): + from openpilot.selfdrive.test.test_onroad import PROCS + return PROCS + + +def is_openpilot_proc(name): + if any(p in name for p in _get_procs()): + return True + # catch openpilot processes not in PROCS (athenad, manager, etc.) + return 'openpilot' in name or name.startswith(('selfdrive.', 'system.')) + + +def get_proc_name(proc): + if len(proc.cmdline) > 0: + return list(proc.cmdline)[0] + return proc.name + + +def pct(val_mb, total_mb): + return val_mb / total_mb * 100 if total_mb else 0 + + +def has_pss(proc_logs): + """Check if logs contain PSS data (new field, not in old logs).""" + try: + for proc in proc_logs[-1].procLog.procs: + if proc.memPss > 0: + return True + except AttributeError: + pass + return False + + +def print_summary(proc_logs, device_states): + mem = proc_logs[-1].procLog.mem + total = mem.total / MB + used = (mem.total - mem.available) / MB + cached = mem.cached / MB + shared = mem.shared / MB + buffers = mem.buffers / MB + + lines = [ + f" Total: {total:.0f} MB", + f" Used (total-avail): {used:.0f} MB ({pct(used, total):.0f}%)", + f" Cached: {cached:.0f} MB ({pct(cached, total):.0f}%) Buffers: {buffers:.0f} MB ({pct(buffers, total):.0f}%)", + f" Shared/MSGQ: {shared:.0f} MB ({pct(shared, total):.0f}%)", + ] + + if device_states: + mem_pcts = [m.deviceState.memoryUsagePercent for m in device_states] + lines.append(f" deviceState memory: {np.min(mem_pcts)}-{np.max(mem_pcts)}% (avg {np.mean(mem_pcts):.0f}%)") + + print("\n-- Memory Summary --") + print("\n".join(lines)) + return total + + +def collect_per_process_mem(proc_logs, use_pss): + """Collect per-process memory samples. Returns {name: {metric: [values_per_sample_in_MB]}}.""" + by_proc = defaultdict(lambda: defaultdict(list)) + + for msg in proc_logs: + sample = defaultdict(lambda: defaultdict(float)) + for proc in msg.procLog.procs: + name = get_proc_name(proc) + sample[name]['rss'] += proc.memRss / MB + if use_pss: + sample[name]['pss'] += proc.memPss / MB + sample[name]['pss_anon'] += proc.memPssAnon / MB + sample[name]['pss_shmem'] += proc.memPssShmem / MB + + for name, metrics in sample.items(): + for metric, val in metrics.items(): + by_proc[name][metric].append(val) + + return by_proc + + +def _has_pss_detail(by_proc) -> bool: + """Check if any process has non-zero pss_anon/pss_shmem (unavailable on some kernels).""" + return any(sum(v.get('pss_anon', [])) > 0 or sum(v.get('pss_shmem', [])) > 0 for v in by_proc.values()) + + +def process_table_rows(by_proc, total_mb, use_pss, show_detail): + """Build table rows. Returns (rows, total_row).""" + mem_key = 'pss' if use_pss else 'rss' + rows = [] + for name in sorted(by_proc, key=lambda n: np.mean(by_proc[n][mem_key]), reverse=True): + m = by_proc[name] + vals = m[mem_key] + avg = round(np.mean(vals)) + row = [name, f"{avg} MB", f"{round(np.max(vals))} MB", f"{round(pct(avg, total_mb), 1)}%"] + if show_detail: + row.append(f"{round(np.mean(m['pss_anon']))} MB") + row.append(f"{round(np.mean(m['pss_shmem']))} MB") + rows.append(row) + + # Total row + total_row = None + if by_proc: + max_samples = max(len(v[mem_key]) for v in by_proc.values()) + totals = [] + for i in range(max_samples): + s = sum(v[mem_key][i] for v in by_proc.values() if i < len(v[mem_key])) + totals.append(s) + avg_total = round(np.mean(totals)) + total_row = ["TOTAL", f"{avg_total} MB", f"{round(np.max(totals))} MB", f"{round(pct(avg_total, total_mb), 1)}%"] + if show_detail: + total_row.append(f"{round(sum(np.mean(v['pss_anon']) for v in by_proc.values()))} MB") + total_row.append(f"{round(sum(np.mean(v['pss_shmem']) for v in by_proc.values()))} MB") + + return rows, total_row + + +def print_process_tables(op_procs, other_procs, total_mb, use_pss): + all_procs = {**op_procs, **other_procs} + show_detail = use_pss and _has_pss_detail(all_procs) + + header = ["process", "avg", "max", "%"] + if show_detail: + header += ["anon", "shmem"] + + op_rows, op_total = process_table_rows(op_procs, total_mb, use_pss, show_detail) + # filter other: >5MB avg and not bare interpreter paths (test infra noise) + other_filtered = {n: v for n, v in other_procs.items() + if np.mean(v['pss' if use_pss else 'rss']) > 5.0 + and os.path.basename(n.split()[0]) not in ('python', 'python3')} + other_rows, other_total = process_table_rows(other_filtered, total_mb, use_pss, show_detail) + + rows = op_rows + if op_total: + rows.append(op_total) + if other_rows: + sep_width = len(header) + rows.append([""] * sep_width) + rows.extend(other_rows) + if other_total: + other_total[0] = "TOTAL (other)" + rows.append(other_total) + + metric = "PSS (no shared double-count)" if use_pss else "RSS (includes shared, overcounts)" + print(f"\n-- Per-Process Memory: {metric} --") + print(tabulate(rows, header, **TABULATE_OPTS)) + + +def print_memory_accounting(proc_logs, op_procs, other_procs, total_mb, use_pss): + last = proc_logs[-1].procLog.mem + used = (last.total - last.available) / MB + shared = last.shared / MB + cached_buf = (last.buffers + last.cached) / MB - shared # shared (MSGQ) is in Cached; separate it + msgq = shared + + mem_key = 'pss' if use_pss else 'rss' + op_total = sum(v[mem_key][-1] for v in op_procs.values()) if op_procs else 0 + other_total = sum(v[mem_key][-1] for v in other_procs.values()) if other_procs else 0 + proc_sum = op_total + other_total + remainder = used - (cached_buf + msgq) - proc_sum + + if not use_pss: + # RSS double-counts shared; add back once to partially correct + remainder += shared + + header = ["", "MB", "%", ""] + label = "PSS" if use_pss else "RSS*" + rows = [ + ["Used (total - avail)", f"{used:.0f}", f"{pct(used, total_mb):.1f}", "memory in use by the system"], + [" Cached + Buffers", f"{cached_buf:.0f}", f"{pct(cached_buf, total_mb):.1f}", "pagecache + fs metadata, reclaimable"], + [" MSGQ (shared)", f"{msgq:.0f}", f"{pct(msgq, total_mb):.1f}", "/dev/shm tmpfs, also in process PSS"], + [f" openpilot {label}", f"{op_total:.0f}", f"{pct(op_total, total_mb):.1f}", "sum of openpilot process memory"], + [f" other {label}", f"{other_total:.0f}", f"{pct(other_total, total_mb):.1f}", "sum of non-openpilot process memory"], + [" kernel/ION/GPU", f"{remainder:.0f}", f"{pct(remainder, total_mb):.1f}", "slab, ION/DMA-BUF, GPU, page tables"], + ] + note = "" if use_pss else " (*RSS overcounts shared mem)" + print(f"\n-- Memory Accounting (last sample){note} --") + print(tabulate(rows, header, tablefmt="simple_grid", stralign="right")) + + +def print_report(proc_logs, device_states=None): + """Print full memory analysis report. Can be called from tests or CLI.""" + if not proc_logs: + print("No procLog messages found") + return + + print(f"{len(proc_logs)} procLog samples, {len(device_states or [])} deviceState samples") + + use_pss = has_pss(proc_logs) + if not use_pss: + print(" (no PSS data — re-record with updated proclogd for accurate numbers)") + + total_mb = print_summary(proc_logs, device_states or []) + + by_proc = collect_per_process_mem(proc_logs, use_pss) + op_procs = {n: v for n, v in by_proc.items() if is_openpilot_proc(n)} + other_procs = {n: v for n, v in by_proc.items() if not is_openpilot_proc(n)} + + print_process_tables(op_procs, other_procs, total_mb, use_pss) + print_memory_accounting(proc_logs, op_procs, other_procs, total_mb, use_pss) diff --git a/selfdrive/test/process_replay/README.md b/openpilot/selfdrive/test/process_replay/README.md similarity index 100% rename from selfdrive/test/process_replay/README.md rename to openpilot/selfdrive/test/process_replay/README.md diff --git a/selfdrive/test/process_replay/__init__.py b/openpilot/selfdrive/test/process_replay/__init__.py similarity index 100% rename from selfdrive/test/process_replay/__init__.py rename to openpilot/selfdrive/test/process_replay/__init__.py diff --git a/selfdrive/test/process_replay/capture.py b/openpilot/selfdrive/test/process_replay/capture.py similarity index 100% rename from selfdrive/test/process_replay/capture.py rename to openpilot/selfdrive/test/process_replay/capture.py diff --git a/selfdrive/test/process_replay/compare_logs.py b/openpilot/selfdrive/test/process_replay/compare_logs.py similarity index 100% rename from selfdrive/test/process_replay/compare_logs.py rename to openpilot/selfdrive/test/process_replay/compare_logs.py diff --git a/selfdrive/test/process_replay/diff_report.py b/openpilot/selfdrive/test/process_replay/diff_report.py similarity index 99% rename from selfdrive/test/process_replay/diff_report.py rename to openpilot/selfdrive/test/process_replay/diff_report.py index 5da78657f4..c6c1f01abd 100644 --- a/selfdrive/test/process_replay/diff_report.py +++ b/openpilot/selfdrive/test/process_replay/diff_report.py @@ -1,6 +1,5 @@ import os from collections import defaultdict - from opendbc.car.tests.car_diff import format_diff, format_numeric_diffs from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs from openpilot.selfdrive.test.process_replay.process_replay import PROC_REPLAY_DIR diff --git a/selfdrive/test/process_replay/migration.py b/openpilot/selfdrive/test/process_replay/migration.py similarity index 99% rename from selfdrive/test/process_replay/migration.py rename to openpilot/selfdrive/test/process_replay/migration.py index 09fdb40b67..e357a0ee22 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/openpilot/selfdrive/test/process_replay/migration.py @@ -5,7 +5,8 @@ import capnp import functools import traceback -from cereal import messaging, car, log +from openpilot.cereal import messaging, log +from opendbc.car.structs import car from opendbc.car.fingerprints import MIGRATION from opendbc.car.toyota.values import EPS_SCALE, ToyotaSafetyFlags from opendbc.car.ford.values import CAR as FORD, FordFlags, FordSafetyFlags @@ -176,8 +177,6 @@ def migrate_liveTracks(msgs): pt.dRel = track.dRel pt.yRel = track.yRel pt.vRel = track.vRel - pt.aRel = track.aRel - pt.measured = True pts.append(pt) new_msg.liveTracks.points = pts diff --git a/selfdrive/test/process_replay/model_replay.py b/openpilot/selfdrive/test/process_replay/model_replay.py similarity index 100% rename from selfdrive/test/process_replay/model_replay.py rename to openpilot/selfdrive/test/process_replay/model_replay.py diff --git a/selfdrive/test/process_replay/process_replay.py b/openpilot/selfdrive/test/process_replay/process_replay.py similarity index 99% rename from selfdrive/test/process_replay/process_replay.py rename to openpilot/selfdrive/test/process_replay/process_replay.py index 432161ceb7..0be5d77251 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/openpilot/selfdrive/test/process_replay/process_replay.py @@ -14,9 +14,9 @@ from tqdm import tqdm import capnp from openpilot.common.hardware.hw import Paths -import cereal.messaging as messaging -from cereal import car -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from opendbc.car.structs import car +from openpilot.cereal.services import SERVICE_LIST from msgq.visionipc import VisionIpcServer, get_endpoint_name as vipc_get_endpoint_name from opendbc.car.can_definitions import CanData from opendbc.car.car_helpers import get_car, interfaces diff --git a/selfdrive/test/process_replay/regen.py b/openpilot/selfdrive/test/process_replay/regen.py similarity index 100% rename from selfdrive/test/process_replay/regen.py rename to openpilot/selfdrive/test/process_replay/regen.py diff --git a/selfdrive/test/process_replay/regen_all.py b/openpilot/selfdrive/test/process_replay/regen_all.py similarity index 100% rename from selfdrive/test/process_replay/regen_all.py rename to openpilot/selfdrive/test/process_replay/regen_all.py diff --git a/selfdrive/test/process_replay/test_fuzzy.py b/openpilot/selfdrive/test/process_replay/test_fuzzy.py similarity index 97% rename from selfdrive/test/process_replay/test_fuzzy.py rename to openpilot/selfdrive/test/process_replay/test_fuzzy.py index 6989f8957f..372b368608 100644 --- a/selfdrive/test/process_replay/test_fuzzy.py +++ b/openpilot/selfdrive/test/process_replay/test_fuzzy.py @@ -4,7 +4,7 @@ from hypothesis import given, HealthCheck, Phase, settings import hypothesis.strategies as st from openpilot.common.parameterized import parameterized -from cereal import log +from openpilot.cereal import log from opendbc.car.toyota.values import CAR as TOYOTA from openpilot.selfdrive.test.fuzzy_generation import FuzzyGenerator import openpilot.selfdrive.test.process_replay.process_replay as pr diff --git a/selfdrive/test/process_replay/test_processes.py b/openpilot/selfdrive/test/process_replay/test_processes.py similarity index 99% rename from selfdrive/test/process_replay/test_processes.py rename to openpilot/selfdrive/test/process_replay/test_processes.py index bc0085534c..d9d827add5 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/openpilot/selfdrive/test/process_replay/test_processes.py @@ -7,7 +7,6 @@ import traceback from collections import defaultdict from tqdm import tqdm from typing import Any - from opendbc.car.car_helpers import interface_names from openpilot.common.git import get_commit from openpilot.tools.lib.openpilotci import get_url diff --git a/selfdrive/test/process_replay/test_regen.py b/openpilot/selfdrive/test/process_replay/test_regen.py similarity index 100% rename from selfdrive/test/process_replay/test_regen.py rename to openpilot/selfdrive/test/process_replay/test_regen.py diff --git a/selfdrive/test/process_replay/vision_meta.py b/openpilot/selfdrive/test/process_replay/vision_meta.py similarity index 100% rename from selfdrive/test/process_replay/vision_meta.py rename to openpilot/selfdrive/test/process_replay/vision_meta.py diff --git a/selfdrive/test/scons_build_test.sh b/openpilot/selfdrive/test/scons_build_test.sh similarity index 89% rename from selfdrive/test/scons_build_test.sh rename to openpilot/selfdrive/test/scons_build_test.sh index d4a0733569..6f6eafcad1 100755 --- a/selfdrive/test/scons_build_test.sh +++ b/openpilot/selfdrive/test/scons_build_test.sh @@ -2,7 +2,7 @@ set -e SCRIPT_DIR=$(dirname "$0") -BASEDIR=$(realpath "$SCRIPT_DIR/../../") +BASEDIR=$(realpath "$SCRIPT_DIR/../../../") cd $BASEDIR # tests that our build system's dependencies are configured properly, diff --git a/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh similarity index 70% rename from selfdrive/test/setup_device_ci.sh rename to openpilot/selfdrive/test/setup_device_ci.sh index 3fe353e72c..60631ce037 100755 --- a/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -3,6 +3,7 @@ set -e set -x + if [ -z "$SOURCE_DIR" ]; then echo "SOURCE_DIR must be set" exit 1 @@ -55,6 +56,28 @@ sleep infinity EOF chmod +x $CONTINUE_PATH +export GIT_LFS_SKIP_SMUDGE=1 +pull_lfs() { + # The big driving model is not used on these devices yet. Keep its pointer in + # the worktree, but don't download or copy the 1.8 GB LFS object. + LFS_EXCLUDE="openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx" + + git config --local lfs.fetchexclude "$LFS_EXCLUDE" + git lfs pull --exclude="$LFS_EXCLUDE" + if git cat-file -e "HEAD:$LFS_EXCLUDE"; then + rm -f "$LFS_EXCLUDE" + git checkout -- "$LFS_EXCLUDE" + + # `git lfs prune` retains objects referenced by HEAD, even when excluded. + # Remove this one explicitly so safe checkout doesn't rsync it either. + oid=$(git show "HEAD:$LFS_EXCLUDE" | sed -n 's/^oid sha256://p') + lfs_objects=$(git lfs env | sed -n 's/^LocalMediaDir=//p') + if [[ "$oid" =~ ^[0-9a-f]{64}$ && -n "$lfs_objects" ]]; then + rm -f "$lfs_objects/${oid:0:2}/${oid:2:2}/$oid" + fi + fi +} + safe_checkout() { # completely clean TEST_DIR @@ -74,8 +97,7 @@ safe_checkout() { git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -xdff" - git lfs pull - (ulimit -n 65535 && git lfs prune) + pull_lfs echo "git checkout done, t=$SECONDS" du -hs $SOURCE_DIR $SOURCE_DIR/.git @@ -100,8 +122,7 @@ unsafe_checkout() {( set -e git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -df" - git lfs pull - (ulimit -n 65535 && git lfs prune) + pull_lfs )} export GIT_PACK_THREADS=8 @@ -124,4 +145,12 @@ else safe_checkout fi +# submodule package symlinks for PYTHONPATH imports on device (same as launch_chffrplus.sh) +cd $TEST_DIR +ln -sfn msgq_repo/msgq msgq +ln -sfn opendbc_repo/opendbc opendbc +ln -sfn rednose_repo/rednose rednose +ln -sfn teleoprtc_repo/teleoprtc teleoprtc +ln -sfn tinygrad_repo/tinygrad tinygrad + echo "$TEST_DIR synced with $GIT_COMMIT, t=$SECONDS" diff --git a/selfdrive/test/test_onroad.py b/openpilot/selfdrive/test/test_onroad.py similarity index 90% rename from selfdrive/test/test_onroad.py rename to openpilot/selfdrive/test/test_onroad.py index 99d0279c4c..b15d890452 100644 --- a/selfdrive/test/test_onroad.py +++ b/openpilot/selfdrive/test/test_onroad.py @@ -10,9 +10,9 @@ from collections import Counter, defaultdict from pathlib import Path from openpilot.common.utils import tabulate -from cereal import log -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR from openpilot.common.timeout import Timeout from openpilot.common.params import Params @@ -35,40 +35,39 @@ LOG_OFFSET = 8 MAX_TOTAL_CPU = 350. # total for all 8 cores PROCS = { # Baseline CPU usage by process - "selfdrive.controls.controlsd": 16.0, - "selfdrive.selfdrived.selfdrived": 16.0, - "selfdrive.car.card": 26.0, + "openpilot.selfdrive.controls.controlsd": 16.0, + "openpilot.selfdrive.selfdrived.selfdrived": 16.0, + "openpilot.selfdrive.car.card": 26.0, "./loggerd": 14.0, "./encoderd": 13.0, "./camerad": 10.0, - "selfdrive.controls.plannerd": 8.0, - "selfdrive.ui.ui": 40.0, - "system.sensord.sensord": 13.0, - "selfdrive.controls.radard": 2.0, - "selfdrive.modeld.modeld": 22.0, - "selfdrive.modeld.dmonitoringmodeld": 18.0, - "system.hardware.hardwared": 4.0, - "selfdrive.locationd.calibrationd": 2.0, - "selfdrive.locationd.torqued": 5.0, - "selfdrive.locationd.locationd": 25.0, - "selfdrive.locationd.paramsd": 9.0, - "selfdrive.locationd.lagd": 11.0, - "selfdrive.ui.soundd": 3.0, - "selfdrive.ui.feedback.feedbackd": 1.0, - "selfdrive.monitoring.dmonitoringd": 4.0, - "system.proclogd": 7.0, - "system.logmessaged": 1.0, - "system.tombstoned": 0, - "system.journald": 1.0, - "system.micd": 5.0, - "system.timed": 0, - "selfdrive.pandad.pandad": 0, - "system.statsd": 1.0, - "system.loggerd.uploader": 15.0, - "system.loggerd.deleter": 1.0, + "openpilot.selfdrive.controls.plannerd": 8.0, + "openpilot.selfdrive.ui.ui": 40.0, + "openpilot.system.sensord.sensord": 13.0, + "openpilot.selfdrive.controls.radard": 2.0, + "openpilot.selfdrive.modeld.modeld": 22.0, + "openpilot.selfdrive.modeld.dmonitoringmodeld": 18.0, + "openpilot.system.hardware.hardwared": 4.0, + "openpilot.selfdrive.locationd.calibrationd": 2.0, + "openpilot.selfdrive.locationd.torqued": 5.0, + "openpilot.selfdrive.locationd.locationd": 25.0, + "openpilot.selfdrive.locationd.paramsd": 9.0, + "openpilot.selfdrive.locationd.lagd": 11.0, + "openpilot.selfdrive.ui.soundd": 3.0, + "openpilot.selfdrive.ui.feedback.feedbackd": 1.0, + "openpilot.selfdrive.monitoring.dmonitoringd": 4.0, + "openpilot.system.proclogd": 7.0, + "openpilot.system.logmessaged": 1.0, + "openpilot.system.tombstoned": 0, + "openpilot.system.journald": 1.0, + "openpilot.system.micd": 5.0, + "openpilot.system.timed": 0, + "openpilot.selfdrive.pandad.pandad": 0, + "openpilot.system.loggerd.uploader": 15.0, + "openpilot.system.loggerd.deleter": 1.0, "./pandad": 19.0, - "system.qcomgpsd.qcomgpsd": 1.0, - "common.hardware.tici.modem": 10.0, + "openpilot.system.qcomgpsd.qcomgpsd": 1.0, + "openpilot.common.hardware.tici.modem": 10.0, } TIMINGS = { @@ -130,7 +129,7 @@ class TestOnroad: # start manager and run openpilot for TEST_DURATION proc = None try: - manager_path = os.path.join(BASEDIR, "system/manager/manager.py") + manager_path = os.path.join(BASEDIR, "openpilot/system/manager/manager.py") cls.manager_st = time.monotonic() proc = subprocess.Popen(["python", manager_path]) @@ -176,8 +175,9 @@ class TestOnroad: if s in ('ubloxGnss', 'ubloxRaw', 'gnssMeasurements', 'gpsLocation', 'gpsLocationExternal', 'qcomGnss'): continue + duration = TEST_DURATION - 5.0 # subtract some selfdrived initializing time with subtests.test(service=s): - assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*int(TEST_DURATION*0.8)) + assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*int(duration*0.8)) def test_manager_starting_time(self): st = self.ts['managerState']['t'][0] @@ -284,7 +284,7 @@ class TestOnroad: print("--------------- Memory Usage -------------------") print("------------------------------------------------") - from openpilot.tools.scripts.mem_usage import print_report + from openpilot.selfdrive.test.mem_usage import print_report print_report(self.msgs['procLog'], self.msgs['deviceState']) offset = int(SERVICE_LIST['deviceState'].frequency * LOG_OFFSET) diff --git a/selfdrive/test/test_power_draw.py b/openpilot/selfdrive/test/test_power_draw.py similarity index 95% rename from selfdrive/test/test_power_draw.py rename to openpilot/selfdrive/test/test_power_draw.py index ad27292945..9bc012ceaa 100644 --- a/selfdrive/test/test_power_draw.py +++ b/openpilot/selfdrive/test/test_power_draw.py @@ -5,8 +5,8 @@ import numpy as np from dataclasses import dataclass from openpilot.common.utils import tabulate -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.mock import mock_messages from openpilot.common.params import Params @@ -14,7 +14,7 @@ from openpilot.common.hardware.tici.power_monitor import get_power from openpilot.system.manager.process_config import managed_processes from openpilot.system.manager.manager import manager_cleanup -SAMPLE_TIME = 8 # seconds to sample power +SAMPLE_TIME = 2 # seconds to sample power MAX_WARMUP_TIME = 30 # seconds to wait for SAMPLE_TIME consecutive valid samples @dataclass @@ -44,9 +44,6 @@ class TestPowerDraw: def setup_method(self): Params().put("CarParams", get_demo_car_params().to_bytes(), block=True) - # wait a bit for power save to disable - time.sleep(5) - def teardown_method(self): manager_cleanup() diff --git a/selfdrive/test/update_ci_routes.py b/openpilot/selfdrive/test/update_ci_routes.py similarity index 99% rename from selfdrive/test/update_ci_routes.py rename to openpilot/selfdrive/test/update_ci_routes.py index 54e1c88718..40f74ee93c 100755 --- a/selfdrive/test/update_ci_routes.py +++ b/openpilot/selfdrive/test/update_ci_routes.py @@ -6,7 +6,6 @@ import sys from collections.abc import Iterable from tqdm import tqdm - from opendbc.car.tests.routes import routes as test_car_models_routes from openpilot.selfdrive.test.process_replay.test_processes import source_segments as replay_segments from openpilot.tools.lib.azure_container import AzureContainer diff --git a/selfdrive/ui/.gitignore b/openpilot/selfdrive/ui/.gitignore similarity index 100% rename from selfdrive/ui/.gitignore rename to openpilot/selfdrive/ui/.gitignore diff --git a/selfdrive/ui/SConscript b/openpilot/selfdrive/ui/SConscript similarity index 92% rename from selfdrive/ui/SConscript rename to openpilot/selfdrive/ui/SConscript index 3d668aef8f..d187b4ca3c 100644 --- a/selfdrive/ui/SConscript +++ b/openpilot/selfdrive/ui/SConscript @@ -4,8 +4,8 @@ import importlib.util Import('env', 'arch', 'common') # build the fonts -generator = File("#selfdrive/assets/fonts/process.py") -source_files = Glob("#selfdrive/assets/fonts/*.ttf") + Glob("#selfdrive/assets/fonts/*.otf") +generator = File("#openpilot/selfdrive/assets/fonts/process.py") +source_files = Glob("#openpilot/selfdrive/assets/fonts/*.ttf") + Glob("#openpilot/selfdrive/assets/fonts/*.otf") output_files = [ (f"#{Path(f.path).with_suffix('.fnt')}", f"#{Path(f.path).with_suffix('.png')}") for f in source_files diff --git a/selfdrive/ui/__init__.py b/openpilot/selfdrive/ui/__init__.py similarity index 100% rename from selfdrive/ui/__init__.py rename to openpilot/selfdrive/ui/__init__.py diff --git a/selfdrive/test/longitudinal_maneuvers/__init__.py b/openpilot/selfdrive/ui/body/__init__.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/__init__.py rename to openpilot/selfdrive/ui/body/__init__.py diff --git a/selfdrive/ui/body/animations.py b/openpilot/selfdrive/ui/body/animations.py similarity index 100% rename from selfdrive/ui/body/animations.py rename to openpilot/selfdrive/ui/body/animations.py diff --git a/selfdrive/ui/body/__init__.py b/openpilot/selfdrive/ui/body/layouts/__init__.py similarity index 100% rename from selfdrive/ui/body/__init__.py rename to openpilot/selfdrive/ui/body/layouts/__init__.py diff --git a/selfdrive/ui/body/layouts/onroad.py b/openpilot/selfdrive/ui/body/layouts/onroad.py similarity index 100% rename from selfdrive/ui/body/layouts/onroad.py rename to openpilot/selfdrive/ui/body/layouts/onroad.py diff --git a/selfdrive/ui/feedback/feedbackd.py b/openpilot/selfdrive/ui/feedback/feedbackd.py similarity index 97% rename from selfdrive/ui/feedback/feedbackd.py rename to openpilot/selfdrive/ui/feedback/feedbackd.py index 24f27874eb..8056a580c6 100755 --- a/selfdrive/ui/feedback/feedbackd.py +++ b/openpilot/selfdrive/ui/feedback/feedbackd.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog -from cereal import car +from opendbc.car.structs import car from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER FEEDBACK_MAX_DURATION = 10.0 diff --git a/selfdrive/ui/installer/continue_openpilot.sh b/openpilot/selfdrive/ui/installer/continue_openpilot.sh similarity index 100% rename from selfdrive/ui/installer/continue_openpilot.sh rename to openpilot/selfdrive/ui/installer/continue_openpilot.sh diff --git a/selfdrive/ui/installer/installer.cc b/openpilot/selfdrive/ui/installer/installer.cc similarity index 100% rename from selfdrive/ui/installer/installer.cc rename to openpilot/selfdrive/ui/installer/installer.cc diff --git a/selfdrive/ui/installer/inter-ascii.ttf b/openpilot/selfdrive/ui/installer/inter-ascii.ttf similarity index 100% rename from selfdrive/ui/installer/inter-ascii.ttf rename to openpilot/selfdrive/ui/installer/inter-ascii.ttf diff --git a/selfdrive/ui/body/layouts/__init__.py b/openpilot/selfdrive/ui/layouts/__init__.py similarity index 100% rename from selfdrive/ui/body/layouts/__init__.py rename to openpilot/selfdrive/ui/layouts/__init__.py diff --git a/selfdrive/ui/layouts/home.py b/openpilot/selfdrive/ui/layouts/home.py similarity index 100% rename from selfdrive/ui/layouts/home.py rename to openpilot/selfdrive/ui/layouts/home.py diff --git a/selfdrive/ui/layouts/main.py b/openpilot/selfdrive/ui/layouts/main.py similarity index 99% rename from selfdrive/ui/layouts/main.py rename to openpilot/selfdrive/ui/layouts/main.py index 1e599f4ea7..134e925b16 100644 --- a/selfdrive/ui/layouts/main.py +++ b/openpilot/selfdrive/ui/layouts/main.py @@ -1,6 +1,6 @@ import pyray as rl from enum import IntEnum -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets import Widget from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH diff --git a/selfdrive/ui/layouts/onboarding.py b/openpilot/selfdrive/ui/layouts/onboarding.py similarity index 96% rename from selfdrive/ui/layouts/onboarding.py rename to openpilot/selfdrive/ui/layouts/onboarding.py index 6e683c0922..df14415c60 100644 --- a/selfdrive/ui/layouts/onboarding.py +++ b/openpilot/selfdrive/ui/layouts/onboarding.py @@ -11,7 +11,7 @@ from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.label import Label from openpilot.selfdrive.ui.ui_state import ui_state -from openpilot.system.version import terms_version, training_version, terms_version_sp +from openpilot.common.version import terms_version, training_version, terms_version_sp from openpilot.selfdrive.ui.sunnypilot.layouts.onboarding import SunnylinkOnboarding @@ -53,9 +53,9 @@ class TrainingGuide(Widget): threading.Thread(target=self._preload_thread, daemon=True).start() def _load_image_paths(self): - paths = [fn for fn in os.listdir(os.path.join(BASEDIR, "selfdrive/assets/training")) if re.match(r'^step\d*\.png$', fn)] + paths = [fn for fn in os.listdir(os.path.join(BASEDIR, "openpilot/selfdrive/assets/training")) if re.match(r'^step\d*\.png$', fn)] paths = sorted(paths, key=lambda x: int(re.search(r'\d+', x).group())) - self._image_paths = [os.path.join(BASEDIR, "selfdrive/assets/training", fn) for fn in paths] + self._image_paths = [os.path.join(BASEDIR, "openpilot/selfdrive/assets/training", fn) for fn in paths] def _preload_thread(self): # PNG loading is slow in raylib, so we preload in a thread and upload to GPU in main thread diff --git a/selfdrive/ui/layouts/settings/common.py b/openpilot/selfdrive/ui/layouts/settings/common.py similarity index 100% rename from selfdrive/ui/layouts/settings/common.py rename to openpilot/selfdrive/ui/layouts/settings/common.py diff --git a/selfdrive/ui/layouts/settings/developer.py b/openpilot/selfdrive/ui/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/layouts/settings/developer.py rename to openpilot/selfdrive/ui/layouts/settings/developer.py diff --git a/selfdrive/ui/layouts/settings/device.py b/openpilot/selfdrive/ui/layouts/settings/device.py similarity index 98% rename from selfdrive/ui/layouts/settings/device.py rename to openpilot/selfdrive/ui/layouts/settings/device.py index 2e0493c8d3..5671f309e3 100644 --- a/selfdrive/ui/layouts/settings/device.py +++ b/openpilot/selfdrive/ui/layouts/settings/device.py @@ -1,7 +1,7 @@ import os import math -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog @@ -188,7 +188,7 @@ class DeviceLayout(Widget): def _on_regulatory(self): if not self._fcc_dialog: - self._fcc_dialog = HtmlModal(os.path.join(BASEDIR, "selfdrive/assets/offroad/fcc.html")) + self._fcc_dialog = HtmlModal(os.path.join(BASEDIR, "openpilot/selfdrive/assets/offroad/fcc.html")) gui_app.push_widget(self._fcc_dialog) def _on_review_training_guide(self): diff --git a/selfdrive/ui/layouts/settings/firehose.py b/openpilot/selfdrive/ui/layouts/settings/firehose.py similarity index 100% rename from selfdrive/ui/layouts/settings/firehose.py rename to openpilot/selfdrive/ui/layouts/settings/firehose.py diff --git a/selfdrive/ui/layouts/settings/settings.py b/openpilot/selfdrive/ui/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/layouts/settings/settings.py rename to openpilot/selfdrive/ui/layouts/settings/settings.py diff --git a/selfdrive/ui/layouts/settings/software.py b/openpilot/selfdrive/ui/layouts/settings/software.py similarity index 96% rename from selfdrive/ui/layouts/settings/software.py rename to openpilot/selfdrive/ui/layouts/settings/software.py index 4ed9f8fe19..d0016797fc 100644 --- a/selfdrive/ui/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/layouts/settings/software.py @@ -1,4 +1,4 @@ -import os +import subprocess import time import datetime from openpilot.common.time_helpers import system_time_valid @@ -160,12 +160,12 @@ class SoftwareLayout(Widget): # Start checking for updates self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) else: # Start downloading self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGHUP -f system.updated.updated") + subprocess.run("pkill -SIGHUP -f openpilot.system.updated.updated", shell=True) def _on_uninstall(self): def handle_uninstall_confirmation(result: DialogResult): @@ -199,7 +199,7 @@ class SoftwareLayout(Widget): selection = self._branch_dialog.selection ui_state.params.put("UpdaterTargetBranch", selection, block=True) self._branch_btn.action_item.set_value(selection) - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) self._branch_dialog = None self._branch_dialog = MultiOptionDialog(tr("Select a branch"), branches, current_target, callback=handle_selection) diff --git a/selfdrive/ui/layouts/settings/toggles.py b/openpilot/selfdrive/ui/layouts/settings/toggles.py similarity index 99% rename from selfdrive/ui/layouts/settings/toggles.py rename to openpilot/selfdrive/ui/layouts/settings/toggles.py index 4c83584ad5..ee76b7e4cc 100644 --- a/selfdrive/ui/layouts/settings/toggles.py +++ b/openpilot/selfdrive/ui/layouts/settings/toggles.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.params import Params, UnknownKeyName from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.list_view import multiple_button_item, toggle_item diff --git a/selfdrive/ui/layouts/sidebar.py b/openpilot/selfdrive/ui/layouts/sidebar.py similarity index 99% rename from selfdrive/ui/layouts/sidebar.py rename to openpilot/selfdrive/ui/layouts/sidebar.py index 3405667245..b892e5bfe8 100644 --- a/selfdrive/ui/layouts/sidebar.py +++ b/openpilot/selfdrive/ui/layouts/sidebar.py @@ -2,7 +2,7 @@ import pyray as rl import time from dataclasses import dataclass from collections.abc import Callable -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos, FONT_SCALE from openpilot.system.ui.lib.multilang import tr, tr_noop diff --git a/selfdrive/ui/lib/api_helpers.py b/openpilot/selfdrive/ui/lib/api_helpers.py similarity index 100% rename from selfdrive/ui/lib/api_helpers.py rename to openpilot/selfdrive/ui/lib/api_helpers.py diff --git a/selfdrive/ui/lib/prime_state.py b/openpilot/selfdrive/ui/lib/prime_state.py similarity index 100% rename from selfdrive/ui/lib/prime_state.py rename to openpilot/selfdrive/ui/lib/prime_state.py diff --git a/selfdrive/ui/layouts/__init__.py b/openpilot/selfdrive/ui/mici/layouts/__init__.py similarity index 100% rename from selfdrive/ui/layouts/__init__.py rename to openpilot/selfdrive/ui/mici/layouts/__init__.py diff --git a/selfdrive/ui/mici/layouts/home.py b/openpilot/selfdrive/ui/mici/layouts/home.py similarity index 99% rename from selfdrive/ui/mici/layouts/home.py rename to openpilot/selfdrive/ui/mici/layouts/home.py index d41165a79d..1f05958781 100644 --- a/selfdrive/ui/mici/layouts/home.py +++ b/openpilot/selfdrive/ui/mici/layouts/home.py @@ -1,7 +1,7 @@ import datetime import time -from cereal import log +from openpilot.cereal import log import pyray as rl from collections.abc import Callable from openpilot.system.ui.widgets import Widget @@ -10,7 +10,7 @@ from openpilot.system.ui.widgets.icon_widget import IconWidget from openpilot.system.ui.widgets.label import UnifiedLabel, gui_label from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos from openpilot.selfdrive.ui.ui_state import ui_state -from openpilot.system.version import RELEASE_BRANCHES +from openpilot.common.version import RELEASE_BRANCHES HEAD_BUTTON_FONT_SIZE = 40 HOME_PADDING = 8 diff --git a/selfdrive/ui/mici/layouts/main.py b/openpilot/selfdrive/ui/mici/layouts/main.py similarity index 99% rename from selfdrive/ui/mici/layouts/main.py rename to openpilot/selfdrive/ui/mici/layouts/main.py index e25b2840f7..47e3779ab2 100644 --- a/selfdrive/ui/mici/layouts/main.py +++ b/openpilot/selfdrive/ui/mici/layouts/main.py @@ -1,5 +1,5 @@ import pyray as rl -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout from openpilot.selfdrive.ui.mici.layouts.settings.settings import SettingsLayout from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts diff --git a/selfdrive/ui/mici/layouts/offroad_alerts.py b/openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py similarity index 100% rename from selfdrive/ui/mici/layouts/offroad_alerts.py rename to openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py diff --git a/selfdrive/ui/mici/layouts/onboarding.py b/openpilot/selfdrive/ui/mici/layouts/onboarding.py similarity index 99% rename from selfdrive/ui/mici/layouts/onboarding.py rename to openpilot/selfdrive/ui/mici/layouts/onboarding.py index f070ec5d5c..3c5ad27a17 100644 --- a/selfdrive/ui/mici/layouts/onboarding.py +++ b/openpilot/selfdrive/ui/mici/layouts/onboarding.py @@ -12,8 +12,8 @@ from openpilot.system.ui.widgets.nav_widget import NavWidget from openpilot.system.ui.mici_setup import GreyBigButton, BigPillButton from openpilot.system.ui.widgets.label import gui_label from openpilot.system.ui.lib.multilang import tr -from openpilot.system.version import terms_version, training_version, terms_version_sp -from openpilot.system.version import sunnylink_consent_version, sunnylink_consent_declined +from openpilot.common.version import terms_version, training_version, terms_version_sp +from openpilot.common.version import sunnylink_consent_version, sunnylink_consent_declined from openpilot.selfdrive.ui.ui_state import ui_state, device from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer diff --git a/selfdrive/ui/mici/layouts/settings/developer.py b/openpilot/selfdrive/ui/mici/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/developer.py rename to openpilot/selfdrive/ui/mici/layouts/settings/developer.py diff --git a/selfdrive/ui/mici/layouts/settings/device.py b/openpilot/selfdrive/ui/mici/layouts/settings/device.py similarity index 98% rename from selfdrive/ui/mici/layouts/settings/device.py rename to openpilot/selfdrive/ui/mici/layouts/settings/device.py index fd8bacf441..0adcf53752 100644 --- a/selfdrive/ui/mici/layouts/settings/device.py +++ b/openpilot/selfdrive/ui/mici/layouts/settings/device.py @@ -215,5 +215,5 @@ class DeviceLayoutMici(NavScroller): def _on_regulatory(self): if not self._fcc_dialog: - self._fcc_dialog = MiciFccModal(os.path.join(BASEDIR, "selfdrive/assets/offroad/mici_fcc.html")) + self._fcc_dialog = MiciFccModal(os.path.join(BASEDIR, "openpilot/selfdrive/assets/offroad/mici_fcc.html")) gui_app.push_widget(self._fcc_dialog) diff --git a/selfdrive/ui/mici/layouts/settings/firehose.py b/openpilot/selfdrive/ui/mici/layouts/settings/firehose.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/firehose.py rename to openpilot/selfdrive/ui/mici/layouts/settings/firehose.py diff --git a/selfdrive/ui/mici/layouts/settings/network/__init__.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/__init__.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/__init__.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/__init__.py diff --git a/selfdrive/ui/mici/layouts/settings/network/network_layout.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/network_layout.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py diff --git a/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/wifi_ui.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py diff --git a/selfdrive/ui/mici/layouts/settings/settings.py b/openpilot/selfdrive/ui/mici/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/settings.py rename to openpilot/selfdrive/ui/mici/layouts/settings/settings.py diff --git a/selfdrive/ui/mici/layouts/settings/software.py b/openpilot/selfdrive/ui/mici/layouts/settings/software.py similarity index 97% rename from selfdrive/ui/mici/layouts/settings/software.py rename to openpilot/selfdrive/ui/mici/layouts/settings/software.py index 8f451cdd0c..d71982ca26 100644 --- a/selfdrive/ui/mici/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/mici/layouts/settings/software.py @@ -1,4 +1,4 @@ -import os +import subprocess import threading import pyray as rl from enum import IntEnum @@ -103,9 +103,9 @@ class CheckUpdateButton(BigButton): def run(): if self.get_value() == "download update": - os.system("pkill -SIGHUP -f system.updated.updated") + subprocess.run("pkill -SIGHUP -f openpilot.system.updated.updated", shell=True) else: - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) threading.Thread(target=run, daemon=True).start() @@ -251,7 +251,7 @@ class TargetBranchButton(BigButton): def _on_select(self, branch: str): ui_state.params.put("UpdaterTargetBranch", branch, block=True) self.set_value(branch) - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) class SoftwareLayoutMici(NavScroller): diff --git a/selfdrive/ui/mici/layouts/settings/toggles.py b/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py similarity index 99% rename from selfdrive/ui/mici/layouts/settings/toggles.py rename to openpilot/selfdrive/ui/mici/layouts/settings/toggles.py index 8635336f97..52bbb65e6a 100644 --- a/selfdrive/ui/mici/layouts/settings/toggles.py +++ b/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.system.ui.widgets.scroller import NavScroller from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle diff --git a/selfdrive/ui/mici/onroad/__init__.py b/openpilot/selfdrive/ui/mici/onroad/__init__.py similarity index 100% rename from selfdrive/ui/mici/onroad/__init__.py rename to openpilot/selfdrive/ui/mici/onroad/__init__.py diff --git a/selfdrive/ui/mici/onroad/alert_renderer.py b/openpilot/selfdrive/ui/mici/onroad/alert_renderer.py similarity index 99% rename from selfdrive/ui/mici/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/alert_renderer.py index 6a227edec4..016e09a0f1 100644 --- a/selfdrive/ui/mici/onroad/alert_renderer.py +++ b/openpilot/selfdrive/ui/mici/onroad/alert_renderer.py @@ -5,7 +5,8 @@ import pyray as rl import random import string from dataclasses import dataclass -from cereal import messaging, log, car +from openpilot.cereal import messaging, log +from opendbc.car.structs import car from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.filter_simple import BounceFilter, FirstOrderFilter from openpilot.common.hardware import TICI diff --git a/selfdrive/ui/mici/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py similarity index 99% rename from selfdrive/ui/mici/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py index 2d437fd700..b5b9a54be8 100644 --- a/selfdrive/ui/mici/onroad/augmented_road_view.py +++ b/openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py @@ -1,6 +1,7 @@ import numpy as np import pyray as rl -from cereal import car, log +from openpilot.cereal import log +from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus from openpilot.selfdrive.ui.mici.onroad import SIDE_PANEL_WIDTH diff --git a/selfdrive/ui/mici/onroad/cameraview.py b/openpilot/selfdrive/ui/mici/onroad/cameraview.py similarity index 100% rename from selfdrive/ui/mici/onroad/cameraview.py rename to openpilot/selfdrive/ui/mici/onroad/cameraview.py diff --git a/selfdrive/ui/mici/onroad/confidence_ball.py b/openpilot/selfdrive/ui/mici/onroad/confidence_ball.py similarity index 100% rename from selfdrive/ui/mici/onroad/confidence_ball.py rename to openpilot/selfdrive/ui/mici/onroad/confidence_ball.py diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py similarity index 98% rename from selfdrive/ui/mici/onroad/driver_camera_dialog.py rename to openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py index df5afe2e7c..e81877b402 100644 --- a/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -1,5 +1,5 @@ import pyray as rl -from cereal import car, log, messaging +from openpilot.cereal import log, messaging from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer @@ -104,8 +104,9 @@ class BaseDriverCameraDialog(Widget): if self._pm is None: return - AudibleAlert = car.CarControl.HUDControl.AudibleAlert + AudibleAlert = log.SelfdriveState.AudibleAlert ALERT_SOUNDS = { + 'one': AudibleAlert.preAlert, 'two': AudibleAlert.promptDistracted, 'three': AudibleAlert.warningImmediate, } diff --git a/selfdrive/ui/mici/onroad/driver_state.py b/openpilot/selfdrive/ui/mici/onroad/driver_state.py similarity index 99% rename from selfdrive/ui/mici/onroad/driver_state.py rename to openpilot/selfdrive/ui/mici/onroad/driver_state.py index 1855d77b77..85b90704ac 100644 --- a/selfdrive/ui/mici/onroad/driver_state.py +++ b/openpilot/selfdrive/ui/mici/onroad/driver_state.py @@ -1,7 +1,7 @@ import pyray as rl import numpy as np import math -from cereal import log +from openpilot.cereal import log from openpilot.common.filter_simple import FirstOrderFilter from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets import Widget diff --git a/selfdrive/ui/mici/onroad/hud_renderer.py b/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py similarity index 99% rename from selfdrive/ui/mici/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/hud_renderer.py index c74d3101b0..67f9833021 100644 --- a/selfdrive/ui/mici/onroad/hud_renderer.py +++ b/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py @@ -8,7 +8,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.text_measure import measure_text_cached from openpilot.system.ui.widgets import Widget from openpilot.common.filter_simple import FirstOrderFilter -from cereal import log +from openpilot.cereal import log EventName = log.OnroadEvent.EventName diff --git a/selfdrive/ui/mici/onroad/model_renderer.py b/openpilot/selfdrive/ui/mici/onroad/model_renderer.py similarity index 99% rename from selfdrive/ui/mici/onroad/model_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/model_renderer.py index e88d320a3f..87174cf7d9 100644 --- a/selfdrive/ui/mici/onroad/model_renderer.py +++ b/openpilot/selfdrive/ui/mici/onroad/model_renderer.py @@ -1,7 +1,8 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging, car +from openpilot.cereal import messaging +from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.params import Params from openpilot.common.filter_simple import FirstOrderFilter @@ -176,7 +177,7 @@ class ModelRenderer(Widget, ModelRendererSP): leads = [radar_state.leadOne, radar_state.leadTwo] for i, lead_data in enumerate(leads): - if lead_data and lead_data.status: + if lead_data and lead_data.present: d_rel, y_rel, v_rel = lead_data.dRel, lead_data.yRel, lead_data.vRel idx = self._get_path_length_idx(path_x_array, d_rel) @@ -205,7 +206,7 @@ class ModelRenderer(Widget, ModelRendererSP): road_edge.projected_points = self._map_line_to_polygon(road_edge.raw_points, line_width_factor, 0.0, max_idx) # Update path using raw points - if lead and lead.status: + if lead and lead.present: lead_d = lead.dRel * 2.0 max_distance = np.clip(lead_d - min(lead_d * 0.35, 10.0), 0.0, max_distance) diff --git a/selfdrive/ui/mici/onroad/torque_bar.py b/openpilot/selfdrive/ui/mici/onroad/torque_bar.py similarity index 100% rename from selfdrive/ui/mici/onroad/torque_bar.py rename to openpilot/selfdrive/ui/mici/onroad/torque_bar.py diff --git a/selfdrive/ui/mici/tests/test_widget_leaks.py b/openpilot/selfdrive/ui/mici/tests/test_widget_leaks.py similarity index 100% rename from selfdrive/ui/mici/tests/test_widget_leaks.py rename to openpilot/selfdrive/ui/mici/tests/test_widget_leaks.py diff --git a/selfdrive/ui/mici/widgets/button.py b/openpilot/selfdrive/ui/mici/widgets/button.py similarity index 100% rename from selfdrive/ui/mici/widgets/button.py rename to openpilot/selfdrive/ui/mici/widgets/button.py diff --git a/selfdrive/ui/mici/widgets/dialog.py b/openpilot/selfdrive/ui/mici/widgets/dialog.py similarity index 100% rename from selfdrive/ui/mici/widgets/dialog.py rename to openpilot/selfdrive/ui/mici/widgets/dialog.py diff --git a/selfdrive/ui/mici/widgets/pairing_dialog.py b/openpilot/selfdrive/ui/mici/widgets/pairing_dialog.py similarity index 100% rename from selfdrive/ui/mici/widgets/pairing_dialog.py rename to openpilot/selfdrive/ui/mici/widgets/pairing_dialog.py diff --git a/selfdrive/ui/mici/layouts/__init__.py b/openpilot/selfdrive/ui/onroad/__init__.py similarity index 100% rename from selfdrive/ui/mici/layouts/__init__.py rename to openpilot/selfdrive/ui/onroad/__init__.py diff --git a/selfdrive/ui/onroad/alert_renderer.py b/openpilot/selfdrive/ui/onroad/alert_renderer.py similarity index 99% rename from selfdrive/ui/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/onroad/alert_renderer.py index 6fab21c4b9..b77b1539f4 100644 --- a/selfdrive/ui/onroad/alert_renderer.py +++ b/openpilot/selfdrive/ui/onroad/alert_renderer.py @@ -1,7 +1,7 @@ import time import pyray as rl from dataclasses import dataclass -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app, FontWeight diff --git a/selfdrive/ui/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/onroad/augmented_road_view.py similarity index 99% rename from selfdrive/ui/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/onroad/augmented_road_view.py index f6ea8f4e2a..c255804f2d 100644 --- a/selfdrive/ui/onroad/augmented_road_view.py +++ b/openpilot/selfdrive/ui/onroad/augmented_road_view.py @@ -1,6 +1,6 @@ import numpy as np import pyray as rl -from cereal import log +from openpilot.cereal import log from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus diff --git a/selfdrive/ui/onroad/cameraview.py b/openpilot/selfdrive/ui/onroad/cameraview.py similarity index 100% rename from selfdrive/ui/onroad/cameraview.py rename to openpilot/selfdrive/ui/onroad/cameraview.py diff --git a/selfdrive/ui/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py similarity index 100% rename from selfdrive/ui/onroad/driver_camera_dialog.py rename to openpilot/selfdrive/ui/onroad/driver_camera_dialog.py diff --git a/selfdrive/ui/onroad/driver_state.py b/openpilot/selfdrive/ui/onroad/driver_state.py similarity index 99% rename from selfdrive/ui/onroad/driver_state.py rename to openpilot/selfdrive/ui/onroad/driver_state.py index 5b09e471b5..6b11f0b10b 100644 --- a/selfdrive/ui/onroad/driver_state.py +++ b/openpilot/selfdrive/ui/onroad/driver_state.py @@ -1,6 +1,6 @@ import numpy as np import pyray as rl -from cereal import log +from openpilot.cereal import log from dataclasses import dataclass from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/onroad/exp_button.py b/openpilot/selfdrive/ui/onroad/exp_button.py similarity index 100% rename from selfdrive/ui/onroad/exp_button.py rename to openpilot/selfdrive/ui/onroad/exp_button.py diff --git a/selfdrive/ui/onroad/hud_renderer.py b/openpilot/selfdrive/ui/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/onroad/hud_renderer.py diff --git a/selfdrive/ui/onroad/model_renderer.py b/openpilot/selfdrive/ui/onroad/model_renderer.py similarity index 99% rename from selfdrive/ui/onroad/model_renderer.py rename to openpilot/selfdrive/ui/onroad/model_renderer.py index 353cc5aa40..4e0dead3df 100644 --- a/selfdrive/ui/onroad/model_renderer.py +++ b/openpilot/selfdrive/ui/onroad/model_renderer.py @@ -1,7 +1,8 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging, car +from openpilot.cereal import messaging +from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params @@ -159,7 +160,7 @@ class ModelRenderer(Widget, ChevronMetrics, ModelRendererSP): leads = [radar_state.leadOne, radar_state.leadTwo] for i, lead_data in enumerate(leads): - if lead_data and lead_data.status: + if lead_data and lead_data.present: d_rel, y_rel, v_rel = lead_data.dRel, lead_data.yRel, lead_data.vRel idx = self._get_path_length_idx(path_x_array, d_rel) @@ -185,7 +186,7 @@ class ModelRenderer(Widget, ChevronMetrics, ModelRendererSP): road_edge.projected_points = self._map_line_to_polygon(road_edge.raw_points, 0.025, 0.0, max_idx, max_distance) # Update path using raw points - if lead and lead.status: + if lead and lead.present: lead_d = lead.dRel * 2.0 max_distance = np.clip(lead_d - min(lead_d * 0.35, 10.0), 0.0, max_distance) diff --git a/selfdrive/ui/soundd.py b/openpilot/selfdrive/ui/soundd.py similarity index 96% rename from selfdrive/ui/soundd.py rename to openpilot/selfdrive/ui/soundd.py index 1722f608e1..72be459834 100644 --- a/selfdrive/ui/soundd.py +++ b/openpilot/selfdrive/ui/soundd.py @@ -4,7 +4,7 @@ import time import wave -from cereal import car, messaging, custom +from openpilot.cereal import log, messaging, custom from openpilot.common.basedir import BASEDIR from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.realtime import Ratekeeper @@ -32,7 +32,7 @@ if HARDWARE.get_device_type() == "tizi": AMBIENT_DB = 30 VOLUME_BASE = 10 -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert AudibleAlertSP = custom.SelfdriveStateSP.AudibleAlert @@ -52,6 +52,8 @@ sound_list: dict[int, tuple[str, int | None, float]] = { AudibleAlert.promptRepeat: ("prompt.wav", None, MAX_VOLUME), AudibleAlert.promptDistracted: ("prompt_distracted.wav", None, MAX_VOLUME), + AudibleAlert.preAlert: ("pre_alert.wav", 1, MAX_VOLUME), + AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME), AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME), @@ -97,7 +99,7 @@ class Soundd(QuietMode): for sound in sound_list: filename, play_count, volume = sound_list[sound] - with wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') as wavefile: + with wave.open(BASEDIR + "/openpilot/selfdrive/assets/sounds/" + filename, 'r') as wavefile: assert wavefile.getnchannels() == 1 assert wavefile.getsampwidth() == 2 assert wavefile.getframerate() == SAMPLE_RATE diff --git a/selfdrive/ui/onroad/__init__.py b/openpilot/selfdrive/ui/sunnypilot/__init__.py similarity index 100% rename from selfdrive/ui/onroad/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/__init__.py diff --git a/selfdrive/ui/sunnypilot/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/onboarding.py b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/onboarding.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py index 7e532678b0..a86677a7b1 100644 --- a/selfdrive/ui/sunnypilot/layouts/onboarding.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py @@ -11,7 +11,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.label import Label -from openpilot.system.version import sunnylink_consent_version, sunnylink_consent_declined +from openpilot.common.version import sunnylink_consent_version, sunnylink_consent_declined class SunnylinkConsentPage(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/developer.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/developer.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/developer.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/device.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/device.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/device.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/device.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/display.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/display.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/display.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/display.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/models.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/models.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py index 587c3560c9..7a175b4037 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/models.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py @@ -9,7 +9,7 @@ import re import time import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.common.constants import CV from openpilot.selfdrive.ui.ui_state import device, ui_state diff --git a/selfdrive/ui/sunnypilot/layouts/settings/navigation.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/navigation.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/navigation.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/navigation.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/network.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/network.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/network.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/network.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/osm.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/osm.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/osm.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/osm.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/software.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py similarity index 97% rename from selfdrive/ui/sunnypilot/layouts/settings/software.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py index a07bda1e34..82875fd698 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import os +import subprocess from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout from openpilot.selfdrive.ui.ui_state import ui_state @@ -78,7 +78,7 @@ class SoftwareLayoutSP(SoftwareLayout): if selection: ui_state.params.put("UpdaterTargetBranch", selection) self._branch_btn.action_item.set_value(selection) - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run(["pkill", "-SIGUSR1", "-f", "system.updated.updated"], check=False) self._branch_dialog = None self._branch_dialog = TreeOptionDialog(tr("Select a branch"), folders, current_target, "", diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/steering.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py index a5cd626483..15cb6a15e0 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/steering.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from enum import IntEnum from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py index d4976b1295..f3c4419e45 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py @@ -21,7 +21,7 @@ from openpilot.system.ui.widgets import Widget, DialogResult from openpilot.system.ui.widgets.network import NavButton from openpilot.system.ui.widgets.scroller_tici import Scroller -TORQUE_VERSIONS_PATH = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "controls", "lib", "latcontrol_torque_versions.json") +TORQUE_VERSIONS_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "selfdrive", "controls", "lib", "latcontrol_torque_versions.json") class TorqueSettingsLayout(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py index 1d9b99d5fd..5e75e797cb 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.selfdrive.ui.sunnypilot.layouts.onboarding import SunnylinkConsentPage from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.sunnypilot.sunnylink.api import UNREGISTERED_SUNNYLINK_DONGLE_ID @@ -20,7 +20,7 @@ from openpilot.system.ui.widgets.confirm_dialog import alert_dialog, ConfirmDial from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.list_view import dual_button_item from openpilot.system.ui.widgets.scroller_tici import Scroller, LineSeparator -from openpilot.system.version import sunnylink_consent_version +from openpilot.common.version import sunnylink_consent_version class SunnylinkHeader(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/trips.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/trips.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/trips.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/trips.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py index 6102e8e9b7..aab935d4b8 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py @@ -21,7 +21,7 @@ from openpilot.system.ui.sunnypilot.lib.styles import style from openpilot.system.ui.sunnypilot.widgets.tree_dialog import TreeOptionDialog, TreeNode, TreeFolder from openpilot.selfdrive.ui.ui_state import ui_state -CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "car", "car_list.json") +CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "openpilot", "sunnypilot", "selfdrive", "car", "car_list.json") class LegendWidget(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/visuals.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/visuals.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/visuals.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/visuals.py diff --git a/selfdrive/ui/sunnypilot/layouts/sidebar.py b/openpilot/selfdrive/ui/sunnypilot/layouts/sidebar.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/sidebar.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/sidebar.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/models.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py similarity index 99% rename from selfdrive/ui/sunnypilot/mici/layouts/models.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py index 138ff87b75..5f3f77d62c 100644 --- a/selfdrive/ui/sunnypilot/mici/layouts/models.py +++ b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py @@ -7,7 +7,7 @@ See the LICENSE.md file in the root directory for more details. from collections.abc import Callable import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.selfdrive.ui.mici.widgets.button import BigButton from openpilot.selfdrive.ui.sunnypilot.layouts.settings.models import ModelsLayout diff --git a/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/onboarding.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/settings.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/settings.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/settings.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py similarity index 99% rename from selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py index 85ebf55f46..e804c78035 100644 --- a/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py +++ b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py @@ -8,7 +8,7 @@ import pyray as rl from collections.abc import Callable -from cereal import custom +from openpilot.cereal import custom from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigConfirmationDialog from openpilot.selfdrive.ui.sunnypilot.mici.layouts.onboarding import SunnylinkConsentPage @@ -20,7 +20,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.scroller import NavScroller -from openpilot.system.version import sunnylink_consent_version, sunnylink_consent_declined +from openpilot.common.version import sunnylink_consent_version, sunnylink_consent_declined class SunnylinkInfo(Widget): def __init__(self): diff --git a/selfdrive/ui/sunnypilot/mici/layouts/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/widgets/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/widgets/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py b/openpilot/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py rename to openpilot/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py diff --git a/selfdrive/ui/sunnypilot/mici/widgets/__init__.py b/openpilot/selfdrive/ui/sunnypilot/onroad/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/widgets/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/__init__.py diff --git a/selfdrive/ui/sunnypilot/onroad/alert_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/alert_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/alert_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py diff --git a/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py b/openpilot/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py diff --git a/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py b/openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py similarity index 97% rename from selfdrive/ui/sunnypilot/onroad/chevron_metrics.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py index a8a342c129..1dded3fc62 100644 --- a/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py @@ -128,8 +128,8 @@ class ChevronMetrics: lead_one = radar_state.leadOne lead_two = radar_state.leadTwo - has_lead_one = lead_one.status if lead_one else False - has_lead_two = lead_two.status if lead_two else False + has_lead_one = lead_one.present if lead_one else False + has_lead_two = lead_two.present if lead_two else False self.update_alpha(has_lead_one or has_lead_two) diff --git a/selfdrive/ui/sunnypilot/onroad/circular_alerts.py b/openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/circular_alerts.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py index f90fc81914..c44e4455eb 100644 --- a/selfdrive/ui/sunnypilot/onroad/circular_alerts.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.selfdrive.ui.sunnypilot.onroad.developer_ui import DeveloperUiState diff --git a/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py diff --git a/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py index 389692d30b..4119990f22 100644 --- a/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py @@ -42,7 +42,7 @@ class LeadInfoElement: @staticmethod def get_lead_status(sm): lead_one = sm['radarState'].leadOne - return lead_one.status, lead_one.dRel, lead_one.vRel + return lead_one.present, lead_one.dRel, lead_one.vRel @staticmethod def get_lead_color(lead_d_rel: float, lead_v_rel: float = 0.0, use_v_rel: bool = False) -> rl.Color: diff --git a/selfdrive/ui/sunnypilot/onroad/driver_state.py b/openpilot/selfdrive/ui/sunnypilot/onroad/driver_state.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/driver_state.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/driver_state.py diff --git a/selfdrive/ui/sunnypilot/onroad/hud_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/hud_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/model_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/model_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/model_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/rainbow_path.py b/openpilot/selfdrive/ui/sunnypilot/onroad/rainbow_path.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/rainbow_path.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/rainbow_path.py diff --git a/selfdrive/ui/sunnypilot/onroad/road_name.py b/openpilot/selfdrive/ui/sunnypilot/onroad/road_name.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/road_name.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/road_name.py diff --git a/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py b/openpilot/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/rocket_fuel.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py diff --git a/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py b/openpilot/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py diff --git a/selfdrive/ui/sunnypilot/onroad/speed_limit.py b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/speed_limit.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py index bfa311c357..7851698683 100644 --- a/selfdrive/ui/sunnypilot/onroad/speed_limit.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py @@ -9,7 +9,7 @@ from dataclasses import dataclass from enum import StrEnum import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.selfdrive.ui.onroad.hud_renderer import UI_CONFIG from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/sunnypilot/onroad/speed_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/speed_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/speed_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/turn_signal.py b/openpilot/selfdrive/ui/sunnypilot/onroad/turn_signal.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/turn_signal.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/turn_signal.py diff --git a/selfdrive/ui/sunnypilot/ui_state.py b/openpilot/selfdrive/ui/sunnypilot/ui_state.py similarity index 99% rename from selfdrive/ui/sunnypilot/ui_state.py rename to openpilot/selfdrive/ui/sunnypilot/ui_state.py index 1c21c35c6f..4b91bd4021 100644 --- a/selfdrive/ui/sunnypilot/ui_state.py +++ b/openpilot/selfdrive/ui/sunnypilot/ui_state.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ from enum import Enum -from cereal import messaging, log, car, custom +from openpilot.cereal import messaging, log, custom +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.selfdrive.ui.sunnypilot.layouts.settings.display import OnroadBrightness from openpilot.sunnypilot.sunnylink.sunnylink_state import SunnylinkState diff --git a/selfdrive/ui/sunnypilot/onroad/__init__.py b/openpilot/selfdrive/ui/tests/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/__init__.py rename to openpilot/selfdrive/ui/tests/__init__.py diff --git a/selfdrive/ui/tests/body.py b/openpilot/selfdrive/ui/tests/body.py similarity index 92% rename from selfdrive/ui/tests/body.py rename to openpilot/selfdrive/ui/tests/body.py index 07a2ef5128..b9f5c2d18c 100755 --- a/selfdrive/ui/tests/body.py +++ b/openpilot/selfdrive/ui/tests/body.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging if __name__ == "__main__": while True: diff --git a/selfdrive/ui/tests/cycle_offroad_alerts.py b/openpilot/selfdrive/ui/tests/cycle_offroad_alerts.py similarity index 90% rename from selfdrive/ui/tests/cycle_offroad_alerts.py rename to openpilot/selfdrive/ui/tests/cycle_offroad_alerts.py index fcb4a72c77..c2690edf7d 100755 --- a/selfdrive/ui/tests/cycle_offroad_alerts.py +++ b/openpilot/selfdrive/ui/tests/cycle_offroad_alerts.py @@ -12,7 +12,7 @@ from openpilot.system.updated.updated import parse_release_notes if __name__ == "__main__": params = Params() - with open(os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json")) as f: + with open(os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json")) as f: offroad_alerts = json.load(f) t = 10 if len(sys.argv) < 2 else int(sys.argv[1]) diff --git a/selfdrive/ui/tests/diff/diff.py b/openpilot/selfdrive/ui/tests/diff/diff.py similarity index 98% rename from selfdrive/ui/tests/diff/diff.py rename to openpilot/selfdrive/ui/tests/diff/diff.py index b861d848eb..9dd7c3bc0e 100755 --- a/selfdrive/ui/tests/diff/diff.py +++ b/openpilot/selfdrive/ui/tests/diff/diff.py @@ -8,7 +8,7 @@ from concurrent.futures import ThreadPoolExecutor from pathlib import Path from openpilot.common.basedir import BASEDIR -DIFF_OUT_DIR = Path(BASEDIR) / "selfdrive" / "ui" / "tests" / "diff" / "report" +DIFF_OUT_DIR = Path(BASEDIR) / "openpilot" / "selfdrive" / "ui" / "tests" / "diff" / "report" HTML_TEMPLATE_PATH = Path(__file__).with_name("diff_template.html") diff --git a/selfdrive/ui/tests/diff/diff_template.html b/openpilot/selfdrive/ui/tests/diff/diff_template.html similarity index 100% rename from selfdrive/ui/tests/diff/diff_template.html rename to openpilot/selfdrive/ui/tests/diff/diff_template.html diff --git a/selfdrive/ui/tests/diff/replay.py b/openpilot/selfdrive/ui/tests/diff/replay.py similarity index 98% rename from selfdrive/ui/tests/diff/replay.py rename to openpilot/selfdrive/ui/tests/diff/replay.py index cb88ee9da8..e378076850 100755 --- a/selfdrive/ui/tests/diff/replay.py +++ b/openpilot/selfdrive/ui/tests/diff/replay.py @@ -7,14 +7,14 @@ import pyray as rl from tqdm import tqdm from typing import Literal from collections.abc import Callable -from cereal.messaging import PubMaster +from openpilot.cereal.messaging import PubMaster from openpilot.common.api import Api from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.prefix import OpenpilotPrefix from openpilot.selfdrive.ui.tests.diff.diff import DIFF_OUT_DIR from openpilot.system.updated.updated import parse_release_notes -from openpilot.system.version import terms_version, training_version, terms_version_sp, sunnylink_consent_version +from openpilot.common.version import terms_version, training_version, terms_version_sp, sunnylink_consent_version LayoutVariant = Literal["mici", "tizi"] diff --git a/selfdrive/ui/tests/diff/replay_script.py b/openpilot/selfdrive/ui/tests/diff/replay_script.py similarity index 99% rename from selfdrive/ui/tests/diff/replay_script.py rename to openpilot/selfdrive/ui/tests/diff/replay_script.py index ad7e8952d6..8517f0dece 100644 --- a/selfdrive/ui/tests/diff/replay_script.py +++ b/openpilot/selfdrive/ui/tests/diff/replay_script.py @@ -5,8 +5,9 @@ from dataclasses import dataclass import math -from cereal import car, log, messaging -from cereal.messaging import PubMaster +from openpilot.cereal import log, messaging +from opendbc.car.structs import car +from openpilot.cereal.messaging import PubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert @@ -121,7 +122,6 @@ def set_prime_state(prime_type: PrimeType) -> None: def setup_offroad_alerts() -> None: set_offroad_alert("Offroad_TemperatureTooHigh", True, extra_text='99C') set_offroad_alert("Offroad_ExcessiveActuation", True, extra_text='longitudinal') - set_offroad_alert("Offroad_IsTakingSnapshot", True) def setup_update_available(available: bool = True) -> None: diff --git a/selfdrive/ui/tests/profile_onroad.py b/openpilot/selfdrive/ui/tests/profile_onroad.py similarity index 100% rename from selfdrive/ui/tests/profile_onroad.py rename to openpilot/selfdrive/ui/tests/profile_onroad.py diff --git a/selfdrive/ui/tests/test_feedbackd.py b/openpilot/selfdrive/ui/tests/test_feedbackd.py similarity index 95% rename from selfdrive/ui/tests/test_feedbackd.py rename to openpilot/selfdrive/ui/tests/test_feedbackd.py index 0f7148de04..72bd499081 100644 --- a/selfdrive/ui/tests/test_feedbackd.py +++ b/openpilot/selfdrive/ui/tests/test_feedbackd.py @@ -1,6 +1,6 @@ import pytest -import cereal.messaging as messaging -from cereal import car +import openpilot.cereal.messaging as messaging +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes diff --git a/selfdrive/ui/tests/test_raylib_ui.py b/openpilot/selfdrive/ui/tests/test_raylib_ui.py similarity index 100% rename from selfdrive/ui/tests/test_raylib_ui.py rename to openpilot/selfdrive/ui/tests/test_raylib_ui.py diff --git a/selfdrive/ui/tests/test_soundd.py b/openpilot/selfdrive/ui/tests/test_soundd.py similarity index 90% rename from selfdrive/ui/tests/test_soundd.py rename to openpilot/selfdrive/ui/tests/test_soundd.py index 226117ae8f..95588a9fba 100644 --- a/selfdrive/ui/tests/test_soundd.py +++ b/openpilot/selfdrive/ui/tests/test_soundd.py @@ -1,11 +1,10 @@ -from cereal import car -from cereal import messaging -from cereal.messaging import SubMaster, PubMaster +from openpilot.cereal import log, messaging +from openpilot.cereal.messaging import SubMaster, PubMaster from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert import time -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert class TestSoundd: diff --git a/selfdrive/ui/tests/test_translations.py b/openpilot/selfdrive/ui/tests/test_translations.py similarity index 100% rename from selfdrive/ui/tests/test_translations.py rename to openpilot/selfdrive/ui/tests/test_translations.py diff --git a/selfdrive/ui/translations/app.pot b/openpilot/selfdrive/ui/translations/app.pot similarity index 100% rename from selfdrive/ui/translations/app.pot rename to openpilot/selfdrive/ui/translations/app.pot diff --git a/selfdrive/ui/translations/app_de.po b/openpilot/selfdrive/ui/translations/app_de.po similarity index 100% rename from selfdrive/ui/translations/app_de.po rename to openpilot/selfdrive/ui/translations/app_de.po diff --git a/selfdrive/ui/translations/app_en.po b/openpilot/selfdrive/ui/translations/app_en.po similarity index 100% rename from selfdrive/ui/translations/app_en.po rename to openpilot/selfdrive/ui/translations/app_en.po diff --git a/selfdrive/ui/translations/app_es.po b/openpilot/selfdrive/ui/translations/app_es.po similarity index 100% rename from selfdrive/ui/translations/app_es.po rename to openpilot/selfdrive/ui/translations/app_es.po diff --git a/selfdrive/ui/translations/app_fr.po b/openpilot/selfdrive/ui/translations/app_fr.po similarity index 100% rename from selfdrive/ui/translations/app_fr.po rename to openpilot/selfdrive/ui/translations/app_fr.po diff --git a/selfdrive/ui/translations/app_ja.po b/openpilot/selfdrive/ui/translations/app_ja.po similarity index 100% rename from selfdrive/ui/translations/app_ja.po rename to openpilot/selfdrive/ui/translations/app_ja.po diff --git a/selfdrive/ui/translations/app_ko.po b/openpilot/selfdrive/ui/translations/app_ko.po similarity index 100% rename from selfdrive/ui/translations/app_ko.po rename to openpilot/selfdrive/ui/translations/app_ko.po diff --git a/selfdrive/ui/translations/app_pt-BR.po b/openpilot/selfdrive/ui/translations/app_pt-BR.po similarity index 100% rename from selfdrive/ui/translations/app_pt-BR.po rename to openpilot/selfdrive/ui/translations/app_pt-BR.po diff --git a/selfdrive/ui/translations/app_th.po b/openpilot/selfdrive/ui/translations/app_th.po similarity index 100% rename from selfdrive/ui/translations/app_th.po rename to openpilot/selfdrive/ui/translations/app_th.po diff --git a/selfdrive/ui/translations/app_tr.po b/openpilot/selfdrive/ui/translations/app_tr.po similarity index 100% rename from selfdrive/ui/translations/app_tr.po rename to openpilot/selfdrive/ui/translations/app_tr.po diff --git a/selfdrive/ui/translations/app_uk.po b/openpilot/selfdrive/ui/translations/app_uk.po similarity index 100% rename from selfdrive/ui/translations/app_uk.po rename to openpilot/selfdrive/ui/translations/app_uk.po diff --git a/selfdrive/ui/translations/app_zh-CHS.po b/openpilot/selfdrive/ui/translations/app_zh-CHS.po similarity index 100% rename from selfdrive/ui/translations/app_zh-CHS.po rename to openpilot/selfdrive/ui/translations/app_zh-CHS.po diff --git a/selfdrive/ui/translations/app_zh-CHT.po b/openpilot/selfdrive/ui/translations/app_zh-CHT.po similarity index 100% rename from selfdrive/ui/translations/app_zh-CHT.po rename to openpilot/selfdrive/ui/translations/app_zh-CHT.po diff --git a/selfdrive/ui/translations/auto_translate.sh b/openpilot/selfdrive/ui/translations/auto_translate.sh similarity index 91% rename from selfdrive/ui/translations/auto_translate.sh rename to openpilot/selfdrive/ui/translations/auto_translate.sh index 03a207ca3c..7238426c75 100755 --- a/selfdrive/ui/translations/auto_translate.sh +++ b/openpilot/selfdrive/ui/translations/auto_translate.sh @@ -15,7 +15,7 @@ command -v codex >/dev/null || { } codex exec --cd "$ROOT" -c 'model_reasoning_effort="low"' --dangerously-bypass-approvals-and-sandbox "$(cat < WMACConstants.LEAD_PROB diff --git a/sunnypilot/selfdrive/controls/lib/dec/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py diff --git a/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py b/openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py rename to openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py index 944bf617e9..b75bae2461 100644 --- a/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL @@ -61,7 +61,7 @@ class E2EAlertsHelper: model_x = sm['modelV2'].position.x max_idx = len(model_x) - 1 - self.has_lead = sm['radarState'].leadOne.status + self.has_lead = sm['radarState'].leadOne.present lead_dRel = sm['radarState'].leadOne.dRel standstill = CS.standstill diff --git a/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py b/openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py similarity index 97% rename from sunnypilot/selfdrive/controls/lib/lane_turn_desire.py rename to openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py index fa35ebb125..ad7e80eda0 100644 --- a/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import custom +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py index f7874cc539..4d9e4492f9 100644 --- a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py @@ -2,7 +2,7 @@ import math import numpy as np from collections import deque -from cereal import log +from openpilot.cereal import log from opendbc.car.lateral import get_friction from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.filter_simple import FirstOrderFilter diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json diff --git a/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/longitudinal_planner.py rename to openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py index 6efda4585f..f1e0c36416 100644 --- a/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from opendbc.car import structs from openpilot.common.constants import CV from openpilot.selfdrive.car.cruise import V_CRUISE_MAX diff --git a/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py similarity index 92% rename from sunnypilot/selfdrive/controls/lib/nnlc/helpers.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py index c34fa435c2..a5d56b1ff0 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py @@ -11,8 +11,8 @@ from difflib import SequenceMatcher from opendbc.car import structs from openpilot.common.basedir import BASEDIR -TORQUE_NN_MODEL_PATH = os.path.join(BASEDIR, "sunnypilot", "neural_network_data", "neural_network_lateral_control") -TORQUE_NN_MODEL_SUBSTITUTE_PATH = os.path.join(BASEDIR, "opendbc", "car", "torque_data/substitute.toml") +TORQUE_NN_MODEL_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "neural_network_data", "neural_network_lateral_control") +TORQUE_NN_MODEL_SUBSTITUTE_PATH = os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "torque_data/substitute.toml") MOCK_MODEL_PATH = os.path.join(TORQUE_NN_MODEL_PATH, "MOCK.json") diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/model.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/model.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/model.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/model.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py index f2009926cf..56fd2f9ce7 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py @@ -1,6 +1,7 @@ import numpy as np -from cereal import car, log, messaging +from openpilot.cereal import log, messaging +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.gm.values import CAR as GM from opendbc.car.honda.values import CAR as HONDA diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py index c7f11a1bb2..65e157bdbc 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py @@ -2,7 +2,7 @@ import json import math import platform -from cereal import custom +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py similarity index 94% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py index 4ca45202fc..ff6c706634 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control.vision_controller import SmartCruiseControlVision from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control.map_controller import SmartCruiseControlMap diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py index 254e85f573..3b16c59bb5 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import platform -from cereal import custom +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py index 2a2c6a6be1..de54a0fdca 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py @@ -7,8 +7,8 @@ See the LICENSE.md file in the root directory for more details. import numpy as np import pytest -import cereal.messaging as messaging -from cereal import custom, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom, log from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py index a9d2a66227..fb76f5b546 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py @@ -6,8 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import numpy as np -import cereal.messaging as messaging -from cereal import custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/common.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/common.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/common.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/common.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py similarity index 95% rename from sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py index 9eddceb820..77d89251e2 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py @@ -5,7 +5,8 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import custom, car +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Mode as SpeedLimitMode diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py index ff7be8a8be..1ff541167f 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import time -from cereal import custom, car +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py index 35965c0e18..e46196654c 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py @@ -6,8 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import time -import cereal.messaging as messaging -from cereal import custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.common.gps import get_gps_location_service from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py index 6dbe32eaf4..7cd6fef524 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py @@ -7,7 +7,7 @@ See the LICENSE.md file in the root directory for more details. import pytest -from cereal import custom +from openpilot.cereal import custom from opendbc.car.car_helpers import interfaces from opendbc.car.rivian.values import CAR as RIVIAN from opendbc.car.tesla.values import CAR as TESLA diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py index c02831d71a..a18880c620 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py @@ -10,7 +10,7 @@ import time import pytest from pytest_mock import MockerFixture -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import LIMIT_MAX_MAP_DATA_AGE from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.speed_limit_resolver import SpeedLimitResolver, ALL_SOURCES diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py index b547ea96b6..7a72cfa1f2 100644 --- a/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.sunnypilot.selfdrive.controls.lib.blinker_pause_lateral import BlinkerPauseLateral diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py index 57fe7b684f..c3e96fd778 100644 --- a/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py @@ -1,5 +1,5 @@ import pytest -from cereal import log, custom +from openpilot.cereal import log, custom from openpilot.common.params import Params from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper diff --git a/sunnypilot/selfdrive/locationd/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/.gitignore diff --git a/sunnypilot/selfdrive/locationd/SConscript b/openpilot/sunnypilot/selfdrive/locationd/SConscript similarity index 100% rename from sunnypilot/selfdrive/locationd/SConscript rename to openpilot/sunnypilot/selfdrive/locationd/SConscript diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/__init__.py diff --git a/sunnypilot/selfdrive/locationd/locationd.cc b/openpilot/sunnypilot/selfdrive/locationd/locationd.cc similarity index 100% rename from sunnypilot/selfdrive/locationd/locationd.cc rename to openpilot/sunnypilot/selfdrive/locationd/locationd.cc diff --git a/sunnypilot/selfdrive/locationd/locationd.h b/openpilot/sunnypilot/selfdrive/locationd/locationd.h similarity index 100% rename from sunnypilot/selfdrive/locationd/locationd.h rename to openpilot/sunnypilot/selfdrive/locationd/locationd.h diff --git a/sunnypilot/selfdrive/locationd/models/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/models/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/models/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/models/.gitignore diff --git a/sunnypilot/selfdrive/locationd/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/models/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/models/__init__.py diff --git a/sunnypilot/selfdrive/locationd/models/car_kf.py b/openpilot/sunnypilot/selfdrive/locationd/models/car_kf.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/car_kf.py rename to openpilot/sunnypilot/selfdrive/locationd/models/car_kf.py diff --git a/sunnypilot/selfdrive/locationd/models/constants.py b/openpilot/sunnypilot/selfdrive/locationd/models/constants.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/constants.py rename to openpilot/sunnypilot/selfdrive/locationd/models/constants.py diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.cc b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.cc similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.cc rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.cc diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.h b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.h similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.h rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.h diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.py b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.py rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.py diff --git a/sunnypilot/selfdrive/locationd/tests/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/tests/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/tests/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/tests/.gitignore diff --git a/sunnypilot/selfdrive/locationd/models/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/tests/__init__.py diff --git a/sunnypilot/selfdrive/locationd/tests/test_locationd.py b/openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py similarity index 97% rename from sunnypilot/selfdrive/locationd/tests/test_locationd.py rename to openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py index 1f5bfd3b25..551259fa01 100644 --- a/sunnypilot/selfdrive/locationd/tests/test_locationd.py +++ b/openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py @@ -5,8 +5,8 @@ import random import time import capnp -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.params import Params from openpilot.common.transformations.coordinates import ecef2geodetic diff --git a/sunnypilot/selfdrive/locationd/torqued_ext.py b/openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py similarity index 98% rename from sunnypilot/selfdrive/locationd/torqued_ext.py rename to openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py index 1e62b7666a..f1f16f58ee 100644 --- a/sunnypilot/selfdrive/locationd/torqued_ext.py +++ b/openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL diff --git a/sunnypilot/selfdrive/locationd/tests/__init__.py b/openpilot/sunnypilot/selfdrive/pandad/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/pandad/__init__.py diff --git a/sunnypilot/selfdrive/pandad/rivian_long_flasher.py b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py similarity index 97% rename from sunnypilot/selfdrive/pandad/rivian_long_flasher.py rename to openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py index 305b994c78..3be9fb0e4d 100755 --- a/sunnypilot/selfdrive/pandad/rivian_long_flasher.py +++ b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py @@ -8,7 +8,8 @@ See the LICENSE.md file in the root directory for more details. import os from itertools import accumulate -from cereal import car, messaging +from openpilot.cereal import messaging +from opendbc.car.structs import car from panda import Panda from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog diff --git a/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed similarity index 100% rename from sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed rename to openpilot/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed diff --git a/sunnypilot/selfdrive/pandad/__init__.py b/openpilot/sunnypilot/selfdrive/selfdrived/__init__.py similarity index 100% rename from sunnypilot/selfdrive/pandad/__init__.py rename to openpilot/sunnypilot/selfdrive/selfdrived/__init__.py diff --git a/sunnypilot/selfdrive/selfdrived/events.py b/openpilot/sunnypilot/selfdrive/selfdrived/events.py similarity index 98% rename from sunnypilot/selfdrive/selfdrived/events.py rename to openpilot/sunnypilot/selfdrive/selfdrived/events.py index e9b0e99153..2001d0dbee 100644 --- a/sunnypilot/selfdrive/selfdrived/events.py +++ b/openpilot/sunnypilot/selfdrive/selfdrived/events.py @@ -4,8 +4,9 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import cereal.messaging as messaging -from cereal import log, car, custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log, custom +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.sunnypilot.selfdrive.selfdrived.events_base import EventsBase, Priority, ET, Alert, \ NoEntryAlert, ImmediateDisableAlert, EngagementAlert, NormalPermanentAlert, AlertCallbackType, wrong_car_mode_alert diff --git a/sunnypilot/selfdrive/selfdrived/events_base.py b/openpilot/sunnypilot/selfdrive/selfdrived/events_base.py similarity index 94% rename from sunnypilot/selfdrive/selfdrived/events_base.py rename to openpilot/sunnypilot/selfdrive/selfdrived/events_base.py index 402121f2fe..a392978144 100644 --- a/sunnypilot/selfdrive/selfdrived/events_base.py +++ b/openpilot/sunnypilot/selfdrive/selfdrived/events_base.py @@ -3,15 +3,16 @@ from enum import IntEnum from abc import abstractmethod from collections.abc import Callable -from cereal import log, car -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_CTRL from openpilot.common.hardware import HARDWARE AlertSize = log.SelfdriveState.AlertSize AlertStatus = log.SelfdriveState.AlertStatus VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert # Alert priorities @@ -46,7 +47,7 @@ class Alert: alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, - audible_alert: car.CarControl.HUDControl.AudibleAlert, + audible_alert: log.SelfdriveState.AudibleAlert, duration: float, creation_delay: float = 0.): @@ -77,7 +78,7 @@ class AlertBase(Alert): def __init__(self, alert_text_1: str, alert_text_2: str, alert_status: log.SelfdriveState.AlertStatus, alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, - audible_alert: car.CarControl.HUDControl.AudibleAlert, duration: float): + audible_alert: log.SelfdriveState.AudibleAlert, duration: float): super().__init__(alert_text_1, alert_text_2, alert_status, alert_size, priority, visual_alert, audible_alert, duration) @@ -185,11 +186,12 @@ EmptyAlert = Alert("" , "", AlertStatus.normal, AlertSize.none, Priority.LOWEST, class NoEntryAlert(Alert): def __init__(self, alert_text_2: str, alert_text_1: str = "openpilot Unavailable", - visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none): + visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none, + priority: Priority = Priority.LOW): if HARDWARE.get_device_type() == 'mici': alert_text_1, alert_text_2 = alert_text_2, alert_text_1 super().__init__(alert_text_1, alert_text_2, AlertStatus.normal, - AlertSize.mid, Priority.LOW, visual_alert, + AlertSize.mid, priority, visual_alert, AudibleAlert.refuse, 3.) @@ -217,7 +219,7 @@ class ImmediateDisableAlert(Alert): class EngagementAlert(Alert): - def __init__(self, audible_alert: car.CarControl.HUDControl.AudibleAlert): + def __init__(self, audible_alert: log.SelfdriveState.AudibleAlert): super().__init__("", "", AlertStatus.normal, AlertSize.none, Priority.MID, VisualAlert.none, diff --git a/sunnypilot/selfdrive/ui/quiet_mode.py b/openpilot/sunnypilot/selfdrive/ui/quiet_mode.py similarity index 96% rename from sunnypilot/selfdrive/ui/quiet_mode.py rename to openpilot/sunnypilot/selfdrive/ui/quiet_mode.py index 739ea1392c..d4dba74d95 100644 --- a/sunnypilot/selfdrive/ui/quiet_mode.py +++ b/openpilot/sunnypilot/selfdrive/ui/quiet_mode.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/selfdrived/__init__.py b/openpilot/sunnypilot/sunnylink/__init__.py similarity index 100% rename from sunnypilot/selfdrive/selfdrived/__init__.py rename to openpilot/sunnypilot/sunnylink/__init__.py diff --git a/sunnypilot/sunnylink/api.py b/openpilot/sunnypilot/sunnylink/api.py similarity index 100% rename from sunnypilot/sunnylink/api.py rename to openpilot/sunnypilot/sunnylink/api.py diff --git a/sunnypilot/sunnylink/__init__.py b/openpilot/sunnypilot/sunnylink/athena/__init__.py similarity index 100% rename from sunnypilot/sunnylink/__init__.py rename to openpilot/sunnypilot/sunnylink/athena/__init__.py diff --git a/sunnypilot/sunnylink/athena/manage_sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/manage_sunnylinkd.py similarity index 100% rename from sunnypilot/sunnylink/athena/manage_sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/manage_sunnylinkd.py diff --git a/sunnypilot/sunnylink/athena/sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py similarity index 99% rename from sunnypilot/sunnylink/athena/sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py index 1a7e69f31c..ac168db7d8 100755 --- a/sunnypilot/sunnylink/athena/sunnylinkd.py +++ b/openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py @@ -16,8 +16,8 @@ import ssl import threading import time -from jsonrpc import dispatcher from functools import partial +from openpilot.system.athena.rpc import dispatcher from openpilot.common.params import Params, ParamKeyType from openpilot.common.realtime import set_core_affinity from openpilot.common.swaglog import cloudlog @@ -27,7 +27,7 @@ from openpilot.system.athena.athenad import ws_send, jsonrpc_handler, \ from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutException, create_connection, WebSocketConnectionClosedException) -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.sunnypilot.selfdrive.car.sync_sunnylink_params import update_car_list_param from openpilot.sunnypilot.sunnylink.api import SunnylinkApi diff --git a/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py similarity index 100% rename from sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py diff --git a/sunnypilot/sunnylink/backups/AESCipher.py b/openpilot/sunnypilot/sunnylink/backups/AESCipher.py similarity index 100% rename from sunnypilot/sunnylink/backups/AESCipher.py rename to openpilot/sunnypilot/sunnylink/backups/AESCipher.py diff --git a/sunnypilot/sunnylink/athena/__init__.py b/openpilot/sunnypilot/sunnylink/backups/__init__.py similarity index 100% rename from sunnypilot/sunnylink/athena/__init__.py rename to openpilot/sunnypilot/sunnylink/backups/__init__.py diff --git a/sunnypilot/sunnylink/backups/manager.py b/openpilot/sunnypilot/sunnylink/backups/manager.py similarity index 99% rename from sunnypilot/sunnylink/backups/manager.py rename to openpilot/sunnypilot/sunnylink/backups/manager.py index 44cdb3bff2..5ac6b8cabc 100644 --- a/sunnypilot/sunnylink/backups/manager.py +++ b/openpilot/sunnypilot/sunnylink/backups/manager.py @@ -16,9 +16,9 @@ from openpilot.common.git import get_branch from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_version +from openpilot.common.version import get_version -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from openpilot.sunnypilot.sunnylink.api import SunnylinkApi from openpilot.sunnypilot.sunnylink.backups.utils import decrypt_compressed_data, encrypt_compressed_data, SnakeCaseEncoder from openpilot.sunnypilot.sunnylink.utils import get_param_as_byte, save_param_from_base64_encoded_string diff --git a/sunnypilot/sunnylink/backups/utils.py b/openpilot/sunnypilot/sunnylink/backups/utils.py similarity index 100% rename from sunnypilot/sunnylink/backups/utils.py rename to openpilot/sunnypilot/sunnylink/backups/utils.py diff --git a/sunnypilot/sunnylink/capabilities.py b/openpilot/sunnypilot/sunnylink/capabilities.py similarity index 98% rename from sunnypilot/sunnylink/capabilities.py rename to openpilot/sunnypilot/sunnylink/capabilities.py index 197e404314..1f12b5b001 100644 --- a/sunnypilot/sunnylink/capabilities.py +++ b/openpilot/sunnypilot/sunnylink/capabilities.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import json -from cereal import car, custom, messaging +from openpilot.cereal import custom, messaging +from opendbc.car.structs import car from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR, UNSUPPORTED_LONGITUDINAL_CAR from opendbc.car.subaru.values import CAR as SUBARU_CAR, SubaruFlags from opendbc.sunnypilot.car.tesla.values import TeslaFlagsSP diff --git a/sunnypilot/sunnylink/docs/README.md b/openpilot/sunnypilot/sunnylink/docs/README.md similarity index 100% rename from sunnypilot/sunnylink/docs/README.md rename to openpilot/sunnypilot/sunnylink/docs/README.md diff --git a/sunnypilot/sunnylink/registration_manager.py b/openpilot/sunnypilot/sunnylink/registration_manager.py similarity index 95% rename from sunnypilot/sunnylink/registration_manager.py rename to openpilot/sunnypilot/sunnylink/registration_manager.py index 3e00c5c013..cc43dcae87 100755 --- a/sunnypilot/sunnylink/registration_manager.py +++ b/openpilot/sunnypilot/sunnylink/registration_manager.py @@ -5,7 +5,7 @@ from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog -from cereal import log, messaging +from openpilot.cereal import log, messaging from openpilot.sunnypilot.sunnylink.utils import register_sunnylink NetworkType = log.DeviceState.NetworkType diff --git a/sunnypilot/sunnylink/settings_ui.json b/openpilot/sunnypilot/sunnylink/settings_ui.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui.json rename to openpilot/sunnypilot/sunnylink/settings_ui.json diff --git a/sunnypilot/sunnylink/settings_ui.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_macros.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/_macros.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_macros.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_macros.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/device.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/display.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/models.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/software.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml diff --git a/sunnypilot/sunnylink/statsd.py b/openpilot/sunnypilot/sunnylink/statsd.py similarity index 97% rename from sunnypilot/sunnylink/statsd.py rename to openpilot/sunnypilot/sunnylink/statsd.py index f1ee18decd..7e8faf6327 100755 --- a/sunnypilot/sunnylink/statsd.py +++ b/openpilot/sunnypilot/sunnylink/statsd.py @@ -13,14 +13,14 @@ from collections import defaultdict from datetime import datetime, UTC from openpilot.common.params import Params -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE from openpilot.common.utils import atomic_write -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S -from openpilot.system.statsd import METRIC_TYPE, StatLogSP +from openpilot.sunnypilot.system.statsd import METRIC_TYPE, StatLogSP from openpilot.common.realtime import Ratekeeper STATSLOGSP = StatLogSP(intercept=False) diff --git a/sunnypilot/sunnylink/sunnylink_state.py b/openpilot/sunnypilot/sunnylink/sunnylink_state.py similarity index 99% rename from sunnypilot/sunnylink/sunnylink_state.py rename to openpilot/sunnypilot/sunnylink/sunnylink_state.py index a4a3df3a2b..7dc553951e 100644 --- a/sunnypilot/sunnylink/sunnylink_state.py +++ b/openpilot/sunnypilot/sunnylink/sunnylink_state.py @@ -11,7 +11,7 @@ import time import json import pyray as rl -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.sunnypilot.sunnylink.api import UNREGISTERED_SUNNYLINK_DONGLE_ID, SunnylinkApi diff --git a/sunnypilot/sunnylink/tests/test_capabilities.py b/openpilot/sunnypilot/sunnylink/tests/test_capabilities.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_capabilities.py rename to openpilot/sunnypilot/sunnylink/tests/test_capabilities.py diff --git a/sunnypilot/sunnylink/tests/test_compile_settings_ui.py b/openpilot/sunnypilot/sunnylink/tests/test_compile_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_compile_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tests/test_compile_settings_ui.py diff --git a/sunnypilot/sunnylink/tests/test_settings_changes.py b/openpilot/sunnypilot/sunnylink/tests/test_settings_changes.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_settings_changes.py rename to openpilot/sunnypilot/sunnylink/tests/test_settings_changes.py diff --git a/sunnypilot/sunnylink/tests/test_settings_schema.py b/openpilot/sunnypilot/sunnylink/tests/test_settings_schema.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_settings_schema.py rename to openpilot/sunnypilot/sunnylink/tests/test_settings_schema.py diff --git a/sunnypilot/sunnylink/tools/apply_macros.py b/openpilot/sunnypilot/sunnylink/tools/apply_macros.py similarity index 100% rename from sunnypilot/sunnylink/tools/apply_macros.py rename to openpilot/sunnypilot/sunnylink/tools/apply_macros.py diff --git a/sunnypilot/sunnylink/tools/compile_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/compile_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/compile_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/compile_settings_ui.py diff --git a/sunnypilot/sunnylink/tools/extract_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/extract_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/extract_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/extract_settings_ui.py diff --git a/sunnypilot/sunnylink/tools/generate_settings_schema.py b/openpilot/sunnypilot/sunnylink/tools/generate_settings_schema.py similarity index 100% rename from sunnypilot/sunnylink/tools/generate_settings_schema.py rename to openpilot/sunnypilot/sunnylink/tools/generate_settings_schema.py diff --git a/sunnypilot/sunnylink/tools/validate_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/validate_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/validate_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/validate_settings_ui.py diff --git a/sunnypilot/sunnylink/uploader.py b/openpilot/sunnypilot/sunnylink/uploader.py similarity index 99% rename from sunnypilot/sunnylink/uploader.py rename to openpilot/sunnypilot/sunnylink/uploader.py index c1da47fa0c..358e3a88e7 100755 --- a/sunnypilot/sunnylink/uploader.py +++ b/openpilot/sunnypilot/sunnylink/uploader.py @@ -9,8 +9,8 @@ import traceback import datetime from collections.abc import Iterator -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.sunnylink.api import SunnylinkApi from openpilot.common.utils import get_upload_stream from openpilot.common.params import Params diff --git a/sunnypilot/sunnylink/utils.py b/openpilot/sunnypilot/sunnylink/utils.py similarity index 98% rename from sunnypilot/sunnylink/utils.py rename to openpilot/sunnypilot/sunnylink/utils.py index 89c3c8a0c8..5588711977 100644 --- a/sunnypilot/sunnylink/utils.py +++ b/openpilot/sunnypilot/sunnylink/utils.py @@ -3,7 +3,7 @@ import gzip import json from openpilot.sunnypilot.sunnylink.api import SunnylinkApi, UNREGISTERED_SUNNYLINK_DONGLE_ID from openpilot.common.params import Params, ParamKeyType -from openpilot.system.version import is_prebuilt +from openpilot.common.version import is_prebuilt def get_sunnylink_status(params=None) -> tuple[bool, bool, bool]: diff --git a/sunnypilot/sunnylink/backups/__init__.py b/openpilot/sunnypilot/system/__init__.py similarity index 100% rename from sunnypilot/sunnylink/backups/__init__.py rename to openpilot/sunnypilot/system/__init__.py diff --git a/sunnypilot/system/hardware/c3/README.md b/openpilot/sunnypilot/system/hardware/c3/README.md similarity index 100% rename from sunnypilot/system/hardware/c3/README.md rename to openpilot/sunnypilot/system/hardware/c3/README.md diff --git a/sunnypilot/system/hardware/c3/agnos.json b/openpilot/sunnypilot/system/hardware/c3/agnos.json similarity index 100% rename from sunnypilot/system/hardware/c3/agnos.json rename to openpilot/sunnypilot/system/hardware/c3/agnos.json diff --git a/sunnypilot/system/hardware/c3/launch_chffrplus.sh b/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh similarity index 100% rename from sunnypilot/system/hardware/c3/launch_chffrplus.sh rename to openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh diff --git a/sunnypilot/system/hardware/c3/launch_env.sh b/openpilot/sunnypilot/system/hardware/c3/launch_env.sh similarity index 100% rename from sunnypilot/system/hardware/c3/launch_env.sh rename to openpilot/sunnypilot/system/hardware/c3/launch_env.sh diff --git a/sunnypilot/system/params_migration.py b/openpilot/sunnypilot/system/params_migration.py similarity index 100% rename from sunnypilot/system/params_migration.py rename to openpilot/sunnypilot/system/params_migration.py diff --git a/sunnypilot/system/sensord/.gitignore b/openpilot/sunnypilot/system/sensord/.gitignore similarity index 100% rename from sunnypilot/system/sensord/.gitignore rename to openpilot/sunnypilot/system/sensord/.gitignore diff --git a/sunnypilot/system/sensord/SConscript b/openpilot/sunnypilot/system/sensord/SConscript similarity index 100% rename from sunnypilot/system/sensord/SConscript rename to openpilot/sunnypilot/system/sensord/SConscript diff --git a/sunnypilot/system/sensord/sensors/bmx055_accel.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_accel.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_accel.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_accel.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_gyro.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_gyro.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_gyro.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_gyro.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_magn.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_magn.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_magn.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_magn.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_temp.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_temp.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_temp.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_temp.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.h diff --git a/sunnypilot/system/sensord/sensors/constants.h b/openpilot/sunnypilot/system/sensord/sensors/constants.h similarity index 100% rename from sunnypilot/system/sensord/sensors/constants.h rename to openpilot/sunnypilot/system/sensord/sensors/constants.h diff --git a/sunnypilot/system/sensord/sensors/i2c_sensor.cc b/openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/i2c_sensor.cc rename to openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.cc diff --git a/sunnypilot/system/sensord/sensors/i2c_sensor.h b/openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.h similarity index 100% rename from sunnypilot/system/sensord/sensors/i2c_sensor.h rename to openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_accel.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_temp.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h diff --git a/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc b/openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc rename to openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc diff --git a/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h b/openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h similarity index 100% rename from sunnypilot/system/sensord/sensors/mmc5603nj_magn.h rename to openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h diff --git a/sunnypilot/system/sensord/sensors/sensor.h b/openpilot/sunnypilot/system/sensord/sensors/sensor.h similarity index 100% rename from sunnypilot/system/sensord/sensors/sensor.h rename to openpilot/sunnypilot/system/sensord/sensors/sensor.h diff --git a/sunnypilot/system/sensord/sensors_qcom2.cc b/openpilot/sunnypilot/system/sensord/sensors_qcom2.cc similarity index 100% rename from sunnypilot/system/sensord/sensors_qcom2.cc rename to openpilot/sunnypilot/system/sensord/sensors_qcom2.cc diff --git a/sunnypilot/system/sensord/tests/test_sensord.py b/openpilot/sunnypilot/system/sensord/tests/test_sensord.py similarity index 97% rename from sunnypilot/system/sensord/tests/test_sensord.py rename to openpilot/sunnypilot/system/sensord/tests/test_sensord.py index 9e09930f0c..98321fb12c 100644 --- a/sunnypilot/system/sensord/tests/test_sensord.py +++ b/openpilot/sunnypilot/system/sensord/tests/test_sensord.py @@ -1,12 +1,13 @@ import os +import subprocess import pytest import time import numpy as np from collections import namedtuple, defaultdict -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.gpio import get_irqs_for_action from openpilot.common.timeout import Timeout from openpilot.common.hardware import HARDWARE @@ -110,7 +111,7 @@ class TestSensord: os.environ["LSM_SELF_TEST"] = "1" # read initial sensor values every test case can use - os.system("pkill -f \\\\./sensord") + subprocess.run(["pkill", "-f", r"\\./sensord"], check=False) try: managed_processes["sensord"].start() cls.sample_secs = int(os.getenv("SAMPLE_SECS", "10")) diff --git a/sunnypilot/system/sensord/tests/ttff_test.py b/openpilot/sunnypilot/system/sensord/tests/ttff_test.py similarity index 96% rename from sunnypilot/system/sensord/tests/ttff_test.py rename to openpilot/sunnypilot/system/sensord/tests/ttff_test.py index a9cc16d707..cc8408055c 100755 --- a/sunnypilot/system/sensord/tests/ttff_test.py +++ b/openpilot/sunnypilot/system/sensord/tests/ttff_test.py @@ -3,7 +3,7 @@ import time import atexit -from cereal import messaging +from openpilot.cereal import messaging from openpilot.system.manager.process_config import managed_processes TIMEOUT = 10*60 diff --git a/system/statsd.py b/openpilot/sunnypilot/system/statsd.py similarity index 98% rename from system/statsd.py rename to openpilot/sunnypilot/system/statsd.py index 4b2e67caeb..ff77a5a57f 100755 --- a/system/statsd.py +++ b/openpilot/sunnypilot/system/statsd.py @@ -13,12 +13,12 @@ from datetime import datetime, UTC, date from typing import NoReturn from openpilot.common.params import Params -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE from openpilot.common.utils import atomic_write -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S diff --git a/sunnypilot/system/updated/tests/test_sp_branch_migrations.py b/openpilot/sunnypilot/system/updated/tests/test_sp_branch_migrations.py similarity index 100% rename from sunnypilot/system/updated/tests/test_sp_branch_migrations.py rename to openpilot/sunnypilot/system/updated/tests/test_sp_branch_migrations.py diff --git a/sunnypilot/system/__init__.py b/openpilot/sunnypilot/tools/__init__.py similarity index 100% rename from sunnypilot/system/__init__.py rename to openpilot/sunnypilot/tools/__init__.py diff --git a/sunnypilot/tools/__init__.py b/openpilot/sunnypilot/tools/memory_profiler/__init__.py similarity index 100% rename from sunnypilot/tools/__init__.py rename to openpilot/sunnypilot/tools/memory_profiler/__init__.py diff --git a/sunnypilot/tools/memory_profiler/mem_usage.py b/openpilot/sunnypilot/tools/memory_profiler/mem_usage.py similarity index 100% rename from sunnypilot/tools/memory_profiler/mem_usage.py rename to openpilot/sunnypilot/tools/memory_profiler/mem_usage.py diff --git a/sunnypilot/tools/pull_footage.py b/openpilot/sunnypilot/tools/pull_footage.py similarity index 100% rename from sunnypilot/tools/pull_footage.py rename to openpilot/sunnypilot/tools/pull_footage.py diff --git a/openpilot/system b/openpilot/system deleted file mode 120000 index 16f8cc2b23..0000000000 --- a/openpilot/system +++ /dev/null @@ -1 +0,0 @@ -../system/ \ No newline at end of file diff --git a/sunnypilot/tools/memory_profiler/__init__.py b/openpilot/system/__init__.py similarity index 100% rename from sunnypilot/tools/memory_profiler/__init__.py rename to openpilot/system/__init__.py diff --git a/system/__init__.py b/openpilot/system/athena/__init__.py similarity index 100% rename from system/__init__.py rename to openpilot/system/athena/__init__.py diff --git a/system/athena/athenad.py b/openpilot/system/athena/athenad.py similarity index 98% rename from system/athena/athenad.py rename to openpilot/system/athena/athenad.py index 3d61a723f6..5a84b8422a 100755 --- a/system/athena/athenad.py +++ b/openpilot/system/athena/athenad.py @@ -25,13 +25,13 @@ from collections.abc import Callable import requests from requests.adapters import HTTPAdapter, DEFAULT_POOLBLOCK -from jsonrpc import JSONRPCResponseManager, dispatcher from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutException, create_connection) -import cereal.messaging as messaging -from cereal import car, log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.api import Api, get_key_pair from openpilot.common.utils import CallbackReader, get_upload_stream from openpilot.common.params import Params @@ -39,8 +39,9 @@ from openpilot.common.realtime import set_core_affinity from openpilot.common.hardware import HARDWARE, PC from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths +from openpilot.system.athena.rpc import dispatcher, handle, is_call, is_response, loads ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') @@ -214,11 +215,11 @@ def jsonrpc_handler(end_event: threading.Event, localProxyHandler = None) -> Non while not end_event.is_set(): try: data = recv_queue.get(timeout=1) - if "method" in data: + msg = loads(data) + if is_call(msg): cloudlog.event("athena.jsonrpc_handler.call_method", data=data) - response = JSONRPCResponseManager.handle(data, dispatcher) - send_queue_push(response.json, SEND_PRIORITY_HIGH) - elif "id" in data and ("result" in data or "error" in data): + send_queue_push(handle(msg, dispatcher), SEND_PRIORITY_HIGH) + elif is_response(msg): log_recv_queue.put_nowait(data) else: raise Exception("not a valid request or response") @@ -616,7 +617,7 @@ def startStream(sdp: str, enabled: bool) -> dict: else: raise Exception("failed to get CarParamsPersistent") - if not params.get_bool("IsOnroad"): + if params.get_bool("IsOffroad"): # manager owns camerad/stream_encoderd/webrtcd; flip the param and let it bring them up. # webrtcd clears IsLiveStreaming when the session ends params.put_bool("IsLiveStreaming", True) @@ -914,7 +915,7 @@ def ws_manage(ws: WebSocket, end_event: threading.Event) -> None: sock = ws.sock while not end_event.wait(5): - onroad = params.get_bool("IsOnroad") + onroad = not params.get_bool("IsOffroad") if onroad != onroad_prev: onroad_prev = onroad diff --git a/system/athena/manage_athenad.py b/openpilot/system/athena/manage_athenad.py similarity index 96% rename from system/athena/manage_athenad.py rename to openpilot/system/athena/manage_athenad.py index 67682dd86e..7ab88fb67e 100755 --- a/system/athena/manage_athenad.py +++ b/openpilot/system/athena/manage_athenad.py @@ -7,7 +7,7 @@ from openpilot.common.params import Params from openpilot.system.manager.process import launcher from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata ATHENA_MGR_PID_PARAM = "AthenadPid" diff --git a/system/athena/registration.py b/openpilot/system/athena/registration.py similarity index 100% rename from system/athena/registration.py rename to openpilot/system/athena/registration.py diff --git a/openpilot/system/athena/rpc.py b/openpilot/system/athena/rpc.py new file mode 100644 index 0000000000..aaf7f41fc3 --- /dev/null +++ b/openpilot/system/athena/rpc.py @@ -0,0 +1,116 @@ +import json +from collections.abc import Callable, Mapping +from typing import Any + +# a minimal implementation of json-rpc 2.0 https://www.jsonrpc.org/specification + +JSONRPC_VERSION = "2.0" + +# JSON-RPC 2.0 reserved / application error codes +PARSE_ERROR = -32700 +INVALID_REQUEST = -32600 +METHOD_NOT_FOUND = -32601 +INVALID_PARAMS = -32602 +SERVER_ERROR = -32000 + +JsonDict = dict[str, Any] +MethodMap = Mapping[str, Callable[..., Any]] + + +class Dispatcher(dict[str, Callable[..., Any]]): + def add_method(self, f: Callable[..., Any] | None = None, *, name: str | None = None): + def decorator(fn: Callable[..., Any]) -> Callable[..., Any]: + self[name or fn.__name__] = fn + return fn + return decorator(f) if f is not None else decorator + + +dispatcher = Dispatcher() + + +def dumps_call(method: str, params: Any = None, request_id: Any = None) -> str: + msg: JsonDict = {"jsonrpc": JSONRPC_VERSION, "method": method, "id": request_id} + if params is not None: + msg["params"] = params + return json.dumps(msg) + + +def dumps_result(request_id: Any, result: Any) -> str: + return json.dumps({"jsonrpc": JSONRPC_VERSION, "id": request_id, "result": result}) + + +def dumps_error(request_id: Any, message: str, code: int = SERVER_ERROR) -> str: + return json.dumps({ + "jsonrpc": JSONRPC_VERSION, + "id": request_id, + "error": {"code": code, "message": message}, + }) + + +def loads(raw: str | bytes) -> JsonDict: + if isinstance(raw, bytes): + raw = raw.decode() + data = json.loads(raw) + if not isinstance(data, dict): + raise ValueError("message must be a JSON object") + return data + + +def is_call(msg: JsonDict) -> bool: + return "method" in msg + + +def is_response(msg: JsonDict) -> bool: + return "id" in msg and ("result" in msg or "error" in msg) + + +def error_message(err: Any) -> str: + """Normalize JSON-RPC object errors and plain-string errors.""" + if isinstance(err, str): + return err + if isinstance(err, dict): + data = err.get("data") + if isinstance(data, dict) and data.get("message"): + return str(data["message"]) + if err.get("message") is not None: + return str(err["message"]) + return str(err) + + +def _invoke(fn: Callable[..., Any], params: Any) -> Any: + if params is None: + return fn() + if isinstance(params, dict): + return fn(**params) + if isinstance(params, (list, tuple)): + return fn(*params) + raise TypeError("params must be a list, object, or omitted") + + +def handle(raw: str | bytes | JsonDict, methods: MethodMap | None = None) -> str: + methods = dispatcher if methods is None else methods + + try: + msg = raw if isinstance(raw, dict) else loads(raw) + except (TypeError, ValueError, UnicodeDecodeError): + return dumps_error(None, "parse error", PARSE_ERROR) + + if not is_call(msg): + raise ValueError("not a call") + + req_id = msg.get("id") + name = msg.get("method") + if not isinstance(name, str): + return dumps_error(req_id, "invalid request", INVALID_REQUEST) + + try: + fn = methods[name] + except KeyError: + return dumps_error(req_id, f"method not found: {name}", METHOD_NOT_FOUND) + + try: + return dumps_result(req_id, _invoke(fn, msg.get("params"))) + except TypeError as e: + return dumps_error(req_id, str(e), INVALID_PARAMS) + except Exception as e: + return dumps_error(req_id, str(e), SERVER_ERROR) diff --git a/system/athena/__init__.py b/openpilot/system/athena/tests/__init__.py similarity index 100% rename from system/athena/__init__.py rename to openpilot/system/athena/tests/__init__.py diff --git a/system/athena/tests/helpers.py b/openpilot/system/athena/tests/helpers.py similarity index 100% rename from system/athena/tests/helpers.py rename to openpilot/system/athena/tests/helpers.py diff --git a/system/athena/tests/test_athenad.py b/openpilot/system/athena/tests/test_athenad.py similarity index 99% rename from system/athena/tests/test_athenad.py rename to openpilot/system/athena/tests/test_athenad.py index 0e3ae68d4e..253a057b91 100644 --- a/system/athena/tests/test_athenad.py +++ b/openpilot/system/athena/tests/test_athenad.py @@ -14,7 +14,7 @@ from datetime import datetime, timedelta from websocket import ABNF from websocket._exceptions import WebSocketConnectionClosedException -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.timeout import Timeout diff --git a/system/athena/tests/test_athenad_ping.py b/openpilot/system/athena/tests/test_athenad_ping.py similarity index 95% rename from system/athena/tests/test_athenad_ping.py rename to openpilot/system/athena/tests/test_athenad_ping.py index 7f44263162..44a6b8a56b 100644 --- a/system/athena/tests/test_athenad_ping.py +++ b/openpilot/system/athena/tests/test_athenad_ping.py @@ -7,7 +7,6 @@ from typing import cast from openpilot.common.params import Params from openpilot.common.timeout import Timeout from openpilot.system.athena import athenad -from openpilot.system.manager.helpers import write_onroad_params from openpilot.common.hardware import TICI TIMEOUT_TOLERANCE = 20 # seconds @@ -93,10 +92,10 @@ class TestAthenadPing: @pytest.mark.skipif(not TICI, reason="only run on desk") def test_offroad(self, subtests, mocker) -> None: - write_onroad_params(False, self.params) + self.params.put_bool("IsOffroad", True, block=True) self.assertTimeout(60 + TIMEOUT_TOLERANCE, subtests, mocker) # based using TCP keepalive settings @pytest.mark.skipif(not TICI, reason="only run on desk") def test_onroad(self, subtests, mocker) -> None: - write_onroad_params(True, self.params) + self.params.put_bool("IsOffroad", False, block=True) self.assertTimeout(21 + TIMEOUT_TOLERANCE, subtests, mocker) diff --git a/system/athena/tests/test_registration.py b/openpilot/system/athena/tests/test_registration.py similarity index 100% rename from system/athena/tests/test_registration.py rename to openpilot/system/athena/tests/test_registration.py diff --git a/system/camerad/SConscript b/openpilot/system/camerad/SConscript similarity index 100% rename from system/camerad/SConscript rename to openpilot/system/camerad/SConscript diff --git a/system/athena/tests/__init__.py b/openpilot/system/camerad/__init__.py similarity index 100% rename from system/athena/tests/__init__.py rename to openpilot/system/camerad/__init__.py diff --git a/system/camerad/cameras/bps_blobs.h b/openpilot/system/camerad/cameras/bps_blobs.h similarity index 100% rename from system/camerad/cameras/bps_blobs.h rename to openpilot/system/camerad/cameras/bps_blobs.h diff --git a/system/camerad/cameras/camera_common.cc b/openpilot/system/camerad/cameras/camera_common.cc similarity index 100% rename from system/camerad/cameras/camera_common.cc rename to openpilot/system/camerad/cameras/camera_common.cc diff --git a/system/camerad/cameras/camera_common.h b/openpilot/system/camerad/cameras/camera_common.h similarity index 95% rename from system/camerad/cameras/camera_common.h rename to openpilot/system/camerad/cameras/camera_common.h index 7f35e06a83..24f70dbcf3 100644 --- a/system/camerad/cameras/camera_common.h +++ b/openpilot/system/camerad/cameras/camera_common.h @@ -2,7 +2,7 @@ #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionipc_server.h" #include "common/util.h" diff --git a/system/camerad/cameras/camera_qcom2.cc b/openpilot/system/camerad/cameras/camera_qcom2.cc similarity index 100% rename from system/camerad/cameras/camera_qcom2.cc rename to openpilot/system/camerad/cameras/camera_qcom2.cc diff --git a/system/camerad/cameras/cdm.cc b/openpilot/system/camerad/cameras/cdm.cc similarity index 100% rename from system/camerad/cameras/cdm.cc rename to openpilot/system/camerad/cameras/cdm.cc diff --git a/system/camerad/cameras/cdm.h b/openpilot/system/camerad/cameras/cdm.h similarity index 100% rename from system/camerad/cameras/cdm.h rename to openpilot/system/camerad/cameras/cdm.h diff --git a/system/camerad/cameras/hw.h b/openpilot/system/camerad/cameras/hw.h similarity index 97% rename from system/camerad/cameras/hw.h rename to openpilot/system/camerad/cameras/hw.h index defe878e89..be0bea872d 100644 --- a/system/camerad/cameras/hw.h +++ b/openpilot/system/camerad/cameras/hw.h @@ -1,7 +1,7 @@ #pragma once #include "common/util.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "msgq/visionipc/visionipc_server.h" #include "media/cam_isp_ife.h" diff --git a/system/camerad/cameras/ife.h b/openpilot/system/camerad/cameras/ife.h similarity index 100% rename from system/camerad/cameras/ife.h rename to openpilot/system/camerad/cameras/ife.h diff --git a/system/camerad/cameras/nv12_info.h b/openpilot/system/camerad/cameras/nv12_info.h similarity index 100% rename from system/camerad/cameras/nv12_info.h rename to openpilot/system/camerad/cameras/nv12_info.h diff --git a/system/camerad/cameras/nv12_info.py b/openpilot/system/camerad/cameras/nv12_info.py similarity index 92% rename from system/camerad/cameras/nv12_info.py rename to openpilot/system/camerad/cameras/nv12_info.py index 2cadc29364..abd734ba50 100644 --- a/system/camerad/cameras/nv12_info.py +++ b/openpilot/system/camerad/cameras/nv12_info.py @@ -1,4 +1,4 @@ -# Python version of system/camerad/cameras/nv12_info.h +# Python version of openpilot/system/camerad/cameras/nv12_info.h # Calculations from media/msm_media_info.h (VENUS_BUFFER_SIZE) def align(val: int, alignment: int) -> int: diff --git a/system/camerad/cameras/spectra.cc b/openpilot/system/camerad/cameras/spectra.cc similarity index 100% rename from system/camerad/cameras/spectra.cc rename to openpilot/system/camerad/cameras/spectra.cc diff --git a/system/camerad/cameras/spectra.h b/openpilot/system/camerad/cameras/spectra.h similarity index 100% rename from system/camerad/cameras/spectra.h rename to openpilot/system/camerad/cameras/spectra.h diff --git a/system/camerad/main.cc b/openpilot/system/camerad/main.cc similarity index 100% rename from system/camerad/main.cc rename to openpilot/system/camerad/main.cc diff --git a/system/camerad/sensors/os04c10.cc b/openpilot/system/camerad/sensors/os04c10.cc similarity index 100% rename from system/camerad/sensors/os04c10.cc rename to openpilot/system/camerad/sensors/os04c10.cc diff --git a/system/camerad/sensors/os04c10_registers.h b/openpilot/system/camerad/sensors/os04c10_registers.h similarity index 100% rename from system/camerad/sensors/os04c10_registers.h rename to openpilot/system/camerad/sensors/os04c10_registers.h diff --git a/system/camerad/sensors/ox03c10.cc b/openpilot/system/camerad/sensors/ox03c10.cc similarity index 100% rename from system/camerad/sensors/ox03c10.cc rename to openpilot/system/camerad/sensors/ox03c10.cc diff --git a/system/camerad/sensors/ox03c10_registers.h b/openpilot/system/camerad/sensors/ox03c10_registers.h similarity index 100% rename from system/camerad/sensors/ox03c10_registers.h rename to openpilot/system/camerad/sensors/ox03c10_registers.h diff --git a/system/camerad/sensors/sensor.h b/openpilot/system/camerad/sensors/sensor.h similarity index 98% rename from system/camerad/sensors/sensor.h rename to openpilot/system/camerad/sensors/sensor.h index 1a647d1528..251f5d64b4 100644 --- a/system/camerad/sensors/sensor.h +++ b/openpilot/system/camerad/sensors/sensor.h @@ -9,7 +9,7 @@ #include "media/cam_isp.h" #include "media/cam_sensor.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "system/camerad/sensors/ox03c10_registers.h" #include "system/camerad/sensors/os04c10_registers.h" diff --git a/system/camerad/snapshot.py b/openpilot/system/camerad/snapshot.py similarity index 53% rename from system/camerad/snapshot.py rename to openpilot/system/camerad/snapshot.py index 241f027044..8383865fce 100755 --- a/system/camerad/snapshot.py +++ b/openpilot/system/camerad/snapshot.py @@ -1,17 +1,10 @@ #!/usr/bin/env python3 -import subprocess -import time import numpy as np -from PIL import Image -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from msgq.visionipc import VisionIpcClient, VisionStreamType -from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL -from openpilot.common.hardware import PC -from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.manager.process_config import managed_processes VISION_STREAMS = { @@ -21,11 +14,6 @@ VISION_STREAMS = { } -def jpeg_write(fn, dat): - img = Image.fromarray(dat) - img.save(fn, "JPEG") - - def yuv_to_rgb(y, u, v): ul = np.repeat(np.repeat(u, 2).reshape(u.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) vl = np.repeat(np.repeat(v, 2).reshape(v.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) @@ -77,55 +65,3 @@ def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"): c = vipc_clients[front_frame] front = extract_image(c.recv()) return rear, front - - -def snapshot(): - params = Params() - - if (not params.get_bool("IsOffroad")) or params.get_bool("IsTakingSnapshot"): - print("Already taking snapshot") - return None, None - - front_camera_allowed = params.get_bool("RecordFront") - params.put_bool("IsTakingSnapshot", True, block=True) - set_offroad_alert("Offroad_IsTakingSnapshot", True) - time.sleep(2.0) # Give hardwared time to read the param, or if just started give camerad time to start - - # Check if camerad is already started - try: - subprocess.check_call(["pgrep", "camerad"]) - print("Camerad already running") - params.put_bool("IsTakingSnapshot", False, block=True) - params.remove("Offroad_IsTakingSnapshot") - return None, None - except subprocess.CalledProcessError: - pass - - try: - # Allow testing on replay on PC - if not PC: - managed_processes['camerad'].start() - - frame = "wideRoadCameraState" - front_frame = "driverCameraState" if front_camera_allowed else None - rear, front = get_snapshots(frame, front_frame) - finally: - managed_processes['camerad'].stop() - params.put_bool("IsTakingSnapshot", False, block=True) - set_offroad_alert("Offroad_IsTakingSnapshot", False) - - if not front_camera_allowed: - front = None - - return rear, front - - -if __name__ == "__main__": - pic, fpic = snapshot() - if pic is not None: - print(pic.shape) - jpeg_write("/tmp/back.jpg", pic) - if fpic is not None: - jpeg_write("/tmp/front.jpg", fpic) - else: - print("Error taking snapshot") diff --git a/system/camerad/test/.gitignore b/openpilot/system/camerad/test/.gitignore similarity index 100% rename from system/camerad/test/.gitignore rename to openpilot/system/camerad/test/.gitignore diff --git a/system/camerad/test/debug.sh b/openpilot/system/camerad/test/debug.sh similarity index 100% rename from system/camerad/test/debug.sh rename to openpilot/system/camerad/test/debug.sh diff --git a/system/camerad/test/icp_debug.sh b/openpilot/system/camerad/test/icp_debug.sh similarity index 100% rename from system/camerad/test/icp_debug.sh rename to openpilot/system/camerad/test/icp_debug.sh diff --git a/system/camerad/test/intercept.sh b/openpilot/system/camerad/test/intercept.sh similarity index 100% rename from system/camerad/test/intercept.sh rename to openpilot/system/camerad/test/intercept.sh diff --git a/system/camerad/test/stress_restart.sh b/openpilot/system/camerad/test/stress_restart.sh similarity index 100% rename from system/camerad/test/stress_restart.sh rename to openpilot/system/camerad/test/stress_restart.sh diff --git a/system/camerad/test/test_ae_gray.cc b/openpilot/system/camerad/test/test_ae_gray.cc similarity index 100% rename from system/camerad/test/test_ae_gray.cc rename to openpilot/system/camerad/test/test_ae_gray.cc diff --git a/system/camerad/test/test_camerad.py b/openpilot/system/camerad/test/test_camerad.py similarity index 99% rename from system/camerad/test/test_camerad.py rename to openpilot/system/camerad/test/test_camerad.py index 3abe4db654..afc49c02bf 100644 --- a/system/camerad/test/test_camerad.py +++ b/openpilot/system/camerad/test/test_camerad.py @@ -3,7 +3,7 @@ import time import pytest import numpy as np -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.log_time_series import msgs_to_time_series from openpilot.system.camerad.snapshot import get_snapshots from openpilot.selfdrive.test.helpers import collect_logs, log_collector, processes_context diff --git a/system/camerad/webcam/README.md b/openpilot/system/camerad/webcam/README.md similarity index 84% rename from system/camerad/webcam/README.md rename to openpilot/system/camerad/webcam/README.md index 2c0ce6a8af..17d7ee6d80 100644 --- a/system/camerad/webcam/README.md +++ b/openpilot/system/camerad/webcam/README.md @@ -10,7 +10,7 @@ ## GO ``` -USE_WEBCAM=1 system/manager/manager.py +USE_WEBCAM=1 openpilot/system/manager/manager.py ``` - Start the car, then the UI should show the road webcam's view - Adjust and secure the webcam @@ -20,5 +20,5 @@ USE_WEBCAM=1 system/manager/manager.py Use the `ROAD_CAM` (default 0) and optional `DRIVER_CAM`, `WIDE_CAM` environment variables to specify which camera is which (ie. `ROAD_CAM=1` uses `/dev/video1`, on Ubuntu, for the road camera): ``` -USE_WEBCAM=1 ROAD_CAM=1 system/manager/manager.py +USE_WEBCAM=1 ROAD_CAM=1 openpilot/system/manager/manager.py ``` diff --git a/system/camerad/webcam/camera.py b/openpilot/system/camerad/webcam/camera.py similarity index 100% rename from system/camerad/webcam/camera.py rename to openpilot/system/camerad/webcam/camera.py diff --git a/system/camerad/webcam/camerad.py b/openpilot/system/camerad/webcam/camerad.py similarity index 98% rename from system/camerad/webcam/camerad.py rename to openpilot/system/camerad/webcam/camerad.py index 401eec106f..c46482360d 100755 --- a/system/camerad/webcam/camerad.py +++ b/openpilot/system/camerad/webcam/camerad.py @@ -5,7 +5,7 @@ import platform from collections import namedtuple from msgq.visionipc import VisionIpcServer, VisionStreamType -from cereal import messaging +from openpilot.cereal import messaging from openpilot.system.camerad.webcam.camera import Camera from openpilot.common.realtime import Ratekeeper diff --git a/system/hardware/fan_controller.py b/openpilot/system/hardware/fan_controller.py similarity index 100% rename from system/hardware/fan_controller.py rename to openpilot/system/hardware/fan_controller.py diff --git a/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py similarity index 96% rename from system/hardware/hardwared.py rename to openpilot/system/hardware/hardwared.py index eb7848edfd..e5b3d8020c 100755 --- a/system/hardware/hardwared.py +++ b/openpilot/system/hardware/hardwared.py @@ -7,23 +7,24 @@ import threading import time from collections import OrderedDict, namedtuple -import psutil - -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import strip_deprecated_keys from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import HARDWARE, TICI +from openpilot.common.hardware.usb import get_usb_state, set_usb_state +from openpilot.common.linux import LinuxSystemStats from openpilot.system.loggerd.config import get_available_percent -from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog +from openpilot.sunnypilot.system.statsd import statlog from openpilot.system.hardware.power_monitoring import PowerMonitoring from openpilot.system.hardware.fan_controller import FanController -from openpilot.system.version import terms_version, training_version, get_build_metadata, terms_version_sp +from openpilot.common.version import terms_version, training_version, get_build_metadata, terms_version_sp + ThermalStatus = log.DeviceState.ThermalStatus NetworkType = log.DeviceState.NetworkType @@ -36,7 +37,7 @@ ONROAD_CYCLE_TIME = 1 # seconds to wait offroad after requesting an onroad cycl ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp']) HardwareState = namedtuple("HardwareState", ['network_type', 'network_info', 'network_strength', 'network_stats', - 'network_metered', 'modem_temps']) + 'network_metered', 'modem_temps', 'usb_state']) # List of thermal bands. We will stay within this region as long as we are within the bounds. # When exiting the bounds, we'll jump to the lower or higher band. Bands are ordered in the dict. @@ -124,6 +125,7 @@ def hw_state_thread(end_event, hw_queue): network_stats={'wwanTx': tx, 'wwanRx': rx}, network_metered=HARDWARE.get_network_metered(network_type), modem_temps=modem_temps, + usb_state=get_usb_state(), ) try: @@ -140,6 +142,7 @@ def hw_state_thread(end_event, hw_queue): def hardware_thread(end_event, hw_queue) -> None: + system_stats = LinuxSystemStats() pm = messaging.PubMaster(['deviceState']) sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "selfdriveState", "pandaStates"], poll="pandaStates") @@ -166,6 +169,7 @@ def hardware_thread(end_event, hw_queue) -> None: network_strength=NetworkStrength.unknown, network_stats={'wwanTx': -1, 'wwanRx': -1}, modem_temps=[], + usb_state=[], ) all_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_HW, initialized=False) @@ -229,9 +233,9 @@ def hardware_thread(end_event, hw_queue) -> None: pass msg.deviceState.freeSpacePercent = get_available_percent(default=100.0) - msg.deviceState.memoryUsagePercent = int(round(psutil.virtual_memory().percent)) + msg.deviceState.memoryUsagePercent = int(round(system_stats.memory_usage_percent())) msg.deviceState.gpuUsagePercent = int(round(HARDWARE.get_gpu_usage_percent())) - online_cpu_usage = [int(round(n)) for n in psutil.cpu_percent(percpu=True)] + online_cpu_usage = [int(round(n)) for n in system_stats.cpu_usage_percent()] offline_cpu_usage = [0., ] * (len(msg.deviceState.cpuTempC) - len(online_cpu_usage)) msg.deviceState.cpuUsagePercent = online_cpu_usage + offline_cpu_usage @@ -246,6 +250,8 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.screenBrightnessPercent = HARDWARE.get_screen_brightness() + set_usb_state(msg.deviceState, last_hw_state.usb_state) + # this subset is only used for offroad temp_sources = [ msg.deviceState.memoryTempC, @@ -286,7 +292,6 @@ def hardware_thread(end_event, hw_queue) -> None: startup_conditions["free_space"] = msg.deviceState.freeSpacePercent > 2 startup_conditions["completed_training"] = params.get("CompletedTrainingVersion") == training_version startup_conditions["not_driver_view"] = not params.get_bool("IsDriverViewEnabled") - startup_conditions["not_taking_snapshot"] = not params.get_bool("IsTakingSnapshot") # must be at an engageable thermal band to go onroad startup_conditions["device_temp_engageable"] = thermal_status < ThermalStatus.overheated @@ -397,7 +402,6 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.thermalStatus = thermal_status pm.send("deviceState", msg) - # Log to statsd statlog.gauge("free_space_percent", msg.deviceState.freeSpacePercent) statlog.gauge("gpu_usage_percent", msg.deviceState.gpuUsagePercent) statlog.gauge("memory_usage_percent", msg.deviceState.memoryUsagePercent) diff --git a/system/hardware/power_monitoring.py b/openpilot/system/hardware/power_monitoring.py similarity index 99% rename from system/hardware/power_monitoring.py rename to openpilot/system/hardware/power_monitoring.py index fdafc5e15d..ca3390b8f0 100644 --- a/system/hardware/power_monitoring.py +++ b/openpilot/system/hardware/power_monitoring.py @@ -4,7 +4,7 @@ import threading from openpilot.common.params import Params from openpilot.common.hardware import HARDWARE from openpilot.common.swaglog import cloudlog -from openpilot.system.statsd import statlog +from openpilot.sunnypilot.system.statsd import statlog CAR_VOLTAGE_LOW_PASS_K = 0.011 # LPF gain for 45s tau (dt/tau / (dt/tau + 1)) diff --git a/system/camerad/__init__.py b/openpilot/system/hardware/tests/__init__.py similarity index 100% rename from system/camerad/__init__.py rename to openpilot/system/hardware/tests/__init__.py diff --git a/system/hardware/tests/test_fan_controller.py b/openpilot/system/hardware/tests/test_fan_controller.py similarity index 61% rename from system/hardware/tests/test_fan_controller.py rename to openpilot/system/hardware/tests/test_fan_controller.py index ee39a24f87..e1aceeb081 100644 --- a/system/hardware/tests/test_fan_controller.py +++ b/openpilot/system/hardware/tests/test_fan_controller.py @@ -4,10 +4,6 @@ from openpilot.system.hardware.fan_controller import FanController ALL_CONTROLLERS = [FanController] -def patched_controller(mocker, controller_class): - mocker.patch("os.system", new=mocker.Mock()) - return controller_class(2) - class TestFanController: def wind_up(self, controller, ignition=True): for _ in range(1000): @@ -18,32 +14,32 @@ class TestFanController: controller.update(10, ignition) @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_hot_onroad(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_hot_onroad(self, controller_class): + controller = controller_class(2) self.wind_up(controller) assert controller.update(100, True) >= 70 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_offroad_limits(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_offroad_limits(self, controller_class): + controller = controller_class(2) self.wind_up(controller) assert controller.update(100, False) <= 30 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_no_fan_wear(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_no_fan_wear(self, controller_class): + controller = controller_class(2) self.wind_down(controller) assert controller.update(10, False) == 0 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_limited(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_limited(self, controller_class): + controller = controller_class(2) self.wind_up(controller, True) assert controller.update(100, True) == 100 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_windup_speed(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_windup_speed(self, controller_class): + controller = controller_class(2) self.wind_down(controller, True) for _ in range(10): controller.update(90, True) diff --git a/system/hardware/tests/test_power_monitoring.py b/openpilot/system/hardware/tests/test_power_monitoring.py similarity index 100% rename from system/hardware/tests/test_power_monitoring.py rename to openpilot/system/hardware/tests/test_power_monitoring.py diff --git a/system/hardware/tici/agnos.json b/openpilot/system/hardware/tici/agnos.json similarity index 100% rename from system/hardware/tici/agnos.json rename to openpilot/system/hardware/tici/agnos.json diff --git a/system/journald.py b/openpilot/system/journald.py similarity index 79% rename from system/journald.py rename to openpilot/system/journald.py index 37158b9251..091494b652 100755 --- a/system/journald.py +++ b/openpilot/system/journald.py @@ -2,12 +2,12 @@ import json import subprocess -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.swaglog import cloudlog def main(): - pm = messaging.PubMaster(['androidLog']) + pm = messaging.PubMaster(['operatingSystemLog']) cmd = ['journalctl', '-f', '-o', 'json'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True) assert proc.stdout is not None @@ -22,8 +22,8 @@ def main(): cloudlog.exception("failed to parse journalctl output") continue - msg = messaging.new_message('androidLog') - entry = msg.androidLog + msg = messaging.new_message('operatingSystemLog') + entry = msg.operatingSystemLog entry.ts = int(kv.get('__REALTIME_TIMESTAMP', 0)) entry.message = json.dumps(kv) if '_PID' in kv: @@ -33,7 +33,7 @@ def main(): if 'SYSLOG_IDENTIFIER' in kv: entry.tag = kv['SYSLOG_IDENTIFIER'] - pm.send('androidLog', msg) + pm.send('operatingSystemLog', msg) finally: proc.terminate() proc.wait() diff --git a/system/loggerd/.gitignore b/openpilot/system/loggerd/.gitignore similarity index 100% rename from system/loggerd/.gitignore rename to openpilot/system/loggerd/.gitignore diff --git a/system/loggerd/SConscript b/openpilot/system/loggerd/SConscript similarity index 65% rename from system/loggerd/SConscript rename to openpilot/system/loggerd/SConscript index a638704dca..7f6d4faf0c 100644 --- a/system/loggerd/SConscript +++ b/openpilot/system/loggerd/SConscript @@ -1,8 +1,6 @@ -Import('env', 'arch', 'messaging', 'common', 'visionipc') +Import('env', 'arch', 'messaging', 'common', 'visionipc', 'ffmpeg_libs') -libs = [common, messaging, visionipc, - 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', - 'pthread', 'z', 'm', 'zstd'] +libs = [common, messaging, visionipc] + ffmpeg_libs + ['pthread', 'm', 'zstd'] frameworks = [] src = ['logger.cc', 'zstd_writer.cc', 'video_writer.cc', 'encoder/encoder.cc', 'encoder/jpeg_encoder.cc'] @@ -10,18 +8,14 @@ if arch == "larch64": src += ['encoder/v4l_encoder.cc'] else: src += ['encoder/ffmpeg_encoder.cc'] - libs += ['yuv'] if arch == "Darwin": frameworks += ['VideoToolbox', 'CoreMedia', 'CoreFoundation', 'CoreVideo'] -if arch != "Darwin": - libs += ['va', 'va-drm', 'drm'] - logger_lib = env.Library('logger', src) libs.insert(0, logger_lib) env.Program('loggerd', ['loggerd.cc'], LIBS=libs, FRAMEWORKS=frameworks) -env.Program('encoderd', ['encoderd.cc'], LIBS=libs + ["jpeg"], FRAMEWORKS=frameworks) +env.Program('encoderd', ['encoderd.cc'], LIBS=libs, FRAMEWORKS=frameworks) env.Program('bootlog.cc', LIBS=libs, FRAMEWORKS=frameworks) if GetOption('extras'): diff --git a/system/hardware/tests/__init__.py b/openpilot/system/loggerd/__init__.py similarity index 100% rename from system/hardware/tests/__init__.py rename to openpilot/system/loggerd/__init__.py diff --git a/system/loggerd/bootlog.cc b/openpilot/system/loggerd/bootlog.cc similarity index 92% rename from system/loggerd/bootlog.cc rename to openpilot/system/loggerd/bootlog.cc index 1b87ce394f..b2e3abfcf1 100644 --- a/system/loggerd/bootlog.cc +++ b/openpilot/system/loggerd/bootlog.cc @@ -1,7 +1,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/params.h" #include "common/swaglog.h" #include "system/loggerd/logger.h" @@ -28,7 +28,7 @@ static kj::Array build_boot_log() { // Gather output of commands std::vector bootlog_commands = { - "[ -x \"$(command -v journalctl)\" ] && journalctl -o short-monotonic", + "[ -x \"$(command -v journalctl)\" ] && journalctl -b -n 2000 -o short-monotonic --no-pager", }; diff --git a/system/loggerd/config.py b/openpilot/system/loggerd/config.py similarity index 100% rename from system/loggerd/config.py rename to openpilot/system/loggerd/config.py diff --git a/system/loggerd/deleter.py b/openpilot/system/loggerd/deleter.py similarity index 100% rename from system/loggerd/deleter.py rename to openpilot/system/loggerd/deleter.py diff --git a/system/loggerd/encoder/encoder.cc b/openpilot/system/loggerd/encoder/encoder.cc similarity index 100% rename from system/loggerd/encoder/encoder.cc rename to openpilot/system/loggerd/encoder/encoder.cc diff --git a/system/loggerd/encoder/encoder.h b/openpilot/system/loggerd/encoder/encoder.h similarity index 95% rename from system/loggerd/encoder/encoder.h rename to openpilot/system/loggerd/encoder/encoder.h index 696cb86737..d333351cb4 100644 --- a/system/loggerd/encoder/encoder.h +++ b/openpilot/system/loggerd/encoder/encoder.h @@ -14,7 +14,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionipc.h" #include "common/queue.h" #include "system/loggerd/loggerd.h" diff --git a/system/loggerd/encoder/ffmpeg_encoder.cc b/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc similarity index 86% rename from system/loggerd/encoder/ffmpeg_encoder.cc rename to openpilot/system/loggerd/encoder/ffmpeg_encoder.cc index 40f3bdee42..451445e5a0 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.cc +++ b/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc @@ -9,8 +9,6 @@ #define __STDC_CONSTANT_MACROS -#include "libyuv.h" - extern "C" { #include #include @@ -19,6 +17,7 @@ extern "C" { #include "common/swaglog.h" #include "common/util.h" +#include "common/yuv.h" const int env_debug_encoder = (getenv("DEBUG_ENCODER") != NULL) ? atoi(getenv("DEBUG_ENCODER")) : 0; @@ -87,26 +86,25 @@ int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { uint8_t *cy = convert_buf.data(); uint8_t *cu = cy + in_width * in_height; uint8_t *cv = cu + (in_width / 2) * (in_height / 2); - libyuv::NV12ToI420(buf->y, buf->stride, - buf->uv, buf->stride, - cy, in_width, - cu, in_width/2, - cv, in_width/2, - in_width, in_height); + yuv::nv12_to_i420(buf->y, buf->stride, + buf->uv, buf->stride, + cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height); if (downscale_buf.size() > 0) { uint8_t *out_y = downscale_buf.data(); uint8_t *out_u = out_y + frame->width * frame->height; uint8_t *out_v = out_u + (frame->width / 2) * (frame->height / 2); - libyuv::I420Scale(cy, in_width, - cu, in_width/2, - cv, in_width/2, - in_width, in_height, - out_y, frame->width, - out_u, frame->width/2, - out_v, frame->width/2, - frame->width, frame->height, - libyuv::kFilterNone); + yuv::i420_scale(cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height, + out_y, frame->width, + out_u, frame->width/2, + out_v, frame->width/2, + frame->width, frame->height); frame->data[0] = out_y; frame->data[1] = out_u; frame->data[2] = out_v; diff --git a/system/loggerd/encoder/ffmpeg_encoder.h b/openpilot/system/loggerd/encoder/ffmpeg_encoder.h similarity index 100% rename from system/loggerd/encoder/ffmpeg_encoder.h rename to openpilot/system/loggerd/encoder/ffmpeg_encoder.h diff --git a/openpilot/system/loggerd/encoder/jpeg_encoder.cc b/openpilot/system/loggerd/encoder/jpeg_encoder.cc new file mode 100644 index 0000000000..79f5e1b80f --- /dev/null +++ b/openpilot/system/loggerd/encoder/jpeg_encoder.cc @@ -0,0 +1,115 @@ +#include "system/loggerd/encoder/jpeg_encoder.h" + +#include +#include + +#include "common/swaglog.h" + +// Lower qscale = higher quality / bigger files for MJPEG. +constexpr int MJPEG_QSCALE = 7; + +JpegEncoder::JpegEncoder(const std::string &publish_name, int width, int height) + : publish_name(publish_name), thumbnail_width(width), thumbnail_height(height) { + yuv_buffer.resize((thumbnail_width * thumbnail_height * 3) / 2); + pm = std::make_unique(std::vector{publish_name.c_str()}); + + const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG); + assert(codec); + + codec_ctx = avcodec_alloc_context3(codec); + assert(codec_ctx); + codec_ctx->width = thumbnail_width; + codec_ctx->height = thumbnail_height; + codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; + codec_ctx->time_base = (AVRational){1, 1}; + codec_ctx->color_range = AVCOL_RANGE_JPEG; + codec_ctx->flags |= AV_CODEC_FLAG_QSCALE; + codec_ctx->global_quality = FF_QP2LAMBDA * MJPEG_QSCALE; + + int err = avcodec_open2(codec_ctx, codec, NULL); + assert(err >= 0); + + frame = av_frame_alloc(); + assert(frame); + frame->format = codec_ctx->pix_fmt; + frame->width = thumbnail_width; + frame->height = thumbnail_height; + frame->linesize[0] = thumbnail_width; + frame->linesize[1] = thumbnail_width / 2; + frame->linesize[2] = thumbnail_width / 2; + frame->color_range = AVCOL_RANGE_JPEG; + + pkt = av_packet_alloc(); + assert(pkt); +} + +JpegEncoder::~JpegEncoder() { + av_packet_free(&pkt); + av_frame_free(&frame); + avcodec_free_context(&codec_ctx); +} + +void JpegEncoder::pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra) { + generateThumbnail(buf->y, buf->uv, buf->width, buf->height, buf->stride); + + MessageBuilder msg; + auto thumbnaild = msg.initEvent().initThumbnail(); + thumbnaild.setFrameId(extra.frame_id); + thumbnaild.setTimestampEof(extra.timestamp_eof); + thumbnaild.setThumbnail({out_buffer.data(), out_buffer.size()}); + + pm->send(publish_name.c_str(), msg); +} + +void JpegEncoder::generateThumbnail(const uint8_t *y_addr, const uint8_t *uv_addr, int width, int height, int stride) { + int downscale = width / thumbnail_width; + assert(downscale * thumbnail_height == height); + + uint8_t *y_plane = yuv_buffer.data(); + uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height; + uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4; + { + // subsampled conversion from nv12 to yuv420p + for (int hy = 0; hy < thumbnail_height / 2; hy++) { + for (int hx = 0; hx < thumbnail_width / 2; hx++) { + int ix = hx * downscale + (downscale - 1) / 2; + int iy = hy * downscale + (downscale - 1) / 2; + y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 0]; + y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 1]; + y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 0]; + y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 1]; + u_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 0]; + v_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 1]; + } + } + } + + compressToJpeg(y_plane, u_plane, v_plane); +} + +void JpegEncoder::compressToJpeg(uint8_t *y_plane, uint8_t *u_plane, uint8_t *v_plane) { + frame->data[0] = y_plane; + frame->data[1] = u_plane; + frame->data[2] = v_plane; + // Required for MJPEG qscale to take effect (global_quality alone is not enough). + frame->quality = FF_QP2LAMBDA * MJPEG_QSCALE; + frame->pts = 0; + + int err = avcodec_send_frame(codec_ctx, frame); + if (err < 0) { + LOGE("thumbnail avcodec_send_frame error %d", err); + out_buffer.clear(); + return; + } + + av_packet_unref(pkt); + err = avcodec_receive_packet(codec_ctx, pkt); + if (err < 0) { + LOGE("thumbnail avcodec_receive_packet error %d", err); + out_buffer.clear(); + return; + } + + out_buffer.assign(pkt->data, pkt->data + pkt->size); + av_packet_unref(pkt); +} diff --git a/system/loggerd/encoder/jpeg_encoder.h b/openpilot/system/loggerd/encoder/jpeg_encoder.h similarity index 63% rename from system/loggerd/encoder/jpeg_encoder.h rename to openpilot/system/loggerd/encoder/jpeg_encoder.h index af1427c19a..10cec52657 100644 --- a/system/loggerd/encoder/jpeg_encoder.h +++ b/openpilot/system/loggerd/encoder/jpeg_encoder.h @@ -1,18 +1,20 @@ #pragma once -#include -#include -#include #include -#include -#include #include -#include "cereal/messaging/messaging.h" +#include +#include + +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionbuf.h" +extern "C" { +#include +} + class JpegEncoder { public: - JpegEncoder(const std::string &pusblish_name, int width, int height); + JpegEncoder(const std::string &publish_name, int width, int height); ~JpegEncoder(); void pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra); @@ -24,9 +26,10 @@ private: int thumbnail_height; std::string publish_name; std::vector yuv_buffer; + std::vector out_buffer; std::unique_ptr pm; - // JPEG output buffer - unsigned char* out_buffer = nullptr; - unsigned long out_size = 0; + AVCodecContext *codec_ctx = nullptr; + AVFrame *frame = nullptr; + AVPacket *pkt = nullptr; }; diff --git a/system/loggerd/encoder/v4l_encoder.cc b/openpilot/system/loggerd/encoder/v4l_encoder.cc similarity index 100% rename from system/loggerd/encoder/v4l_encoder.cc rename to openpilot/system/loggerd/encoder/v4l_encoder.cc diff --git a/system/loggerd/encoder/v4l_encoder.h b/openpilot/system/loggerd/encoder/v4l_encoder.h similarity index 100% rename from system/loggerd/encoder/v4l_encoder.h rename to openpilot/system/loggerd/encoder/v4l_encoder.h diff --git a/system/loggerd/encoderd.cc b/openpilot/system/loggerd/encoderd.cc similarity index 100% rename from system/loggerd/encoderd.cc rename to openpilot/system/loggerd/encoderd.cc diff --git a/system/loggerd/logger.cc b/openpilot/system/loggerd/logger.cc similarity index 100% rename from system/loggerd/logger.cc rename to openpilot/system/loggerd/logger.cc diff --git a/system/loggerd/logger.h b/openpilot/system/loggerd/logger.h similarity index 95% rename from system/loggerd/logger.h rename to openpilot/system/loggerd/logger.h index dba7c2f44c..419becfe5d 100644 --- a/system/loggerd/logger.h +++ b/openpilot/system/loggerd/logger.h @@ -4,7 +4,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/util.h" #include "common/hardware/hw.h" #include "system/loggerd/zstd_writer.h" diff --git a/system/loggerd/loggerd.cc b/openpilot/system/loggerd/loggerd.cc similarity index 100% rename from system/loggerd/loggerd.cc rename to openpilot/system/loggerd/loggerd.cc diff --git a/system/loggerd/loggerd.h b/openpilot/system/loggerd/loggerd.h similarity index 98% rename from system/loggerd/loggerd.h rename to openpilot/system/loggerd/loggerd.h index 7877e9dbb8..110dbe4fd2 100644 --- a/system/loggerd/loggerd.h +++ b/openpilot/system/loggerd/loggerd.h @@ -3,8 +3,8 @@ #include #include -#include "cereal/messaging/messaging.h" -#include "cereal/services.h" +#include "openpilot/cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" #include "msgq/visionipc/visionipc_client.h" #include "common/hardware/hw.h" #include "common/params.h" diff --git a/system/loggerd/__init__.py b/openpilot/system/loggerd/tests/__init__.py similarity index 100% rename from system/loggerd/__init__.py rename to openpilot/system/loggerd/tests/__init__.py diff --git a/system/loggerd/tests/loggerd_tests_common.py b/openpilot/system/loggerd/tests/loggerd_tests_common.py similarity index 100% rename from system/loggerd/tests/loggerd_tests_common.py rename to openpilot/system/loggerd/tests/loggerd_tests_common.py diff --git a/system/loggerd/tests/test_deleter.py b/openpilot/system/loggerd/tests/test_deleter.py similarity index 100% rename from system/loggerd/tests/test_deleter.py rename to openpilot/system/loggerd/tests/test_deleter.py diff --git a/system/loggerd/tests/test_encoder.py b/openpilot/system/loggerd/tests/test_encoder.py similarity index 93% rename from system/loggerd/tests/test_encoder.py rename to openpilot/system/loggerd/tests/test_encoder.py index 416c158ed3..05bc211cbe 100644 --- a/system/loggerd/tests/test_encoder.py +++ b/openpilot/system/loggerd/tests/test_encoder.py @@ -1,13 +1,11 @@ import math import os import pytest -import random import shutil import subprocess import time from pathlib import Path -from openpilot.common.parameterized import parameterized from tqdm import trange from openpilot.common.params import Params @@ -51,9 +49,8 @@ class TestEncoder: return os.path.join(Paths.log_root(), last_route) # TODO: this should run faster than real time - @parameterized.expand([(True, ), (False, )]) - def test_log_rotation(self, record_front): - Params().put_bool("RecordFront", record_front, block=True) + def test_log_rotation(self): + Params().put_bool("RecordFront", True, block=True) managed_processes['sensord'].start() managed_processes['loggerd'].start() @@ -62,7 +59,7 @@ class TestEncoder: time.sleep(1.0) managed_processes['camerad'].start() - num_segments = int(os.getenv("SEGMENTS", random.randint(2, 8))) + num_segments = 3 # wait for loggerd to make the dir for first segment route_prefix_path = None @@ -78,9 +75,6 @@ class TestEncoder: counts = [] first_frames = [] for camera, fps, size_lambda, encode_idx_name in CAMERAS: - if not record_front and "dcamera" in camera: - continue - file_path = f"{route_prefix_path}--{i}/{camera}" # check file exists diff --git a/system/loggerd/tests/test_logger.cc b/openpilot/system/loggerd/tests/test_logger.cc similarity index 100% rename from system/loggerd/tests/test_logger.cc rename to openpilot/system/loggerd/tests/test_logger.cc diff --git a/system/loggerd/tests/test_loggerd.py b/openpilot/system/loggerd/tests/test_loggerd.py similarity index 98% rename from system/loggerd/tests/test_loggerd.py rename to openpilot/system/loggerd/tests/test_loggerd.py index 882de583b4..5d8f635d96 100644 --- a/system/loggerd/tests/test_loggerd.py +++ b/openpilot/system/loggerd/tests/test_loggerd.py @@ -9,9 +9,9 @@ from collections import defaultdict from pathlib import Path import pytest -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.timeout import Timeout @@ -20,7 +20,7 @@ from openpilot.common.hardware import TICI from openpilot.system.loggerd.xattr_cache import getxattr from openpilot.system.loggerd.deleter import PRESERVE_ATTR_NAME, PRESERVE_ATTR_VALUE from openpilot.system.manager.process_config import managed_processes -from openpilot.system.version import get_version +from openpilot.common.version import get_version from openpilot.tools.lib.helpers import RE from openpilot.tools.lib.logreader import LogReader from msgq.visionipc import VisionIpcServer, VisionStreamType @@ -54,7 +54,7 @@ class TestLoggerd: def _gen_bootlog(self): with Timeout(5): - out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), encoding='utf-8') + out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "openpilot/system/loggerd"), encoding='utf-8') log_fn = self._get_log_fn(out) diff --git a/system/loggerd/tests/test_runner.cc b/openpilot/system/loggerd/tests/test_runner.cc similarity index 100% rename from system/loggerd/tests/test_runner.cc rename to openpilot/system/loggerd/tests/test_runner.cc diff --git a/system/loggerd/tests/test_uploader.py b/openpilot/system/loggerd/tests/test_uploader.py similarity index 100% rename from system/loggerd/tests/test_uploader.py rename to openpilot/system/loggerd/tests/test_uploader.py diff --git a/system/loggerd/tests/test_zstd_writer.cc b/openpilot/system/loggerd/tests/test_zstd_writer.cc similarity index 100% rename from system/loggerd/tests/test_zstd_writer.cc rename to openpilot/system/loggerd/tests/test_zstd_writer.cc diff --git a/system/loggerd/tests/vidc_debug.sh b/openpilot/system/loggerd/tests/vidc_debug.sh similarity index 100% rename from system/loggerd/tests/vidc_debug.sh rename to openpilot/system/loggerd/tests/vidc_debug.sh diff --git a/system/loggerd/uploader.py b/openpilot/system/loggerd/uploader.py similarity index 99% rename from system/loggerd/uploader.py rename to openpilot/system/loggerd/uploader.py index 809a302b6f..e36b12ed6a 100755 --- a/system/loggerd/uploader.py +++ b/openpilot/system/loggerd/uploader.py @@ -9,8 +9,8 @@ import traceback import datetime from collections.abc import Iterator -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.api import Api from openpilot.common.utils import get_upload_stream from openpilot.common.params import Params diff --git a/system/loggerd/video_writer.cc b/openpilot/system/loggerd/video_writer.cc similarity index 100% rename from system/loggerd/video_writer.cc rename to openpilot/system/loggerd/video_writer.cc diff --git a/system/loggerd/video_writer.h b/openpilot/system/loggerd/video_writer.h similarity index 95% rename from system/loggerd/video_writer.h rename to openpilot/system/loggerd/video_writer.h index e973c5d811..fdec606058 100644 --- a/system/loggerd/video_writer.h +++ b/openpilot/system/loggerd/video_writer.h @@ -8,7 +8,7 @@ extern "C" { #include } -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" class VideoWriter { public: diff --git a/system/loggerd/xattr_cache.py b/openpilot/system/loggerd/xattr_cache.py similarity index 100% rename from system/loggerd/xattr_cache.py rename to openpilot/system/loggerd/xattr_cache.py diff --git a/system/loggerd/zstd_writer.cc b/openpilot/system/loggerd/zstd_writer.cc similarity index 100% rename from system/loggerd/zstd_writer.cc rename to openpilot/system/loggerd/zstd_writer.cc diff --git a/system/loggerd/zstd_writer.h b/openpilot/system/loggerd/zstd_writer.h similarity index 100% rename from system/loggerd/zstd_writer.h rename to openpilot/system/loggerd/zstd_writer.h diff --git a/system/logmessaged.py b/openpilot/system/logmessaged.py similarity index 96% rename from system/logmessaged.py rename to openpilot/system/logmessaged.py index a64a849b02..937a0741d0 100755 --- a/system/logmessaged.py +++ b/openpilot/system/logmessaged.py @@ -2,7 +2,7 @@ import zmq from typing import NoReturn -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.logging_extra import SwagLogFileFormatter from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import get_file_handler diff --git a/system/loggerd/tests/__init__.py b/openpilot/system/manager/__init__.py similarity index 100% rename from system/loggerd/tests/__init__.py rename to openpilot/system/manager/__init__.py diff --git a/system/manager/build.py b/openpilot/system/manager/build.py similarity index 100% rename from system/manager/build.py rename to openpilot/system/manager/build.py diff --git a/system/manager/github_runner.sh b/openpilot/system/manager/github_runner.sh similarity index 100% rename from system/manager/github_runner.sh rename to openpilot/system/manager/github_runner.sh diff --git a/system/manager/helpers.py b/openpilot/system/manager/helpers.py similarity index 87% rename from system/manager/helpers.py rename to openpilot/system/manager/helpers.py index 6af4a799e4..453e13184d 100644 --- a/system/manager/helpers.py +++ b/openpilot/system/manager/helpers.py @@ -44,12 +44,6 @@ def unblock_stdout() -> None: exit_status = os.wait()[1] >> 8 os._exit(exit_status) - -def write_onroad_params(started, params): - params.put_bool("IsOnroad", started, block=True) - params.put_bool("IsOffroad", not started, block=True) - - def save_bootlog(): # copy current params tmp = tempfile.mkdtemp() @@ -60,7 +54,7 @@ def save_bootlog(): def fn(tmpdir): env = os.environ.copy() env['PARAMS_COPY_PATH'] = tmpdir - subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), env=env) + subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "openpilot/system/loggerd"), env=env) shutil.rmtree(tmpdir) t = threading.Thread(target=fn, args=(tmp, )) t.daemon = True diff --git a/system/manager/manager.py b/openpilot/system/manager/manager.py similarity index 95% rename from system/manager/manager.py rename to openpilot/system/manager/manager.py index f2ff5c282a..88cb7f6b14 100755 --- a/system/manager/manager.py +++ b/openpilot/system/manager/manager.py @@ -6,19 +6,19 @@ import sys import time import traceback -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.utils import atomic_write from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.text_window import TextWindow from openpilot.common.hardware import HARDWARE, PC -from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog +from openpilot.system.manager.helpers import unblock_stdout, save_bootlog from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID from openpilot.common.swaglog import cloudlog, add_file_handler -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths from openpilot.sunnypilot.system.params_migration import run_migration @@ -138,7 +138,7 @@ def manager_thread() -> None: sm = messaging.SubMaster(['deviceState', 'carParams', 'pandaStates'], poll='deviceState') pm = messaging.PubMaster(['managerState']) - write_onroad_params(False, params) + params.put_bool("IsOffroad", True, block=True) ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) started_prev = False @@ -158,9 +158,9 @@ def manager_thread() -> None: if ignition and not ignition_prev: params.clear_all(ParamKeyFlag.CLEAR_ON_IGNITION_ON) - # update onroad params, which drives pandad's safety setter thread + # update offroad state for services that don't subscribe to deviceState if started != started_prev: - write_onroad_params(started, params) + params.put_bool("IsOffroad", not started, block=True) started_prev = started ignition_prev = ignition diff --git a/system/manager/process.py b/openpilot/system/manager/process.py similarity index 98% rename from system/manager/process.py rename to openpilot/system/manager/process.py index cdb316e1a1..a0b878d0f2 100644 --- a/system/manager/process.py +++ b/openpilot/system/manager/process.py @@ -9,8 +9,9 @@ from multiprocessing import Process from setproctitle import setproctitle -from cereal import car, log -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params diff --git a/openpilot/system/manager/process_config.py b/openpilot/system/manager/process_config.py new file mode 100644 index 0000000000..a72675385d --- /dev/null +++ b/openpilot/system/manager/process_config.py @@ -0,0 +1,211 @@ +import os +import operator +import platform + +from opendbc.car.structs import car +from openpilot.cereal import custom +from openpilot.common.params import Params +from openpilot.common.hardware import PC, TICI +from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess +from openpilot.common.hardware.hw import Paths + +from openpilot.sunnypilot.mapd.mapd_manager import MAPD_PATH + +from openpilot.sunnypilot.models.helpers import get_active_model_runner +from openpilot.sunnypilot.sunnylink.utils import sunnylink_need_register, sunnylink_ready, use_sunnylink_uploader + +WEBCAM = os.getenv("USE_WEBCAM") is not None + +def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: + return started or params.get_bool("IsDriverViewEnabled") + +def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and CP.notCar + +def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and not CP.notCar + +def logging(started: bool, params: Params, CP: car.CarParams) -> bool: + run = (not CP.notCar) or not params.get_bool("DisableLogging") + return started and run + +def ublox_available() -> bool: + return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') + +def ublox(started: bool, params: Params, CP: car.CarParams) -> bool: + use_ublox = ublox_available() + if use_ublox != params.get_bool("UbloxAvailable"): + params.put_bool("UbloxAvailable", use_ublox, block=True) + return started and use_ublox + +def joystick(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and params.get_bool("JoystickDebugMode") + +def not_joystick(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and not params.get_bool("JoystickDebugMode") + +def long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and params.get_bool("LongitudinalManeuverMode") + +def lat_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and params.get_bool("LateralManeuverMode") + +def not_long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and not params.get_bool("LongitudinalManeuverMode") + +def qcomgps(started: bool, params: Params, CP: car.CarParams) -> bool: + return started and not ublox_available() + +def always_run(started: bool, params: Params, CP: car.CarParams) -> bool: + return True + +def only_onroad(started: bool, params: Params, CP: car.CarParams) -> bool: + return started + +def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: + return not started + +def livestream(started: bool, params: Params, CP: car.CarParams) -> bool: + return params.get_bool("IsLiveStreaming") + +def use_github_runner(started, params, CP: car.CarParams) -> bool: + return not PC and params.get_bool("EnableGithubRunner") and ( + not params.get_bool("NetworkMetered") and not params.get_bool("GithubRunnerSufficientVoltage")) + +def use_copyparty(started, params, CP: car.CarParams) -> bool: + return bool(params.get_bool("EnableCopyparty")) + +def sunnylink_ready_shim(started, params, CP: car.CarParams) -> bool: + """Shim for sunnylink_ready to match the process manager signature.""" + return sunnylink_ready(params) + +def sunnylink_need_register_shim(started, params, CP: car.CarParams) -> bool: + """Shim for sunnylink_need_register to match the process manager signature.""" + return sunnylink_need_register(params) + +def use_sunnylink_uploader_shim(started, params, CP: car.CarParams) -> bool: + """Shim for use_sunnylink_uploader to match the process manager signature.""" + return use_sunnylink_uploader(params) + +def is_tinygrad_model(started, params, CP: car.CarParams) -> bool: + """Check if the active model runner is SNPE.""" + return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.tinygrad) + +def is_stock_model(started, params, CP: car.CarParams) -> bool: + """Check if the active model runner is stock.""" + return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.stock) + +def mapd_ready(started: bool, params: Params, CP: car.CarParams) -> bool: + return bool(os.path.exists(Paths.mapd_root())) + +def uploader_ready(started: bool, params: Params, CP: car.CarParams) -> bool: + if not params.get_bool("OnroadUploads"): + return only_offroad(started, params, CP) + + return always_run(started, params, CP) + +def or_(*fns): + return lambda *args: operator.or_(*(fn(*args) for fn in fns)) + +def and_(*fns): + return lambda *args: operator.and_(*(fn(*args) for fn in fns)) + +def not_(*fns): + return lambda *args: operator.not_(*(fn(*args) for fn in fns)) + +procs = [ + DaemonProcess("manage_athenad", "openpilot.system.athena.manage_athenad", "AthenadPid"), + + NativeProcess("loggerd", "openpilot/system/loggerd", ["./loggerd"], logging), + NativeProcess("encoderd", "openpilot/system/loggerd", ["./encoderd"], only_onroad), + NativeProcess("stream_encoderd", "openpilot/system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), + PythonProcess("logmessaged", "openpilot.system.logmessaged", always_run), + + NativeProcess("camerad", "openpilot/system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), + PythonProcess("webcamerad", "openpilot.system.camerad.webcam.camerad", driverview, enabled=WEBCAM), + PythonProcess("proclogd", "openpilot.system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), + PythonProcess("journald", "openpilot.system.journald", only_onroad, platform.system() != "Darwin"), + PythonProcess("micd", "openpilot.system.micd", iscar), + PythonProcess("timed", "openpilot.system.timed", always_run, enabled=not PC), + + PythonProcess("modeld", "openpilot.selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)), + PythonProcess("dmonitoringmodeld", "openpilot.selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), + + PythonProcess("sensord", "openpilot.system.sensord.sensord", only_onroad, enabled=not PC), + PythonProcess("ui", "openpilot.selfdrive.ui.ui", always_run, restart_if_crash=True), + PythonProcess("soundd", "openpilot.selfdrive.ui.soundd", driverview), + PythonProcess("locationd", "openpilot.selfdrive.locationd.locationd", only_onroad), + NativeProcess("_pandad", "openpilot/selfdrive/pandad", ["./pandad"], always_run, enabled=False), + PythonProcess("calibrationd", "openpilot.selfdrive.locationd.calibrationd", only_onroad), + PythonProcess("torqued", "openpilot.selfdrive.locationd.torqued", only_onroad), + PythonProcess("controlsd", "openpilot.selfdrive.controls.controlsd", and_(not_joystick, iscar)), + PythonProcess("joystickd", "openpilot.tools.joystick.joystickd", or_(joystick, notcar)), + PythonProcess("selfdrived", "openpilot.selfdrive.selfdrived.selfdrived", only_onroad), + PythonProcess("card", "openpilot.selfdrive.car.card", only_onroad), + PythonProcess("deleter", "openpilot.system.loggerd.deleter", always_run), + PythonProcess("dmonitoringd", "openpilot.selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), + PythonProcess("qcomgpsd", "openpilot.system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), + PythonProcess("pandad", "openpilot.selfdrive.pandad.pandad", always_run), + PythonProcess("paramsd", "openpilot.selfdrive.locationd.paramsd", only_onroad), + PythonProcess("lagd", "openpilot.selfdrive.locationd.lagd", only_onroad), + PythonProcess("ubloxd", "openpilot.system.ubloxd.ubloxd", ublox, enabled=TICI), + PythonProcess("pigeond", "openpilot.system.ubloxd.pigeond", ublox, enabled=TICI), + PythonProcess("plannerd", "openpilot.selfdrive.controls.plannerd", not_long_maneuver), + PythonProcess("maneuversd", "openpilot.tools.longitudinal_maneuvers.maneuversd", long_maneuver), + PythonProcess("lateral_maneuversd", "openpilot.tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), + PythonProcess("radard", "openpilot.selfdrive.controls.radard", only_onroad), + PythonProcess("hardwared", "openpilot.system.hardware.hardwared", always_run), + PythonProcess("modem", "openpilot.common.hardware.tici.modem", always_run, enabled=TICI), + PythonProcess("tombstoned", "openpilot.system.tombstoned", always_run, enabled=not PC), + PythonProcess("updated", "openpilot.system.updated.updated", only_offroad, enabled=not PC), + PythonProcess("uploader", "openpilot.system.loggerd.uploader", uploader_ready), + PythonProcess("statsd", "openpilot.sunnypilot.system.statsd", always_run), + PythonProcess("feedbackd", "openpilot.selfdrive.ui.feedback.feedbackd", only_onroad), + + # debug procs + NativeProcess("bridge", "openpilot/cereal/messaging", ["./bridge"], notcar), + PythonProcess("webrtcd", "openpilot.system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), + PythonProcess("joystick", "openpilot.tools.joystick.joystick_control", and_(joystick, iscar)), + + # sunnylink <3 + DaemonProcess("manage_sunnylinkd", "openpilot.sunnypilot.sunnylink.athena.manage_sunnylinkd", "SunnylinkdPid"), + PythonProcess("sunnylink_registration_manager", "openpilot.sunnypilot.sunnylink.registration_manager", sunnylink_need_register_shim), + PythonProcess("statsd_sp", "openpilot.sunnypilot.sunnylink.statsd", and_(always_run, sunnylink_ready_shim)), +] + +# sunnypilot +procs += [ + # Models + PythonProcess("models_manager", "openpilot.sunnypilot.models.manager", only_offroad), + NativeProcess("modeld_tinygrad", "openpilot/sunnypilot/modeld_v2", ["./modeld"], and_(only_onroad, is_tinygrad_model)), + + # Backup + PythonProcess("backup_manager", "openpilot.sunnypilot.sunnylink.backups.manager", and_(only_offroad, sunnylink_ready_shim)), + + # mapd + NativeProcess("mapd", Paths.mapd_root(), ["bash", "-c", f"{MAPD_PATH} > /dev/null 2>&1"], mapd_ready), + PythonProcess("mapd_manager", "openpilot.sunnypilot.mapd.mapd_manager", always_run), + + # locationd + NativeProcess("locationd_llk", "openpilot/sunnypilot/selfdrive/locationd", ["./locationd"], only_onroad), +] + +if os.path.exists("./github_runner.sh"): + procs += [NativeProcess("github_runner_start", "openpilot/system/manager", + ["./github_runner.sh", "start"], and_(only_offroad, use_github_runner), sigkill=False)] + +if os.path.exists("../../sunnypilot/sunnylink/uploader.py"): + procs += [PythonProcess("sunnylink_uploader", "openpilot.sunnypilot.sunnylink.uploader", use_sunnylink_uploader_shim)] + +if os.path.exists("../../third_party/copyparty/copyparty-sfx.py"): + sunnypilot_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + copyparty_args = [f"-v{Paths.crash_log_root()}:/swaglogs:r"] + copyparty_args += [f"-v{Paths.log_root()}:/routes:r"] + copyparty_args += [f"-v{Paths.model_root()}:/models:rw"] + copyparty_args += [f"-v{sunnypilot_root}:/sunnypilot:rw"] + copyparty_args += ["-p8080"] + copyparty_args += ["-z"] + copyparty_args += ["-q"] + procs += [NativeProcess("copyparty-sfx", "openpilot/third_party/copyparty", ["./copyparty-sfx.py", *copyparty_args], and_(only_offroad, use_copyparty))] + +managed_processes = {p.name: p for p in procs} diff --git a/system/manager/__init__.py b/openpilot/system/manager/test/__init__.py similarity index 100% rename from system/manager/__init__.py rename to openpilot/system/manager/test/__init__.py diff --git a/system/manager/test/test_manager.py b/openpilot/system/manager/test/test_manager.py similarity index 95% rename from system/manager/test/test_manager.py rename to openpilot/system/manager/test/test_manager.py index 73c66ff3fc..a3808bf29f 100644 --- a/system/manager/test/test_manager.py +++ b/openpilot/system/manager/test/test_manager.py @@ -3,7 +3,7 @@ import pytest import signal import time -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params import openpilot.system.manager.manager as manager from openpilot.system.manager.process import ensure_running @@ -27,10 +27,6 @@ class TestManager: def teardown_method(self): manager.manager_cleanup() - def test_manager_prepare(self): - os.environ['PREPAREONLY'] = '1' - manager.main() - def test_duplicate_procs(self): assert len(procs) == len(managed_processes), "Duplicate process names" diff --git a/system/micd.py b/openpilot/system/micd.py similarity index 99% rename from system/micd.py rename to openpilot/system/micd.py index 9b3ccc8d29..a3a93c8c1a 100755 --- a/system/micd.py +++ b/openpilot/system/micd.py @@ -3,7 +3,7 @@ import numpy as np from functools import cache import threading -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import Ratekeeper from openpilot.common.utils import retry from openpilot.common.swaglog import cloudlog diff --git a/system/proclogd.py b/openpilot/system/proclogd.py similarity index 99% rename from system/proclogd.py rename to openpilot/system/proclogd.py index b008f8ed9b..9979b3a401 100755 --- a/system/proclogd.py +++ b/openpilot/system/proclogd.py @@ -2,7 +2,7 @@ import os from typing import NoReturn, TypedDict -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog diff --git a/system/qcomgpsd/modemdiag.py b/openpilot/system/qcomgpsd/modemdiag.py similarity index 80% rename from system/qcomgpsd/modemdiag.py rename to openpilot/system/qcomgpsd/modemdiag.py index 5d72aeba9e..313563a314 100644 --- a/system/qcomgpsd/modemdiag.py +++ b/openpilot/system/qcomgpsd/modemdiag.py @@ -1,8 +1,31 @@ import select -from serial import Serial -from crcmod import mkCrcFun from struct import pack, unpack_from, calcsize +from openpilot.common.serial import Serial + + +def _gen_crc16_reflected_table(poly: int) -> list[int]: + # poly is the reflected form (e.g. 0x8408 for CRC-16 poly 0x1021) + table = [] + for i in range(256): + crc = i + for _ in range(8): + if crc & 1: + crc = (crc >> 1) ^ poly + else: + crc >>= 1 + table.append(crc) + return table + +# CRC-16/IBM-SDLC (aka X-25 / ISO-HDLC): poly 0x1021, refin/refout, init/xor 0xFFFF +_CRC16_X25_TABLE = _gen_crc16_reflected_table(0x8408) + +def crc16_x25(data: bytes) -> int: + crc = 0xFFFF + for b in data: + crc = _CRC16_X25_TABLE[(crc ^ b) & 0xFF] ^ (crc >> 8) + return crc ^ 0xFFFF + class ModemDiag: def __init__(self): self.serial = self.open_serial() @@ -15,12 +38,11 @@ class ModemDiag: serial.reset_output_buffer() return serial - ccitt_crc16 = mkCrcFun(0x11021, initCrc=0, xorOut=0xffff) ESCAPE_CHAR = b'\x7d' TRAILER_CHAR = b'\x7e' def hdlc_encapsulate(self, payload): - payload += pack('/crash/") @@ -104,7 +104,7 @@ def report_tombstone_apport(fn): # Try to find first entry in openpilot, fall back to first line for line in stacktrace_s: - if "at selfdrive/" in line: + if "at openpilot/selfdrive/" in line or "at selfdrive/" in line: crash_function = line found = True break diff --git a/system/ubloxd/binary_struct.py b/openpilot/system/ubloxd/binary_struct.py similarity index 100% rename from system/ubloxd/binary_struct.py rename to openpilot/system/ubloxd/binary_struct.py diff --git a/system/ubloxd/glonass.py b/openpilot/system/ubloxd/glonass.py similarity index 100% rename from system/ubloxd/glonass.py rename to openpilot/system/ubloxd/glonass.py diff --git a/system/ubloxd/gps.py b/openpilot/system/ubloxd/gps.py similarity index 100% rename from system/ubloxd/gps.py rename to openpilot/system/ubloxd/gps.py diff --git a/system/ubloxd/pigeond.py b/openpilot/system/ubloxd/pigeond.py similarity index 98% rename from system/ubloxd/pigeond.py rename to openpilot/system/ubloxd/pigeond.py index fe2634e333..9891285465 100755 --- a/system/ubloxd/pigeond.py +++ b/openpilot/system/ubloxd/pigeond.py @@ -2,15 +2,15 @@ import sys import time import signal -import serial import struct import requests import urllib.parse from datetime import datetime, UTC -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.time_helpers import system_time_valid from openpilot.common.params import Params +from openpilot.common.serial import Serial from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import TICI from openpilot.common.gpio import gpio_init, gpio_set @@ -64,7 +64,7 @@ def get_assistnow_messages(token: str) -> list[bytes]: class TTYPigeon: def __init__(self): - self.tty = serial.VTIMESerial(UBLOX_TTY, baudrate=9600, timeout=0) + self.tty = Serial(UBLOX_TTY, baudrate=9600, timeout=0) def send(self, dat: bytes) -> None: self.tty.write(dat) diff --git a/system/ubloxd/tests/test_pigeond.py b/openpilot/system/ubloxd/tests/test_pigeond.py similarity index 93% rename from system/ubloxd/tests/test_pigeond.py rename to openpilot/system/ubloxd/tests/test_pigeond.py index fb979a9372..b894ed718b 100644 --- a/system/ubloxd/tests/test_pigeond.py +++ b/openpilot/system/ubloxd/tests/test_pigeond.py @@ -1,8 +1,8 @@ import pytest import time -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.gpio import gpio_read from openpilot.selfdrive.test.helpers import with_processes from openpilot.system.manager.process_config import managed_processes diff --git a/system/ubloxd/ubloxd.py b/openpilot/system/ubloxd/ubloxd.py similarity index 99% rename from system/ubloxd/ubloxd.py rename to openpilot/system/ubloxd/ubloxd.py index 78429a847b..3b32f70657 100755 --- a/system/ubloxd/ubloxd.py +++ b/openpilot/system/ubloxd/ubloxd.py @@ -6,8 +6,8 @@ import numpy as np from collections import defaultdict from dataclasses import dataclass -from cereal import log -from cereal import messaging +from openpilot.cereal import log +from openpilot.cereal import messaging from openpilot.system.ubloxd.ubx import Ubx from openpilot.system.ubloxd.gps import Gps from openpilot.system.ubloxd.glonass import Glonass diff --git a/system/ubloxd/ubx.py b/openpilot/system/ubloxd/ubx.py similarity index 100% rename from system/ubloxd/ubx.py rename to openpilot/system/ubloxd/ubx.py diff --git a/system/ui/README.md b/openpilot/system/ui/README.md similarity index 91% rename from system/ui/README.md rename to openpilot/system/ui/README.md index 54697dada8..7c9713b39e 100644 --- a/system/ui/README.md +++ b/openpilot/system/ui/README.md @@ -16,6 +16,6 @@ Quick start: * https://electronstudio.github.io/raylib-python-cffi/README.html#quickstart Style guide: -* All graphical elements should subclass [`Widget`](/system/ui/widgets/__init__.py). +* All graphical elements should subclass [`Widget`](/openpilot/system/ui/widgets/__init__.py). * Prefer a stateful widget over a function for easy migration from QT * All internal class variables and functions should be prefixed with `_` diff --git a/system/tests/__init__.py b/openpilot/system/ui/lib/__init__.py similarity index 100% rename from system/tests/__init__.py rename to openpilot/system/ui/lib/__init__.py diff --git a/system/ui/lib/application.py b/openpilot/system/ui/lib/application.py similarity index 100% rename from system/ui/lib/application.py rename to openpilot/system/ui/lib/application.py diff --git a/system/ui/lib/egl.py b/openpilot/system/ui/lib/egl.py similarity index 100% rename from system/ui/lib/egl.py rename to openpilot/system/ui/lib/egl.py diff --git a/system/ui/lib/emoji.py b/openpilot/system/ui/lib/emoji.py similarity index 100% rename from system/ui/lib/emoji.py rename to openpilot/system/ui/lib/emoji.py diff --git a/system/ui/lib/multilang.py b/openpilot/system/ui/lib/multilang.py similarity index 98% rename from system/ui/lib/multilang.py rename to openpilot/system/ui/lib/multilang.py index c7d39e4794..8d79ec3eea 100644 --- a/system/ui/lib/multilang.py +++ b/openpilot/system/ui/lib/multilang.py @@ -10,7 +10,7 @@ try: except ImportError: Params = None -SYSTEM_UI_DIR = os.path.join(BASEDIR, "system", "ui") +SYSTEM_UI_DIR = os.path.join(BASEDIR, "openpilot/system", "ui") UI_DIR = files("openpilot.selfdrive.ui") TRANSLATIONS_DIR = UI_DIR.joinpath("translations") LANGUAGES_FILE = TRANSLATIONS_DIR.joinpath("languages.json") diff --git a/system/ui/lib/networkmanager.py b/openpilot/system/ui/lib/networkmanager.py similarity index 100% rename from system/ui/lib/networkmanager.py rename to openpilot/system/ui/lib/networkmanager.py diff --git a/system/ui/lib/scroll_panel.py b/openpilot/system/ui/lib/scroll_panel.py similarity index 100% rename from system/ui/lib/scroll_panel.py rename to openpilot/system/ui/lib/scroll_panel.py diff --git a/system/ui/lib/scroll_panel2.py b/openpilot/system/ui/lib/scroll_panel2.py similarity index 100% rename from system/ui/lib/scroll_panel2.py rename to openpilot/system/ui/lib/scroll_panel2.py diff --git a/system/ui/lib/shader_polygon.py b/openpilot/system/ui/lib/shader_polygon.py similarity index 100% rename from system/ui/lib/shader_polygon.py rename to openpilot/system/ui/lib/shader_polygon.py diff --git a/system/ui/lib/tests/test_handle_state_change.py b/openpilot/system/ui/lib/tests/test_handle_state_change.py similarity index 100% rename from system/ui/lib/tests/test_handle_state_change.py rename to openpilot/system/ui/lib/tests/test_handle_state_change.py diff --git a/system/ui/lib/text_measure.py b/openpilot/system/ui/lib/text_measure.py similarity index 100% rename from system/ui/lib/text_measure.py rename to openpilot/system/ui/lib/text_measure.py diff --git a/system/ui/lib/utils.py b/openpilot/system/ui/lib/utils.py similarity index 100% rename from system/ui/lib/utils.py rename to openpilot/system/ui/lib/utils.py diff --git a/system/ui/lib/wifi_manager.py b/openpilot/system/ui/lib/wifi_manager.py similarity index 100% rename from system/ui/lib/wifi_manager.py rename to openpilot/system/ui/lib/wifi_manager.py diff --git a/system/ui/lib/wrap_text.py b/openpilot/system/ui/lib/wrap_text.py similarity index 100% rename from system/ui/lib/wrap_text.py rename to openpilot/system/ui/lib/wrap_text.py diff --git a/system/ui/mici_reset.py b/openpilot/system/ui/mici_reset.py similarity index 94% rename from system/ui/mici_reset.py rename to openpilot/system/ui/mici_reset.py index 90de7843f9..97ecaf7024 100755 --- a/system/ui/mici_reset.py +++ b/openpilot/system/ui/mici_reset.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import os +import subprocess import sys import time import threading @@ -105,12 +105,12 @@ class Reset(Scroller): return # Removing data and formatting - rm = os.system("sudo rm -rf /data/*") - os.system(f"sudo umount {USERDATA}") - fmt = os.system(f"yes | sudo mkfs.ext4 {USERDATA}") + rm = subprocess.run("sudo rm -rf /data/*", shell=True).returncode + subprocess.run(f"sudo umount {USERDATA}", shell=True) + fmt = subprocess.run(f"yes | sudo mkfs.ext4 {USERDATA}", shell=True).returncode if rm == 0 or fmt == 0: - os.system("sudo reboot") + subprocess.run("sudo reboot", shell=True) else: self._reset_failed = True diff --git a/system/ui/mici_setup.py b/openpilot/system/ui/mici_setup.py similarity index 99% rename from system/ui/mici_setup.py rename to openpilot/system/ui/mici_setup.py index 65506ef3a0..e446697cfe 100755 --- a/system/ui/mici_setup.py +++ b/openpilot/system/ui/mici_setup.py @@ -11,7 +11,7 @@ from collections.abc import Callable import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.common.filter_simple import BounceFilter from openpilot.common.hardware import HARDWARE, TICI from openpilot.common.realtime import config_realtime_process, set_core_affinity diff --git a/system/ui/mici_updater.py b/openpilot/system/ui/mici_updater.py similarity index 100% rename from system/ui/mici_updater.py rename to openpilot/system/ui/mici_updater.py diff --git a/system/ui/reset.py b/openpilot/system/ui/reset.py similarity index 100% rename from system/ui/reset.py rename to openpilot/system/ui/reset.py diff --git a/system/ui/setup.py b/openpilot/system/ui/setup.py similarity index 100% rename from system/ui/setup.py rename to openpilot/system/ui/setup.py diff --git a/system/ui/spinner.py b/openpilot/system/ui/spinner.py similarity index 100% rename from system/ui/spinner.py rename to openpilot/system/ui/spinner.py diff --git a/system/ui/sunnypilot/lib/application.py b/openpilot/system/ui/sunnypilot/lib/application.py similarity index 100% rename from system/ui/sunnypilot/lib/application.py rename to openpilot/system/ui/sunnypilot/lib/application.py diff --git a/system/ui/sunnypilot/lib/styles.py b/openpilot/system/ui/sunnypilot/lib/styles.py similarity index 100% rename from system/ui/sunnypilot/lib/styles.py rename to openpilot/system/ui/sunnypilot/lib/styles.py diff --git a/system/ui/sunnypilot/lib/utils.py b/openpilot/system/ui/sunnypilot/lib/utils.py similarity index 100% rename from system/ui/sunnypilot/lib/utils.py rename to openpilot/system/ui/sunnypilot/lib/utils.py diff --git a/system/ui/sunnypilot/widgets/__init__.py b/openpilot/system/ui/sunnypilot/widgets/__init__.py similarity index 100% rename from system/ui/sunnypilot/widgets/__init__.py rename to openpilot/system/ui/sunnypilot/widgets/__init__.py diff --git a/system/ui/lib/__init__.py b/openpilot/system/ui/sunnypilot/widgets/helpers/__init__.py similarity index 100% rename from system/ui/lib/__init__.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/__init__.py diff --git a/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py b/openpilot/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/fuzzy_search.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py diff --git a/system/ui/sunnypilot/widgets/helpers/star_icon.py b/openpilot/system/ui/sunnypilot/widgets/helpers/star_icon.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/star_icon.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/star_icon.py diff --git a/system/ui/sunnypilot/widgets/html_render.py b/openpilot/system/ui/sunnypilot/widgets/html_render.py similarity index 100% rename from system/ui/sunnypilot/widgets/html_render.py rename to openpilot/system/ui/sunnypilot/widgets/html_render.py diff --git a/system/ui/sunnypilot/widgets/input_dialog.py b/openpilot/system/ui/sunnypilot/widgets/input_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/input_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/input_dialog.py diff --git a/system/ui/sunnypilot/widgets/list_view.py b/openpilot/system/ui/sunnypilot/widgets/list_view.py similarity index 100% rename from system/ui/sunnypilot/widgets/list_view.py rename to openpilot/system/ui/sunnypilot/widgets/list_view.py diff --git a/system/ui/sunnypilot/widgets/option_control.py b/openpilot/system/ui/sunnypilot/widgets/option_control.py similarity index 100% rename from system/ui/sunnypilot/widgets/option_control.py rename to openpilot/system/ui/sunnypilot/widgets/option_control.py diff --git a/system/ui/sunnypilot/widgets/progress_bar.py b/openpilot/system/ui/sunnypilot/widgets/progress_bar.py similarity index 100% rename from system/ui/sunnypilot/widgets/progress_bar.py rename to openpilot/system/ui/sunnypilot/widgets/progress_bar.py diff --git a/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py b/openpilot/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py diff --git a/system/ui/sunnypilot/widgets/toggle.py b/openpilot/system/ui/sunnypilot/widgets/toggle.py similarity index 100% rename from system/ui/sunnypilot/widgets/toggle.py rename to openpilot/system/ui/sunnypilot/widgets/toggle.py diff --git a/system/ui/sunnypilot/widgets/tree_dialog.py b/openpilot/system/ui/sunnypilot/widgets/tree_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/tree_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/tree_dialog.py diff --git a/system/ui/text.py b/openpilot/system/ui/text.py similarity index 100% rename from system/ui/text.py rename to openpilot/system/ui/text.py diff --git a/system/ui/tici_reset.py b/openpilot/system/ui/tici_reset.py similarity index 91% rename from system/ui/tici_reset.py rename to openpilot/system/ui/tici_reset.py index cb5441a406..569faf45fe 100755 --- a/system/ui/tici_reset.py +++ b/openpilot/system/ui/tici_reset.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import os +import subprocess import sys import threading import time @@ -37,19 +37,19 @@ class Reset(Widget): self._reset_state = ResetState.NONE self._cancel_button = Button("Cancel", gui_app.request_close) self._confirm_button = Button("Confirm", self._confirm, button_style=ButtonStyle.PRIMARY) - self._reboot_button = Button("Reboot", lambda: os.system("sudo reboot")) + self._reboot_button = Button("Reboot", lambda: subprocess.run("sudo reboot", shell=True)) def _do_erase(self): if PC: return # Removing data and formatting - rm = os.system("sudo rm -rf /data/*") - os.system(f"sudo umount {USERDATA}") - fmt = os.system(f"yes | sudo mkfs.ext4 {USERDATA}") + rm = subprocess.run("sudo rm -rf /data/*", shell=True).returncode + subprocess.run(f"sudo umount {USERDATA}", shell=True) + fmt = subprocess.run(f"yes | sudo mkfs.ext4 {USERDATA}", shell=True).returncode if rm == 0 or fmt == 0: - os.system("sudo reboot") + subprocess.run("sudo reboot", shell=True) else: self._reset_state = ResetState.FAILED diff --git a/system/ui/tici_setup.py b/openpilot/system/ui/tici_setup.py similarity index 99% rename from system/ui/tici_setup.py rename to openpilot/system/ui/tici_setup.py index 0e0c6fdc7c..2b2c1c39f8 100755 --- a/system/ui/tici_setup.py +++ b/openpilot/system/ui/tici_setup.py @@ -10,7 +10,7 @@ from enum import IntEnum import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.common.hardware import HARDWARE from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE diff --git a/system/ui/tici_updater.py b/openpilot/system/ui/tici_updater.py similarity index 100% rename from system/ui/tici_updater.py rename to openpilot/system/ui/tici_updater.py diff --git a/system/ui/updater.py b/openpilot/system/ui/updater.py similarity index 100% rename from system/ui/updater.py rename to openpilot/system/ui/updater.py diff --git a/system/ui/widgets/__init__.py b/openpilot/system/ui/widgets/__init__.py similarity index 100% rename from system/ui/widgets/__init__.py rename to openpilot/system/ui/widgets/__init__.py diff --git a/system/ui/widgets/button.py b/openpilot/system/ui/widgets/button.py similarity index 100% rename from system/ui/widgets/button.py rename to openpilot/system/ui/widgets/button.py diff --git a/system/ui/widgets/confirm_dialog.py b/openpilot/system/ui/widgets/confirm_dialog.py similarity index 100% rename from system/ui/widgets/confirm_dialog.py rename to openpilot/system/ui/widgets/confirm_dialog.py diff --git a/system/ui/widgets/html_render.py b/openpilot/system/ui/widgets/html_render.py similarity index 100% rename from system/ui/widgets/html_render.py rename to openpilot/system/ui/widgets/html_render.py diff --git a/system/ui/widgets/icon_widget.py b/openpilot/system/ui/widgets/icon_widget.py similarity index 100% rename from system/ui/widgets/icon_widget.py rename to openpilot/system/ui/widgets/icon_widget.py diff --git a/system/ui/widgets/inputbox.py b/openpilot/system/ui/widgets/inputbox.py similarity index 100% rename from system/ui/widgets/inputbox.py rename to openpilot/system/ui/widgets/inputbox.py diff --git a/system/ui/widgets/keyboard.py b/openpilot/system/ui/widgets/keyboard.py similarity index 100% rename from system/ui/widgets/keyboard.py rename to openpilot/system/ui/widgets/keyboard.py diff --git a/system/ui/widgets/label.py b/openpilot/system/ui/widgets/label.py similarity index 100% rename from system/ui/widgets/label.py rename to openpilot/system/ui/widgets/label.py diff --git a/system/ui/widgets/layouts.py b/openpilot/system/ui/widgets/layouts.py similarity index 100% rename from system/ui/widgets/layouts.py rename to openpilot/system/ui/widgets/layouts.py diff --git a/system/ui/widgets/list_view.py b/openpilot/system/ui/widgets/list_view.py similarity index 100% rename from system/ui/widgets/list_view.py rename to openpilot/system/ui/widgets/list_view.py diff --git a/system/ui/widgets/mici_keyboard.py b/openpilot/system/ui/widgets/mici_keyboard.py similarity index 100% rename from system/ui/widgets/mici_keyboard.py rename to openpilot/system/ui/widgets/mici_keyboard.py diff --git a/system/ui/widgets/nav_widget.py b/openpilot/system/ui/widgets/nav_widget.py similarity index 100% rename from system/ui/widgets/nav_widget.py rename to openpilot/system/ui/widgets/nav_widget.py diff --git a/system/ui/widgets/network.py b/openpilot/system/ui/widgets/network.py similarity index 100% rename from system/ui/widgets/network.py rename to openpilot/system/ui/widgets/network.py diff --git a/system/ui/widgets/option_dialog.py b/openpilot/system/ui/widgets/option_dialog.py similarity index 100% rename from system/ui/widgets/option_dialog.py rename to openpilot/system/ui/widgets/option_dialog.py diff --git a/system/ui/widgets/scroller.py b/openpilot/system/ui/widgets/scroller.py similarity index 100% rename from system/ui/widgets/scroller.py rename to openpilot/system/ui/widgets/scroller.py diff --git a/system/ui/widgets/scroller_tici.py b/openpilot/system/ui/widgets/scroller_tici.py similarity index 100% rename from system/ui/widgets/scroller_tici.py rename to openpilot/system/ui/widgets/scroller_tici.py diff --git a/system/ui/widgets/slider.py b/openpilot/system/ui/widgets/slider.py similarity index 100% rename from system/ui/widgets/slider.py rename to openpilot/system/ui/widgets/slider.py diff --git a/system/ui/widgets/toggle.py b/openpilot/system/ui/widgets/toggle.py similarity index 100% rename from system/ui/widgets/toggle.py rename to openpilot/system/ui/widgets/toggle.py diff --git a/system/updated/common.py b/openpilot/system/updated/common.py similarity index 100% rename from system/updated/common.py rename to openpilot/system/updated/common.py diff --git a/system/updated/updated.py b/openpilot/system/updated/updated.py similarity index 98% rename from system/updated/updated.py rename to openpilot/system/updated/updated.py index 53f200fe5c..99e42a41b3 100755 --- a/system/updated/updated.py +++ b/openpilot/system/updated/updated.py @@ -3,7 +3,6 @@ import os import re import datetime import subprocess -import psutil import shutil import signal import fcntl @@ -18,7 +17,7 @@ from openpilot.common.markdown import parse_markdown from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import AGNOS, HARDWARE -from openpilot.system.version import get_build_metadata, SP_BRANCH_MIGRATIONS +from openpilot.common.version import get_build_metadata, SP_BRANCH_MIGRATIONS LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") @@ -210,7 +209,7 @@ def handle_agnos_update() -> None: cloudlog.info(f"Beginning background installation for AGNOS {updated_version}") set_offroad_alert("Offroad_NeosUpdate", True) - manifest_path = os.path.join(OVERLAY_MERGED, "system/hardware/tici/agnos.json") + manifest_path = os.path.join(OVERLAY_MERGED, "openpilot/system/hardware/tici/agnos.json") target_slot_number = get_target_slot_number() flash_agnos_update(manifest_path, target_slot_number, cloudlog) set_offroad_alert("Offroad_NeosUpdate", False) @@ -294,7 +293,7 @@ class Updater: try: branch = self.get_branch(basedir) commit = self.get_commit_hash(basedir)[:7] - with open(os.path.join(basedir, "sunnypilot", "common", "version.h")) as f: + with open(os.path.join(basedir, "openpilot", "sunnypilot", "common", "version.h")) as f: version = f.read().split('"')[1] commit_unix_ts = run(["git", "show", "-s", "--format=%ct", "HEAD"], basedir).rstrip() @@ -412,11 +411,6 @@ def main() -> None: except OSError as e: raise RuntimeError("couldn't get overlay lock; is another instance running?") from e - # Set low io priority - proc = psutil.Process() - if psutil.LINUX: - proc.ionice(psutil.IOPRIO_CLASS_BE, value=7) - # Check if we just performed an update if Path(os.path.join(STAGING_ROOT, "old_openpilot")).is_dir(): cloudlog.event("update installed") diff --git a/system/ui/sunnypilot/widgets/helpers/__init__.py b/openpilot/system/webrtc/__init__.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/__init__.py rename to openpilot/system/webrtc/__init__.py diff --git a/system/webrtc/device/video.py b/openpilot/system/webrtc/device/video.py similarity index 98% rename from system/webrtc/device/video.py rename to openpilot/system/webrtc/device/video.py index 69f628cb11..3c8a7b93c2 100644 --- a/system/webrtc/device/video.py +++ b/openpilot/system/webrtc/device/video.py @@ -6,7 +6,7 @@ import av from teleoprtc.tracks import TiciVideoStreamTrack from aiortc import MediaStreamError -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/system/webrtc/helpers.py b/openpilot/system/webrtc/helpers.py similarity index 100% rename from system/webrtc/helpers.py rename to openpilot/system/webrtc/helpers.py diff --git a/system/webrtc/schema.py b/openpilot/system/webrtc/schema.py similarity index 100% rename from system/webrtc/schema.py rename to openpilot/system/webrtc/schema.py diff --git a/system/webrtc/tests/test_stream_session.py b/openpilot/system/webrtc/tests/test_stream_session.py similarity index 98% rename from system/webrtc/tests/test_stream_session.py rename to openpilot/system/webrtc/tests/test_stream_session.py index bf413eeeba..e03932f7b2 100644 --- a/system/webrtc/tests/test_stream_session.py +++ b/openpilot/system/webrtc/tests/test_stream_session.py @@ -9,7 +9,7 @@ warnings.filterwarnings("ignore", category=RuntimeWarning) # TODO: remove this w from aiortc import RTCDataChannel from aiortc.mediastreams import VIDEO_CLOCK_RATE, VIDEO_TIME_BASE import capnp -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.system.webrtc.webrtcd import CerealOutgoingMessageProxy, CerealIncomingMessageProxy from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack diff --git a/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py similarity index 72% rename from system/webrtc/webrtcd.py rename to openpilot/system/webrtc/webrtcd.py index da10855a59..bf96cd04ba 100755 --- a/system/webrtc/webrtcd.py +++ b/openpilot/system/webrtc/webrtcd.py @@ -10,6 +10,10 @@ import contextlib import json import uuid import logging +import signal +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlparse, parse_qs from typing import Any, TYPE_CHECKING # aiortc and its dependencies have lots of internal warnings :( @@ -18,7 +22,6 @@ warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=RuntimeWarning) # TODO: remove this when google-crc32c publish a python3.12 wheel import capnp -from aiohttp import web if TYPE_CHECKING: from aiortc.rtcdatachannel import RTCDataChannel import aioice.ice @@ -26,7 +29,7 @@ import aioice.ice from openpilot.system.webrtc.helpers import StreamRequestBody from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params -from cereal import messaging, log +from openpilot.cereal import messaging, log # socket trick: route lookup for 8.8.8.8 (nothing is sent or actually connected to) @@ -363,27 +366,43 @@ class StreamSession: await self.stream.stop() -def schedule_teardown(app): - # if nothing connects for 5 seconds, tear down livestreaming processes - h = app.get('teardown') - if h: - h.cancel() +class ServerState: + def __init__(self, debug: bool): + self.streams: dict[str, StreamSession] = {} + self.stream_lock = asyncio.Lock() + self.debug = debug + self.teardown: asyncio.TimerHandle | None = None + + +# if nothing connects for 5 seconds, tear down livestreaming processes +def schedule_teardown(state: ServerState): + if state.teardown is not None: + state.teardown.cancel() + def clear(): - if not app['streams']: - Params().put_bool("IsLiveStreaming", False) - app['teardown'] = asyncio.get_running_loop().call_later(5.0, clear) + if not state.streams: + Params().put_bool("IsLiveStreaming", False) + + state.teardown = asyncio.get_running_loop().call_later(5.0, clear) -async def get_stream(request: 'web.Request'): - stream_dict, debug_mode = request.app['streams'], request.app['debug'] - raw_body = await request.json() - body = StreamRequestBody(**raw_body) +def _json_response(obj: Any, status: int = 200) -> tuple[int, bytes, str]: + return (status, json.dumps(obj).encode(), "application/json; charset=utf-8") - async with request.app['stream_lock']: + +def _text_response(text: str, status: int = 200) -> tuple[int, bytes, str]: + return (status, text.encode(), "text/plain; charset=utf-8") + + +async def handle_get_stream(state: ServerState, raw_body: bytes) -> tuple[int, bytes, str]: + stream_dict, debug_mode = state.streams, state.debug + body = StreamRequestBody(**json.loads(raw_body)) + + async with state.stream_lock: # don't remove existing connection on prewarm request enabled = any(s.run_task and not s.run_task.done() and s.enabled for s in stream_dict.values()) if enabled and not body.enabled: - return web.json_response({"error": "busy", "message": "someone else is connected."}) + return _json_response({"error": "busy", "message": "someone else is connected."}) for sid, s in list(stream_dict.items()): if s.run_task and not s.run_task.done(): @@ -408,54 +427,134 @@ async def get_stream(request: 'web.Request'): def remove_finished_session(_: asyncio.Task) -> None: stream_dict.pop(session.identifier, None) - schedule_teardown(request.app) + schedule_teardown(state) + session.run_task.add_done_callback(remove_finished_session) - return web.json_response({"sdp": answer.sdp, "type": answer.type}) + return _json_response({"sdp": answer.sdp, "type": answer.type}) -async def get_schema(request: 'web.Request'): - services = request.query.get("services", "").split(",") +async def handle_get_schema(state: ServerState, services_param: str) -> tuple[int, bytes, str]: + services = services_param.split(",") services = [s for s in services if s] assert all(s in log.Event.schema.fields and not s.endswith("DEPRECATED") for s in services), "Invalid service name" schema_dict = {s: generate_field(log.Event.schema.fields[s]) for s in services} - return web.json_response(schema_dict) + return _json_response(schema_dict) -async def post_notify(request: 'web.Request'): - try: - payload = await request.json() - except Exception as e: - raise web.HTTPBadRequest(text="Invalid JSON") from e - - for session in list(request.app.get('streams', {}).values()): +async def handle_post_notify(state: ServerState, payload: Any) -> tuple[int, bytes, str]: + for session in list(state.streams.values()): try: ch = session.stream.get_messaging_channel() ch.send(json.dumps(payload)) except Exception: continue - return web.Response(status=200, text="OK") + return _text_response("OK") -async def on_shutdown(app: 'web.Application'): - for session in list(app['streams'].values()): +async def on_shutdown(state: ServerState): + for session in list(state.streams.values()): try: ch = session.stream.get_messaging_channel() ch.send(json.dumps({"type": "disconnect", "data": "device streaming has been stopped."})) except Exception: pass await session.stop() - del app['streams'] + state.streams.clear() -@web.middleware -async def error_middleware(request: 'web.Request', handler): - try: - return await handler(request) - except Exception as e: - logging.getLogger("webrtcd").exception("Unhandled error handling %s", request.path) - return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) +class WebrtcdHandler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + # path -> allowed methods (aiohttp registered POST /stream, POST /notify, GET /schema + its auto HEAD) + _routes = { + "/schema": ("GET", "HEAD"), + "/stream": ("POST",), + "/notify": ("POST",), + } + + def _send(self, status: int, body: bytes, content_type: str) -> None: + self.send_response(status) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(body))) + self.end_headers() + if self.command != "HEAD": + self.wfile.write(body) + + def _read_body(self) -> bytes: + length = int(self.headers.get("Content-Length", 0)) + return self.rfile.read(length) if length else b"" + + def _run(self, coro) -> tuple[int, bytes, str]: + return asyncio.run_coroutine_threadsafe(coro, self.server.loop).result() + + def _dispatch_request(self) -> None: + parsed = urlparse(self.path) + allowed = self._routes.get(parsed.path) + + try: + if allowed is None: + result = _json_response({"error": "not found"}, status=404) + elif self.command not in allowed: + result = _json_response({"error": "method not allowed"}, status=405) + elif parsed.path == "/schema": + services = parse_qs(parsed.query).get("services", [""])[0] + result = self._run(handle_get_schema(self.server.state, services)) + elif parsed.path == "/stream": + result = self._run(handle_get_stream(self.server.state, self._read_body())) + else: # /notify + try: + payload = json.loads(self._read_body()) + except Exception: + result = _json_response({"error": "bad request"}, status=400) + else: + result = self._run(handle_post_notify(self.server.state, payload)) + except Exception as e: + logging.getLogger("webrtcd").exception("Unhandled error handling %s", self.path) + result = _json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) + + self._send(*result) + + def do_GET(self) -> None: + self._dispatch_request() + + def do_HEAD(self) -> None: + self._dispatch_request() + + def do_POST(self) -> None: + self._dispatch_request() + + def do_PUT(self) -> None: + self._dispatch_request() + + def do_DELETE(self) -> None: + self._dispatch_request() + + def do_PATCH(self) -> None: + self._dispatch_request() + + def do_OPTIONS(self) -> None: + self._dispatch_request() + + def log_message(self, fmt, *args) -> None: + # silence default access logging; errors are logged explicitly in _dispatch_request + pass + + +class WebrtcdHTTPServer(ThreadingHTTPServer): + daemon_threads = True + allow_reuse_address = True + state: ServerState + loop: asyncio.AbstractEventLoop + + +async def _shutdown(server: WebrtcdHTTPServer, state: ServerState, loop: asyncio.AbstractEventLoop) -> None: + # stop accepting new HTTP connections (blocks until serve_forever returns, so + # run it off the loop) then tear down active stream sessions. + await loop.run_in_executor(None, server.shutdown) + await on_shutdown(state) + loop.stop() def prewarm_stream_session_imports(debug_mode: bool = False) -> None: @@ -475,17 +574,35 @@ def webrtcd_thread(host: str, port: int, debug: bool): prewarm_end = time.monotonic() logging.getLogger("webrtcd").info(f"webrtc prewarm finished in {(prewarm_end - prewarm_start) * 1000} ms") - app = web.Application(middlewares=[error_middleware]) + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + state = ServerState(debug) - app['streams'] = dict() - app['stream_lock'] = asyncio.Lock() - app['debug'] = debug - app.on_shutdown.append(on_shutdown) - app.router.add_post("/stream", get_stream) - app.router.add_post("/notify", post_notify) - app.router.add_get("/schema", get_schema) + server = WebrtcdHTTPServer((host, port), WebrtcdHandler) + server.state = state + server.loop = loop - web.run_app(app, host=host, port=port) + # serve HTTP on a daemon thread so the asyncio loop can own the main thread + http_thread = threading.Thread(target=server.serve_forever, name="webrtcd-http", daemon=True) + http_thread.start() + + shutting_down = False + + def request_shutdown() -> None: + nonlocal shutting_down + if shutting_down: + return + shutting_down = True + loop.create_task(_shutdown(server, state, loop)) + + for sig in (signal.SIGINT, signal.SIGTERM): + loop.add_signal_handler(sig, request_shutdown) + + try: + loop.run_forever() + finally: + server.server_close() + loop.close() def main(): diff --git a/third_party/copyparty/copyparty-sfx.py b/openpilot/third_party/copyparty/copyparty-sfx.py similarity index 100% rename from third_party/copyparty/copyparty-sfx.py rename to openpilot/third_party/copyparty/copyparty-sfx.py diff --git a/third_party/mapd_pfeiferj/README.md b/openpilot/third_party/mapd_pfeiferj/README.md similarity index 100% rename from third_party/mapd_pfeiferj/README.md rename to openpilot/third_party/mapd_pfeiferj/README.md diff --git a/third_party/mapd_pfeiferj/mapd b/openpilot/third_party/mapd_pfeiferj/mapd similarity index 100% rename from third_party/mapd_pfeiferj/mapd rename to openpilot/third_party/mapd_pfeiferj/mapd diff --git a/openpilot/tools b/openpilot/tools deleted file mode 120000 index 4887d6e0c9..0000000000 --- a/openpilot/tools +++ /dev/null @@ -1 +0,0 @@ -../tools \ No newline at end of file diff --git a/system/webrtc/__init__.py b/openpilot/tools/__init__.py similarity index 100% rename from system/webrtc/__init__.py rename to openpilot/tools/__init__.py diff --git a/tools/auto_source.py b/openpilot/tools/auto_source.py similarity index 100% rename from tools/auto_source.py rename to openpilot/tools/auto_source.py diff --git a/tools/cabana/.gitignore b/openpilot/tools/cabana/.gitignore similarity index 100% rename from tools/cabana/.gitignore rename to openpilot/tools/cabana/.gitignore diff --git a/tools/cabana/README.md b/openpilot/tools/cabana/README.md similarity index 98% rename from tools/cabana/README.md rename to openpilot/tools/cabana/README.md index a721b1aa13..b30c29640e 100644 --- a/tools/cabana/README.md +++ b/openpilot/tools/cabana/README.md @@ -63,8 +63,8 @@ cabana "5beb9b58bd12b691/0000010a--a51155e496" --dcam --ecam [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and start the bridge with the following command: ```shell -cd /data/openpilot/cereal/messaging/ -./bridge & +cd /data/openpilot +./openpilot/cereal/messaging/bridge & ``` Then Run Cabana with the device's IP address: diff --git a/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript similarity index 88% rename from tools/cabana/SConscript rename to openpilot/tools/cabana/SConscript index 04389a9ebf..26c20ddba1 100644 --- a/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -5,7 +5,7 @@ import shutil import bootstrap_icons import libusb -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib', 'ffmpeg_libs') # Detect Qt - skip build if not available if arch == "Darwin": @@ -60,7 +60,7 @@ qt_flags = [ "-DQT_MESSAGELOGCONTEXT", ] qt_env['CXXFLAGS'] += qt_flags -qt_env['LIBPATH'] += ['#selfdrive/ui', ] +qt_env['LIBPATH'] += ['#openpilot/selfdrive/ui', ] qt_env['LIBS'] = qt_libs base_frameworks = qt_env['FRAMEWORKS'] @@ -75,10 +75,8 @@ cabana_env = qt_env.Clone() cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] -cabana_libs = [cereal, messaging, visionipc, replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs -if arch != "Darwin": - cabana_libs += ['va', 'va-drm', 'drm'] -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../opendbc/dbc").abspath) +cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'usb-1.0'] + base_libs +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc_repo/opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] def write_assets_qrc(target, source, env): @@ -112,8 +110,8 @@ cabana_env.Program('_cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_lib if GetOption('extras'): cabana_env.Program('tests/test_cabana', ['tests/test_runner.cc', 'tests/test_cabana.cc', cabana_lib], LIBS=[cabana_libs]) -output_json_file = 'tools/cabana/dbc/car_fingerprint_to_dbc.json' +output_json_file = 'openpilot/tools/cabana/dbc/car_fingerprint_to_dbc.json' generate_dbc = cabana_env.Command('#' + output_json_file, ['dbc/generate_dbc_json.py'], - "python3 tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) -cabana_env.Depends(generate_dbc, ["#common", '#opendbc_repo', "#cereal", "#msgq_repo"]) + "python3 openpilot/tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) +cabana_env.Depends(generate_dbc, ["#openpilot/common", '#opendbc_repo', "#openpilot/cereal", "#msgq_repo"]) diff --git a/tools/cabana/assets/assets.qrc b/openpilot/tools/cabana/assets/assets.qrc similarity index 100% rename from tools/cabana/assets/assets.qrc rename to openpilot/tools/cabana/assets/assets.qrc diff --git a/tools/cabana/assets/cabana-icon.png b/openpilot/tools/cabana/assets/cabana-icon.png similarity index 100% rename from tools/cabana/assets/cabana-icon.png rename to openpilot/tools/cabana/assets/cabana-icon.png diff --git a/tools/cabana/binaryview.cc b/openpilot/tools/cabana/binaryview.cc similarity index 100% rename from tools/cabana/binaryview.cc rename to openpilot/tools/cabana/binaryview.cc diff --git a/tools/cabana/binaryview.h b/openpilot/tools/cabana/binaryview.h similarity index 100% rename from tools/cabana/binaryview.h rename to openpilot/tools/cabana/binaryview.h diff --git a/tools/cabana/cabana b/openpilot/tools/cabana/cabana similarity index 86% rename from tools/cabana/cabana rename to openpilot/tools/cabana/cabana index 5eb15eabf0..db613b5391 100755 --- a/tools/cabana/cabana +++ b/openpilot/tools/cabana/cabana @@ -2,7 +2,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -ROOT="$(cd "$DIR/../../" && pwd)" +ROOT="$(cd "$DIR/../../../" && pwd)" install_qt() { if [[ "$(uname)" == "Darwin" ]]; then @@ -33,6 +33,6 @@ fi # Build _cabana cd "$ROOT" -scons tools/cabana/_cabana cereal/messaging/bridge +scons -u openpilot/tools/cabana/_cabana openpilot/cereal/messaging/bridge exec "$DIR/_cabana" "$@" diff --git a/tools/cabana/cabana.cc b/openpilot/tools/cabana/cabana.cc similarity index 100% rename from tools/cabana/cabana.cc rename to openpilot/tools/cabana/cabana.cc diff --git a/tools/cabana/cameraview.cc b/openpilot/tools/cabana/cameraview.cc similarity index 100% rename from tools/cabana/cameraview.cc rename to openpilot/tools/cabana/cameraview.cc diff --git a/tools/cabana/cameraview.h b/openpilot/tools/cabana/cameraview.h similarity index 100% rename from tools/cabana/cameraview.h rename to openpilot/tools/cabana/cameraview.h diff --git a/tools/cabana/chart/chart.cc b/openpilot/tools/cabana/chart/chart.cc similarity index 100% rename from tools/cabana/chart/chart.cc rename to openpilot/tools/cabana/chart/chart.cc diff --git a/tools/cabana/chart/chart.h b/openpilot/tools/cabana/chart/chart.h similarity index 100% rename from tools/cabana/chart/chart.h rename to openpilot/tools/cabana/chart/chart.h diff --git a/tools/cabana/chart/chartswidget.cc b/openpilot/tools/cabana/chart/chartswidget.cc similarity index 100% rename from tools/cabana/chart/chartswidget.cc rename to openpilot/tools/cabana/chart/chartswidget.cc diff --git a/tools/cabana/chart/chartswidget.h b/openpilot/tools/cabana/chart/chartswidget.h similarity index 100% rename from tools/cabana/chart/chartswidget.h rename to openpilot/tools/cabana/chart/chartswidget.h diff --git a/tools/cabana/chart/signalselector.cc b/openpilot/tools/cabana/chart/signalselector.cc similarity index 100% rename from tools/cabana/chart/signalselector.cc rename to openpilot/tools/cabana/chart/signalselector.cc diff --git a/tools/cabana/chart/signalselector.h b/openpilot/tools/cabana/chart/signalselector.h similarity index 100% rename from tools/cabana/chart/signalselector.h rename to openpilot/tools/cabana/chart/signalselector.h diff --git a/tools/cabana/chart/sparkline.cc b/openpilot/tools/cabana/chart/sparkline.cc similarity index 100% rename from tools/cabana/chart/sparkline.cc rename to openpilot/tools/cabana/chart/sparkline.cc diff --git a/tools/cabana/chart/sparkline.h b/openpilot/tools/cabana/chart/sparkline.h similarity index 100% rename from tools/cabana/chart/sparkline.h rename to openpilot/tools/cabana/chart/sparkline.h diff --git a/tools/cabana/chart/tiplabel.cc b/openpilot/tools/cabana/chart/tiplabel.cc similarity index 100% rename from tools/cabana/chart/tiplabel.cc rename to openpilot/tools/cabana/chart/tiplabel.cc diff --git a/tools/cabana/chart/tiplabel.h b/openpilot/tools/cabana/chart/tiplabel.h similarity index 100% rename from tools/cabana/chart/tiplabel.h rename to openpilot/tools/cabana/chart/tiplabel.h diff --git a/tools/cabana/commands.cc b/openpilot/tools/cabana/commands.cc similarity index 100% rename from tools/cabana/commands.cc rename to openpilot/tools/cabana/commands.cc diff --git a/tools/cabana/commands.h b/openpilot/tools/cabana/commands.h similarity index 100% rename from tools/cabana/commands.h rename to openpilot/tools/cabana/commands.h diff --git a/tools/cabana/dbc/dbc.cc b/openpilot/tools/cabana/dbc/dbc.cc similarity index 100% rename from tools/cabana/dbc/dbc.cc rename to openpilot/tools/cabana/dbc/dbc.cc diff --git a/tools/cabana/dbc/dbc.h b/openpilot/tools/cabana/dbc/dbc.h similarity index 100% rename from tools/cabana/dbc/dbc.h rename to openpilot/tools/cabana/dbc/dbc.h diff --git a/tools/cabana/dbc/dbcfile.cc b/openpilot/tools/cabana/dbc/dbcfile.cc similarity index 100% rename from tools/cabana/dbc/dbcfile.cc rename to openpilot/tools/cabana/dbc/dbcfile.cc diff --git a/tools/cabana/dbc/dbcfile.h b/openpilot/tools/cabana/dbc/dbcfile.h similarity index 100% rename from tools/cabana/dbc/dbcfile.h rename to openpilot/tools/cabana/dbc/dbcfile.h diff --git a/tools/cabana/dbc/dbcmanager.cc b/openpilot/tools/cabana/dbc/dbcmanager.cc similarity index 100% rename from tools/cabana/dbc/dbcmanager.cc rename to openpilot/tools/cabana/dbc/dbcmanager.cc diff --git a/tools/cabana/dbc/dbcmanager.h b/openpilot/tools/cabana/dbc/dbcmanager.h similarity index 100% rename from tools/cabana/dbc/dbcmanager.h rename to openpilot/tools/cabana/dbc/dbcmanager.h diff --git a/tools/cabana/dbc/generate_dbc_json.py b/openpilot/tools/cabana/dbc/generate_dbc_json.py similarity index 99% rename from tools/cabana/dbc/generate_dbc_json.py rename to openpilot/tools/cabana/dbc/generate_dbc_json.py index d002a50ef8..13b6799ffb 100755 --- a/tools/cabana/dbc/generate_dbc_json.py +++ b/openpilot/tools/cabana/dbc/generate_dbc_json.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import argparse import json - from opendbc.car import Bus from opendbc.car.fingerprints import MIGRATION from opendbc.car.values import PLATFORMS diff --git a/tools/cabana/detailwidget.cc b/openpilot/tools/cabana/detailwidget.cc similarity index 100% rename from tools/cabana/detailwidget.cc rename to openpilot/tools/cabana/detailwidget.cc diff --git a/tools/cabana/detailwidget.h b/openpilot/tools/cabana/detailwidget.h similarity index 100% rename from tools/cabana/detailwidget.h rename to openpilot/tools/cabana/detailwidget.h diff --git a/tools/cabana/historylog.cc b/openpilot/tools/cabana/historylog.cc similarity index 100% rename from tools/cabana/historylog.cc rename to openpilot/tools/cabana/historylog.cc diff --git a/tools/cabana/historylog.h b/openpilot/tools/cabana/historylog.h similarity index 100% rename from tools/cabana/historylog.h rename to openpilot/tools/cabana/historylog.h diff --git a/tools/cabana/mainwin.cc b/openpilot/tools/cabana/mainwin.cc similarity index 100% rename from tools/cabana/mainwin.cc rename to openpilot/tools/cabana/mainwin.cc diff --git a/tools/cabana/mainwin.h b/openpilot/tools/cabana/mainwin.h similarity index 100% rename from tools/cabana/mainwin.h rename to openpilot/tools/cabana/mainwin.h diff --git a/tools/cabana/messageswidget.cc b/openpilot/tools/cabana/messageswidget.cc similarity index 100% rename from tools/cabana/messageswidget.cc rename to openpilot/tools/cabana/messageswidget.cc diff --git a/tools/cabana/messageswidget.h b/openpilot/tools/cabana/messageswidget.h similarity index 100% rename from tools/cabana/messageswidget.h rename to openpilot/tools/cabana/messageswidget.h diff --git a/tools/cabana/panda.cc b/openpilot/tools/cabana/panda.cc similarity index 99% rename from tools/cabana/panda.cc rename to openpilot/tools/cabana/panda.cc index cf5354a507..33117812d3 100644 --- a/tools/cabana/panda.cc +++ b/openpilot/tools/cabana/panda.cc @@ -6,7 +6,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" #include "common/util.h" diff --git a/tools/cabana/panda.h b/openpilot/tools/cabana/panda.h similarity index 96% rename from tools/cabana/panda.h rename to openpilot/tools/cabana/panda.h index 8b861a2476..216a6b72d7 100644 --- a/tools/cabana/panda.h +++ b/openpilot/tools/cabana/panda.h @@ -13,8 +13,8 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "panda/board/health.h" #include "panda/board/can.h" diff --git a/tools/cabana/settings.cc b/openpilot/tools/cabana/settings.cc similarity index 100% rename from tools/cabana/settings.cc rename to openpilot/tools/cabana/settings.cc diff --git a/tools/cabana/settings.h b/openpilot/tools/cabana/settings.h similarity index 100% rename from tools/cabana/settings.h rename to openpilot/tools/cabana/settings.h diff --git a/tools/cabana/signalview.cc b/openpilot/tools/cabana/signalview.cc similarity index 100% rename from tools/cabana/signalview.cc rename to openpilot/tools/cabana/signalview.cc diff --git a/tools/cabana/signalview.h b/openpilot/tools/cabana/signalview.h similarity index 100% rename from tools/cabana/signalview.h rename to openpilot/tools/cabana/signalview.h diff --git a/tools/cabana/streams/abstractstream.cc b/openpilot/tools/cabana/streams/abstractstream.cc similarity index 100% rename from tools/cabana/streams/abstractstream.cc rename to openpilot/tools/cabana/streams/abstractstream.cc diff --git a/tools/cabana/streams/abstractstream.h b/openpilot/tools/cabana/streams/abstractstream.h similarity index 99% rename from tools/cabana/streams/abstractstream.h rename to openpilot/tools/cabana/streams/abstractstream.h index 7d66a420dc..2f3b26fe2a 100644 --- a/tools/cabana/streams/abstractstream.h +++ b/openpilot/tools/cabana/streams/abstractstream.h @@ -14,7 +14,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "tools/cabana/dbc/dbcmanager.h" #include "tools/cabana/utils/util.h" #include "tools/replay/util.h" diff --git a/tools/cabana/streams/devicestream.cc b/openpilot/tools/cabana/streams/devicestream.cc similarity index 97% rename from tools/cabana/streams/devicestream.cc rename to openpilot/tools/cabana/streams/devicestream.cc index 20eaa70cd6..96fae908ba 100644 --- a/tools/cabana/streams/devicestream.cc +++ b/openpilot/tools/cabana/streams/devicestream.cc @@ -3,7 +3,7 @@ #include #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include #include @@ -33,7 +33,7 @@ DeviceStream::~DeviceStream() { void DeviceStream::start() { if (!zmq_address.isEmpty()) { bridge_process = new QProcess(this); - QString bridge_path = QCoreApplication::applicationDirPath() + "/../../cereal/messaging/bridge"; + QString bridge_path = QCoreApplication::applicationDirPath() + "/../../openpilot/cereal/messaging/bridge"; bridge_process->start(QFileInfo(bridge_path).absoluteFilePath(), QStringList { zmq_address, "/\"can/\"" }); if (!bridge_process->waitForStarted()) { diff --git a/tools/cabana/streams/devicestream.h b/openpilot/tools/cabana/streams/devicestream.h similarity index 100% rename from tools/cabana/streams/devicestream.h rename to openpilot/tools/cabana/streams/devicestream.h diff --git a/tools/cabana/streams/livestream.cc b/openpilot/tools/cabana/streams/livestream.cc similarity index 100% rename from tools/cabana/streams/livestream.cc rename to openpilot/tools/cabana/streams/livestream.cc diff --git a/tools/cabana/streams/livestream.h b/openpilot/tools/cabana/streams/livestream.h similarity index 100% rename from tools/cabana/streams/livestream.h rename to openpilot/tools/cabana/streams/livestream.h diff --git a/tools/cabana/streams/pandastream.cc b/openpilot/tools/cabana/streams/pandastream.cc similarity index 100% rename from tools/cabana/streams/pandastream.cc rename to openpilot/tools/cabana/streams/pandastream.cc diff --git a/tools/cabana/streams/pandastream.h b/openpilot/tools/cabana/streams/pandastream.h similarity index 100% rename from tools/cabana/streams/pandastream.h rename to openpilot/tools/cabana/streams/pandastream.h diff --git a/tools/cabana/streams/replaystream.cc b/openpilot/tools/cabana/streams/replaystream.cc similarity index 99% rename from tools/cabana/streams/replaystream.cc rename to openpilot/tools/cabana/streams/replaystream.cc index f42bf2601c..b00c6e52c6 100644 --- a/tools/cabana/streams/replaystream.cc +++ b/openpilot/tools/cabana/streams/replaystream.cc @@ -68,7 +68,7 @@ bool ReplayStream::loadRoute(const std::string &route, const std::string &data_d QString message; if (auth_content.empty()) { message = "Authentication Required. Please run the following command to authenticate:\n\n" - "python3 tools/lib/auth.py\n\n" + "python3 openpilot/tools/lib/auth.py\n\n" "This will grant access to routes from your comma account."; } else { message = tr("Access Denied. You do not have permission to access route:\n\n%1\n\n" diff --git a/tools/cabana/streams/replaystream.h b/openpilot/tools/cabana/streams/replaystream.h similarity index 100% rename from tools/cabana/streams/replaystream.h rename to openpilot/tools/cabana/streams/replaystream.h diff --git a/tools/cabana/streams/routes.cc b/openpilot/tools/cabana/streams/routes.cc similarity index 98% rename from tools/cabana/streams/routes.cc rename to openpilot/tools/cabana/streams/routes.cc index 1e69a45cea..e3e5cb1b6e 100644 --- a/tools/cabana/streams/routes.cc +++ b/openpilot/tools/cabana/streams/routes.cc @@ -88,7 +88,7 @@ void RoutesDialog::parseDeviceList(const QString &json, bool success, int error_ device_list_->addItem(dongle_id, dongle_id); } } else { - QMessageBox::warning(this, tr("Error"), error_code == 401 ? tr("Unauthorized. Authenticate with tools/lib/auth.py") : tr("Network error")); + QMessageBox::warning(this, tr("Error"), error_code == 401 ? tr("Unauthorized. Authenticate with openpilot/tools/lib/auth.py") : tr("Network error")); reject(); } } diff --git a/tools/cabana/streams/routes.h b/openpilot/tools/cabana/streams/routes.h similarity index 100% rename from tools/cabana/streams/routes.h rename to openpilot/tools/cabana/streams/routes.h diff --git a/tools/cabana/streams/socketcanstream.cc b/openpilot/tools/cabana/streams/socketcanstream.cc similarity index 100% rename from tools/cabana/streams/socketcanstream.cc rename to openpilot/tools/cabana/streams/socketcanstream.cc diff --git a/tools/cabana/streams/socketcanstream.h b/openpilot/tools/cabana/streams/socketcanstream.h similarity index 100% rename from tools/cabana/streams/socketcanstream.h rename to openpilot/tools/cabana/streams/socketcanstream.h diff --git a/tools/cabana/streamselector.cc b/openpilot/tools/cabana/streamselector.cc similarity index 100% rename from tools/cabana/streamselector.cc rename to openpilot/tools/cabana/streamselector.cc diff --git a/tools/cabana/streamselector.h b/openpilot/tools/cabana/streamselector.h similarity index 100% rename from tools/cabana/streamselector.h rename to openpilot/tools/cabana/streamselector.h diff --git a/tools/cabana/tests/test_cabana.cc b/openpilot/tools/cabana/tests/test_cabana.cc similarity index 100% rename from tools/cabana/tests/test_cabana.cc rename to openpilot/tools/cabana/tests/test_cabana.cc diff --git a/tools/cabana/tests/test_runner.cc b/openpilot/tools/cabana/tests/test_runner.cc similarity index 100% rename from tools/cabana/tests/test_runner.cc rename to openpilot/tools/cabana/tests/test_runner.cc diff --git a/tools/cabana/tools/findsignal.cc b/openpilot/tools/cabana/tools/findsignal.cc similarity index 100% rename from tools/cabana/tools/findsignal.cc rename to openpilot/tools/cabana/tools/findsignal.cc diff --git a/tools/cabana/tools/findsignal.h b/openpilot/tools/cabana/tools/findsignal.h similarity index 100% rename from tools/cabana/tools/findsignal.h rename to openpilot/tools/cabana/tools/findsignal.h diff --git a/tools/cabana/tools/findsimilarbits.cc b/openpilot/tools/cabana/tools/findsimilarbits.cc similarity index 100% rename from tools/cabana/tools/findsimilarbits.cc rename to openpilot/tools/cabana/tools/findsimilarbits.cc diff --git a/tools/cabana/tools/findsimilarbits.h b/openpilot/tools/cabana/tools/findsimilarbits.h similarity index 100% rename from tools/cabana/tools/findsimilarbits.h rename to openpilot/tools/cabana/tools/findsimilarbits.h diff --git a/tools/cabana/tools/routeinfo.cc b/openpilot/tools/cabana/tools/routeinfo.cc similarity index 100% rename from tools/cabana/tools/routeinfo.cc rename to openpilot/tools/cabana/tools/routeinfo.cc diff --git a/tools/cabana/tools/routeinfo.h b/openpilot/tools/cabana/tools/routeinfo.h similarity index 100% rename from tools/cabana/tools/routeinfo.h rename to openpilot/tools/cabana/tools/routeinfo.h diff --git a/tools/cabana/utils/elidedlabel.cc b/openpilot/tools/cabana/utils/elidedlabel.cc similarity index 100% rename from tools/cabana/utils/elidedlabel.cc rename to openpilot/tools/cabana/utils/elidedlabel.cc diff --git a/tools/cabana/utils/elidedlabel.h b/openpilot/tools/cabana/utils/elidedlabel.h similarity index 100% rename from tools/cabana/utils/elidedlabel.h rename to openpilot/tools/cabana/utils/elidedlabel.h diff --git a/tools/cabana/utils/export.cc b/openpilot/tools/cabana/utils/export.cc similarity index 100% rename from tools/cabana/utils/export.cc rename to openpilot/tools/cabana/utils/export.cc diff --git a/tools/cabana/utils/export.h b/openpilot/tools/cabana/utils/export.h similarity index 100% rename from tools/cabana/utils/export.h rename to openpilot/tools/cabana/utils/export.h diff --git a/tools/cabana/utils/util.cc b/openpilot/tools/cabana/utils/util.cc similarity index 100% rename from tools/cabana/utils/util.cc rename to openpilot/tools/cabana/utils/util.cc diff --git a/tools/cabana/utils/util.h b/openpilot/tools/cabana/utils/util.h similarity index 100% rename from tools/cabana/utils/util.h rename to openpilot/tools/cabana/utils/util.h diff --git a/tools/cabana/videowidget.cc b/openpilot/tools/cabana/videowidget.cc similarity index 100% rename from tools/cabana/videowidget.cc rename to openpilot/tools/cabana/videowidget.cc diff --git a/tools/cabana/videowidget.h b/openpilot/tools/cabana/videowidget.h similarity index 100% rename from tools/cabana/videowidget.h rename to openpilot/tools/cabana/videowidget.h diff --git a/tools/camerastream/README.md b/openpilot/tools/camerastream/README.md similarity index 92% rename from tools/camerastream/README.md rename to openpilot/tools/camerastream/README.md index 2f7498a07c..8b77fc5990 100644 --- a/tools/camerastream/README.md +++ b/openpilot/tools/camerastream/README.md @@ -7,7 +7,7 @@ ### On the device SSH into the device and run following in separate terminals: -`cd /data/openpilot/cereal/messaging && ./bridge` +`cd /data/openpilot && ./openpilot/cereal/messaging/bridge` `cd /data/openpilot/system/loggerd && ./encoderd` @@ -18,8 +18,8 @@ Note that both the device and your PC must be on the same openpilot commit. Alternatively paste this as a single command: ``` ( - cd /data/openpilot/cereal/messaging/ - ./bridge & + cd /data/openpilot + ./openpilot/cereal/messaging/bridge & cd /data/openpilot/system/camerad/ ./camerad & diff --git a/tools/camerastream/compressed_vipc.py b/openpilot/tools/camerastream/compressed_vipc.py similarity index 98% rename from tools/camerastream/compressed_vipc.py rename to openpilot/tools/camerastream/compressed_vipc.py index 4dc74272ea..35e9d3dab2 100755 --- a/tools/camerastream/compressed_vipc.py +++ b/openpilot/tools/camerastream/compressed_vipc.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import av +import av.video.format import os import sys import argparse @@ -9,7 +10,7 @@ import time import signal -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from msgq.visionipc import VisionIpcServer, VisionStreamType V4L2_BUF_FLAG_KEYFRAME = 8 diff --git a/tools/clip/run.py b/openpilot/tools/clip/run.py similarity index 100% rename from tools/clip/run.py rename to openpilot/tools/clip/run.py diff --git a/tools/jotpluggler/.gitignore b/openpilot/tools/jotpluggler/.gitignore similarity index 100% rename from tools/jotpluggler/.gitignore rename to openpilot/tools/jotpluggler/.gitignore diff --git a/tools/jotpluggler/SConscript b/openpilot/tools/jotpluggler/SConscript similarity index 89% rename from tools/jotpluggler/SConscript rename to openpilot/tools/jotpluggler/SConscript index 078e173959..d5ebaffb98 100644 --- a/tools/jotpluggler/SConscript +++ b/openpilot/tools/jotpluggler/SConscript @@ -9,7 +9,7 @@ from opendbc.car.fingerprints import MIGRATION from opendbc.car.values import PLATFORMS from openpilot.common.basedir import BASEDIR -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib', 'ffmpeg_libs') jot_env = env.Clone() jot_env["LIBPATH"] += [imgui.MESA_DIR, libusb.LIB_DIR] @@ -83,7 +83,7 @@ def write_car_fingerprint_to_dbc_header(target, source, env): def generate_event_extractors(target, source, env): subprocess.check_call([ "python3", - "tools/jotpluggler/generate_event_extractors.py", + "openpilot/tools/jotpluggler/generate_event_extractors.py", os.path.realpath(BASEDIR), str(target[0]), ]) @@ -93,18 +93,20 @@ generated_dbc_stamp = jot_env.Command(f"generated_dbcs/.stamp", [], materialize_ car_fingerprint_to_dbc = jot_env.Command("car_fingerprint_to_dbc.h", [], write_car_fingerprint_to_dbc_header) event_extractors = jot_env.Command("generated_event_extractors.h", [ "generate_event_extractors.py", - jot_env.Glob("#cereal/*.capnp"), - jot_env.Glob("#cereal/include/*.capnp"), + jot_env.Glob("#openpilot/cereal/*.capnp"), + jot_env.Glob("#openpilot/cereal/include/*.capnp"), + "#opendbc_repo/opendbc/car/car.capnp", + "#opendbc_repo/opendbc/car/include/c++.capnp", ], generate_event_extractors, ) -libs = [replay_lib, common, messaging, visionipc, cereal, File(f"{imgui.LIB_DIR}/libimgui.a"), File(f"{imgui.LIB_DIR}/libglfw3.a"), - "avformat", "avcodec", "avutil", "x264", "yuv", "z", "bz2", "zstd", "m", "pthread", "usb-1.0"] +libs = [replay_lib, common, messaging, visionipc, cereal, File(f"{imgui.LIB_DIR}/libimgui.a"), File(f"{imgui.LIB_DIR}/libglfw3.a")] + \ + ffmpeg_libs + ["bz2", "zstd", "m", "pthread", "usb-1.0"] if arch == "Darwin": jot_env["FRAMEWORKS"] = ["OpenGL", "Cocoa", "IOKit", "CoreFoundation", "CoreVideo", "CoreMedia", "VideoToolbox"] else: - libs += ["GL", "dl", "va", "va-drm", "drm"] + libs += ["GL", "dl"] program = jot_env.Program("jotpluggler", jot_env.Glob("*.cc"), LIBS=libs) jot_env.Depends(program, generated_dbc_stamp) diff --git a/tools/jotpluggler/app.cc b/openpilot/tools/jotpluggler/app.cc similarity index 99% rename from tools/jotpluggler/app.cc rename to openpilot/tools/jotpluggler/app.cc index f80443e569..01eec15367 100644 --- a/tools/jotpluggler/app.cc +++ b/openpilot/tools/jotpluggler/app.cc @@ -49,7 +49,7 @@ std::string layout_name_from_arg(const std::string &layout_arg) { } fs::path layouts_dir() { - return repo_root() / "tools" / "jotpluggler" / "layouts"; + return repo_root() / "openpilot" / "tools" / "jotpluggler" / "layouts"; } std::string sanitize_layout_stem(std::string_view name) { @@ -249,7 +249,7 @@ void configure_style() { g_ui_font = nullptr; g_ui_bold_font = nullptr; g_mono_font = nullptr; - const fs::path fonts_dir = repo_root() / "selfdrive" / "assets" / "fonts"; + const fs::path fonts_dir = repo_root() / "openpilot" / "selfdrive" / "assets" / "fonts"; ImFontConfig font_cfg; font_cfg.OversampleH = 2; font_cfg.OversampleV = 2; diff --git a/tools/jotpluggler/app.h b/openpilot/tools/jotpluggler/app.h similarity index 99% rename from tools/jotpluggler/app.h rename to openpilot/tools/jotpluggler/app.h index 872a6973d7..a38f889687 100644 --- a/tools/jotpluggler/app.h +++ b/openpilot/tools/jotpluggler/app.h @@ -1,6 +1,6 @@ #pragma once -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "imgui.h" #include "tools/jotpluggler/dbc.h" #include "tools/jotpluggler/util.h" @@ -143,7 +143,7 @@ struct CameraFeedIndex { enum class LogOrigin : uint8_t { Log, - Android, + OperatingSystem, Alert, }; diff --git a/tools/jotpluggler/browser.cc b/openpilot/tools/jotpluggler/browser.cc similarity index 100% rename from tools/jotpluggler/browser.cc rename to openpilot/tools/jotpluggler/browser.cc diff --git a/tools/jotpluggler/camera.cc b/openpilot/tools/jotpluggler/camera.cc similarity index 100% rename from tools/jotpluggler/camera.cc rename to openpilot/tools/jotpluggler/camera.cc diff --git a/tools/jotpluggler/camera.h b/openpilot/tools/jotpluggler/camera.h similarity index 100% rename from tools/jotpluggler/camera.h rename to openpilot/tools/jotpluggler/camera.h diff --git a/tools/jotpluggler/common.cc b/openpilot/tools/jotpluggler/common.cc similarity index 100% rename from tools/jotpluggler/common.cc rename to openpilot/tools/jotpluggler/common.cc diff --git a/tools/jotpluggler/common.h b/openpilot/tools/jotpluggler/common.h similarity index 100% rename from tools/jotpluggler/common.h rename to openpilot/tools/jotpluggler/common.h diff --git a/tools/jotpluggler/custom_series.cc b/openpilot/tools/jotpluggler/custom_series.cc similarity index 99% rename from tools/jotpluggler/custom_series.cc rename to openpilot/tools/jotpluggler/custom_series.cc index aabf78a0db..70b3e8c3cb 100644 --- a/tools/jotpluggler/custom_series.cc +++ b/openpilot/tools/jotpluggler/custom_series.cc @@ -189,7 +189,7 @@ PythonEvalResult evaluate_custom_python_series(const AppSession &session, const CommandResult process = run_process_capture_output({ "python3", - (repo_root() / "tools" / "jotpluggler" / "math_eval.py").string(), + (repo_root() / "openpilot" / "tools" / "jotpluggler" / "math_eval.py").string(), manifest_path.string(), globals_path.string(), code_path.string(), diff --git a/tools/jotpluggler/dbc.h b/openpilot/tools/jotpluggler/dbc.h similarity index 100% rename from tools/jotpluggler/dbc.h rename to openpilot/tools/jotpluggler/dbc.h diff --git a/tools/jotpluggler/generate_event_extractors.py b/openpilot/tools/jotpluggler/generate_event_extractors.py similarity index 98% rename from tools/jotpluggler/generate_event_extractors.py rename to openpilot/tools/jotpluggler/generate_event_extractors.py index 1aba9578cd..be9bd49003 100644 --- a/tools/jotpluggler/generate_event_extractors.py +++ b/openpilot/tools/jotpluggler/generate_event_extractors.py @@ -275,7 +275,7 @@ class Generator: def generate(self): self.lines = [] - self.emit(0, "// Generated by tools/jotpluggler/generate_event_extractors.py; do not edit.") + self.emit(0, "// Generated by openpilot/tools/jotpluggler/generate_event_extractors.py; do not edit.") self.emit(0, "") self.emit(0, "const std::vector &static_event_fixed_paths() {") self.emit(2, "static const std::vector paths = {") @@ -321,7 +321,7 @@ if __name__ == "__main__": repo_root = Path(sys.argv[1]).resolve() output = Path(sys.argv[2]) capnp.remove_import_hook() - log = capnp.load(str(repo_root / "cereal" / "log.capnp")) + log = capnp.load(str(repo_root / "openpilot" / "cereal" / "log.capnp"), imports=[str(repo_root / "opendbc_repo" / "opendbc" / "car")]) generated = Generator(log.Event.schema).generate() output.parent.mkdir(parents=True, exist_ok=True) output.write_text(generated) diff --git a/tools/jotpluggler/generated_dbcs/.gitignore b/openpilot/tools/jotpluggler/generated_dbcs/.gitignore similarity index 100% rename from tools/jotpluggler/generated_dbcs/.gitignore rename to openpilot/tools/jotpluggler/generated_dbcs/.gitignore diff --git a/tools/jotpluggler/icons.cc b/openpilot/tools/jotpluggler/icons.cc similarity index 100% rename from tools/jotpluggler/icons.cc rename to openpilot/tools/jotpluggler/icons.cc diff --git a/tools/jotpluggler/internal.h b/openpilot/tools/jotpluggler/internal.h similarity index 100% rename from tools/jotpluggler/internal.h rename to openpilot/tools/jotpluggler/internal.h diff --git a/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc similarity index 98% rename from tools/jotpluggler/layout.cc rename to openpilot/tools/jotpluggler/layout.cc index bf2a3f208c..6bc3a6168a 100644 --- a/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -274,9 +274,9 @@ std::string default_dbc_template() { } DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { - const fs::path generated_dbc_dir = repo_root() / "tools" / "jotpluggler" / "generated_dbcs"; + const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ - {.path = repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, + {.path = repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, }}; for (const DbcEditorSource &candidate : candidates) { @@ -334,7 +334,7 @@ bool save_dbc_editor_contents(AppSession *session, UiState *state) { } try { dbc::Database::fromContent(editor.text, editor.save_name + ".dbc"); - const fs::path generated_dbc_dir = repo_root() / "tools" / "jotpluggler" / "generated_dbcs"; + const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; fs::create_directories(generated_dbc_dir); const fs::path output = generated_dbc_dir / (editor.save_name + ".dbc"); write_file_or_throw(output, editor.text); diff --git a/tools/jotpluggler/layout_io.cc b/openpilot/tools/jotpluggler/layout_io.cc similarity index 100% rename from tools/jotpluggler/layout_io.cc rename to openpilot/tools/jotpluggler/layout_io.cc diff --git a/tools/jotpluggler/layouts/.gitignore b/openpilot/tools/jotpluggler/layouts/.gitignore similarity index 100% rename from tools/jotpluggler/layouts/.gitignore rename to openpilot/tools/jotpluggler/layouts/.gitignore diff --git a/tools/jotpluggler/layouts/CAN-bus-debug.json b/openpilot/tools/jotpluggler/layouts/CAN-bus-debug.json similarity index 100% rename from tools/jotpluggler/layouts/CAN-bus-debug.json rename to openpilot/tools/jotpluggler/layouts/CAN-bus-debug.json diff --git a/tools/jotpluggler/layouts/camera-timings.json b/openpilot/tools/jotpluggler/layouts/camera-timings.json similarity index 100% rename from tools/jotpluggler/layouts/camera-timings.json rename to openpilot/tools/jotpluggler/layouts/camera-timings.json diff --git a/tools/jotpluggler/layouts/cameras-and-map.json b/openpilot/tools/jotpluggler/layouts/cameras-and-map.json similarity index 100% rename from tools/jotpluggler/layouts/cameras-and-map.json rename to openpilot/tools/jotpluggler/layouts/cameras-and-map.json diff --git a/tools/jotpluggler/layouts/can-states.json b/openpilot/tools/jotpluggler/layouts/can-states.json similarity index 100% rename from tools/jotpluggler/layouts/can-states.json rename to openpilot/tools/jotpluggler/layouts/can-states.json diff --git a/tools/jotpluggler/layouts/controls_mismatch_debug.json b/openpilot/tools/jotpluggler/layouts/controls_mismatch_debug.json similarity index 100% rename from tools/jotpluggler/layouts/controls_mismatch_debug.json rename to openpilot/tools/jotpluggler/layouts/controls_mismatch_debug.json diff --git a/tools/jotpluggler/layouts/driver-monitoring-debug.json b/openpilot/tools/jotpluggler/layouts/driver-monitoring-debug.json similarity index 100% rename from tools/jotpluggler/layouts/driver-monitoring-debug.json rename to openpilot/tools/jotpluggler/layouts/driver-monitoring-debug.json diff --git a/tools/jotpluggler/layouts/gps.json b/openpilot/tools/jotpluggler/layouts/gps.json similarity index 100% rename from tools/jotpluggler/layouts/gps.json rename to openpilot/tools/jotpluggler/layouts/gps.json diff --git a/tools/jotpluggler/layouts/gps_vs_llk.json b/openpilot/tools/jotpluggler/layouts/gps_vs_llk.json similarity index 100% rename from tools/jotpluggler/layouts/gps_vs_llk.json rename to openpilot/tools/jotpluggler/layouts/gps_vs_llk.json diff --git a/tools/jotpluggler/layouts/locationd_debug.json b/openpilot/tools/jotpluggler/layouts/locationd_debug.json similarity index 100% rename from tools/jotpluggler/layouts/locationd_debug.json rename to openpilot/tools/jotpluggler/layouts/locationd_debug.json diff --git a/tools/jotpluggler/layouts/longitudinal.json b/openpilot/tools/jotpluggler/layouts/longitudinal.json similarity index 100% rename from tools/jotpluggler/layouts/longitudinal.json rename to openpilot/tools/jotpluggler/layouts/longitudinal.json diff --git a/tools/jotpluggler/layouts/max-torque-debug.json b/openpilot/tools/jotpluggler/layouts/max-torque-debug.json similarity index 100% rename from tools/jotpluggler/layouts/max-torque-debug.json rename to openpilot/tools/jotpluggler/layouts/max-torque-debug.json diff --git a/tools/jotpluggler/layouts/new-layout.json b/openpilot/tools/jotpluggler/layouts/new-layout.json similarity index 100% rename from tools/jotpluggler/layouts/new-layout.json rename to openpilot/tools/jotpluggler/layouts/new-layout.json diff --git a/tools/jotpluggler/layouts/system_lag_debug.json b/openpilot/tools/jotpluggler/layouts/system_lag_debug.json similarity index 100% rename from tools/jotpluggler/layouts/system_lag_debug.json rename to openpilot/tools/jotpluggler/layouts/system_lag_debug.json diff --git a/tools/jotpluggler/layouts/thermal_debug.json b/openpilot/tools/jotpluggler/layouts/thermal_debug.json similarity index 100% rename from tools/jotpluggler/layouts/thermal_debug.json rename to openpilot/tools/jotpluggler/layouts/thermal_debug.json diff --git a/tools/jotpluggler/layouts/torque-controller.json b/openpilot/tools/jotpluggler/layouts/torque-controller.json similarity index 100% rename from tools/jotpluggler/layouts/torque-controller.json rename to openpilot/tools/jotpluggler/layouts/torque-controller.json diff --git a/tools/jotpluggler/layouts/tuning.json b/openpilot/tools/jotpluggler/layouts/tuning.json similarity index 100% rename from tools/jotpluggler/layouts/tuning.json rename to openpilot/tools/jotpluggler/layouts/tuning.json diff --git a/tools/jotpluggler/layouts/ublox-debug.json b/openpilot/tools/jotpluggler/layouts/ublox-debug.json similarity index 100% rename from tools/jotpluggler/layouts/ublox-debug.json rename to openpilot/tools/jotpluggler/layouts/ublox-debug.json diff --git a/tools/jotpluggler/logs.cc b/openpilot/tools/jotpluggler/logs.cc similarity index 100% rename from tools/jotpluggler/logs.cc rename to openpilot/tools/jotpluggler/logs.cc diff --git a/tools/jotpluggler/main.cc b/openpilot/tools/jotpluggler/main.cc similarity index 100% rename from tools/jotpluggler/main.cc rename to openpilot/tools/jotpluggler/main.cc diff --git a/tools/jotpluggler/map.cc b/openpilot/tools/jotpluggler/map.cc similarity index 100% rename from tools/jotpluggler/map.cc rename to openpilot/tools/jotpluggler/map.cc diff --git a/tools/jotpluggler/map.h b/openpilot/tools/jotpluggler/map.h similarity index 100% rename from tools/jotpluggler/map.h rename to openpilot/tools/jotpluggler/map.h diff --git a/tools/jotpluggler/math_eval.py b/openpilot/tools/jotpluggler/math_eval.py similarity index 100% rename from tools/jotpluggler/math_eval.py rename to openpilot/tools/jotpluggler/math_eval.py diff --git a/tools/jotpluggler/plot.cc b/openpilot/tools/jotpluggler/plot.cc similarity index 100% rename from tools/jotpluggler/plot.cc rename to openpilot/tools/jotpluggler/plot.cc diff --git a/tools/jotpluggler/render.cc b/openpilot/tools/jotpluggler/render.cc similarity index 100% rename from tools/jotpluggler/render.cc rename to openpilot/tools/jotpluggler/render.cc diff --git a/tools/jotpluggler/runtime.cc b/openpilot/tools/jotpluggler/runtime.cc similarity index 98% rename from tools/jotpluggler/runtime.cc rename to openpilot/tools/jotpluggler/runtime.cc index 3247a5d01d..a1e47c7e8e 100644 --- a/tools/jotpluggler/runtime.cc +++ b/openpilot/tools/jotpluggler/runtime.cc @@ -1,13 +1,13 @@ #include "tools/jotpluggler/app.h" #include "tools/jotpluggler/common.h" -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/timing.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3_loader.h" #include "implot.h" -#include "libyuv.h" +#include "common/yuv.h" #include "msgq_repo/msgq/ipc.h" #include "tools/replay/framereader.h" @@ -1173,14 +1173,14 @@ struct CameraFeedView::Impl { result.width = reader->width; result.height = reader->height; result.rgba.resize(static_cast(result.width) * static_cast(result.height) * 4U, 0); - libyuv::NV12ToABGR(decode_buffer.y, - static_cast(decode_buffer.stride), - decode_buffer.uv, - static_cast(decode_buffer.stride), - result.rgba.data(), - result.width * 4, - result.width, - result.height); + yuv::nv12_to_rgba(decode_buffer.y, + static_cast(decode_buffer.stride), + decode_buffer.uv, + static_cast(decode_buffer.stride), + result.rgba.data(), + result.width * 4, + result.width, + result.height); result.success = true; result.decode_ms = std::chrono::duration(std::chrono::steady_clock::now() - decode_begin).count(); publish_result(*request, std::move(result)); @@ -1203,14 +1203,14 @@ struct CameraFeedView::Impl { .height = reader->height, }; prefetched.rgba.resize(static_cast(prefetched.width) * static_cast(prefetched.height) * 4U, 0); - libyuv::NV12ToABGR(decode_buffer.y, - static_cast(decode_buffer.stride), - decode_buffer.uv, - static_cast(decode_buffer.stride), - prefetched.rgba.data(), - prefetched.width * 4, - prefetched.width, - prefetched.height); + yuv::nv12_to_rgba(decode_buffer.y, + static_cast(decode_buffer.stride), + decode_buffer.uv, + static_cast(decode_buffer.stride), + prefetched.rgba.data(), + prefetched.width * 4, + prefetched.width, + prefetched.height); remember_cached_result(prefetched); } } diff --git a/tools/jotpluggler/session.cc b/openpilot/tools/jotpluggler/session.cc similarity index 100% rename from tools/jotpluggler/session.cc rename to openpilot/tools/jotpluggler/session.cc diff --git a/tools/jotpluggler/sidebar.cc b/openpilot/tools/jotpluggler/sidebar.cc similarity index 100% rename from tools/jotpluggler/sidebar.cc rename to openpilot/tools/jotpluggler/sidebar.cc diff --git a/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc similarity index 98% rename from tools/jotpluggler/sketch_layout.cc rename to openpilot/tools/jotpluggler/sketch_layout.cc index 2091280169..ee307653f6 100644 --- a/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -385,8 +385,8 @@ std::string detect_dbc_for_fingerprint(std::string_view car_fingerprint) { std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { - repo_root() / "opendbc" / "dbc", - repo_root() / "tools" / "jotpluggler" / "generated_dbcs", + repo_root() / "opendbc_repo" / "opendbc" / "dbc", + repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { for (const auto &entry : fs::directory_iterator(dbc_dir)) { @@ -407,8 +407,8 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { - repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), - repo_root() / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), + repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), + repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; } @@ -432,7 +432,7 @@ std::array parse_color(std::string_view color) { return out; } -uint8_t android_priority_to_level(uint8_t priority) { +uint8_t operating_system_priority_to_level(uint8_t priority) { switch (priority) { case 2: case 3: @@ -491,7 +491,7 @@ void append_timeline_entry(std::vector *timeline, double mono_tim }); } -double android_wall_time_seconds(uint64_t timestamp) { +double operating_system_wall_time_seconds(uint64_t timestamp) { if (timestamp == 0) return 0.0; if (timestamp > 1000000000000ULL) return static_cast(timestamp) / 1.0e9; if (timestamp > 1000000000ULL) return static_cast(timestamp) / 1.0e6; @@ -609,13 +609,13 @@ void append_log_event(cereal::Event::Which which, logs->push_back(std::move(entry)); break; } - case cereal::Event::Which::ANDROID_LOG: { - const auto android = event.getAndroidLog(); - auto entry = make_entry(LogOrigin::Android, android_priority_to_level(android.getPriority())); - entry.wall_time = android_wall_time_seconds(android.getTs()); - entry.source = android.hasTag() ? android.getTag().cStr() : "android"; - entry.message = android.hasMessage() ? android.getMessage().cStr() : std::string(); - entry.context = "pid=" + std::to_string(android.getPid()) + ", tid=" + std::to_string(android.getTid()); + case cereal::Event::Which::OPERATING_SYSTEM_LOG: { + const auto operating_system_log = event.getOperatingSystemLog(); + auto entry = make_entry(LogOrigin::OperatingSystem, operating_system_priority_to_level(operating_system_log.getPriority())); + entry.wall_time = operating_system_wall_time_seconds(operating_system_log.getTs()); + entry.source = operating_system_log.hasTag() ? operating_system_log.getTag().cStr() : "operating_system"; + entry.message = operating_system_log.hasMessage() ? operating_system_log.getMessage().cStr() : std::string(); + entry.context = "pid=" + std::to_string(operating_system_log.getPid()) + ", tid=" + std::to_string(operating_system_log.getTid()); if (!entry.message.empty()) { std::string err; if (const auto p = json11::Json::parse(entry.message, err); err.empty() && p.is_object()) { @@ -623,10 +623,10 @@ void append_log_event(cereal::Event::Which which, if (p["SYSLOG_IDENTIFIER"].is_string() && !p["SYSLOG_IDENTIFIER"].string_value().empty()) entry.source = p["SYSLOG_IDENTIFIER"].string_value(); if (auto pri = json_int_value(p["PRIORITY"]); pri.has_value()) - entry.level = android_priority_to_level(*pri); + entry.level = operating_system_priority_to_level(*pri); if (auto ts = json_u64_value(p["__REALTIME_TIMESTAMP"]); ts.has_value()) - entry.wall_time = android_wall_time_seconds(*ts); - entry.context = format_journal_context(p, android.getPid(), android.getTid()); + entry.wall_time = operating_system_wall_time_seconds(*ts); + entry.context = format_journal_context(p, operating_system_log.getPid(), operating_system_log.getTid()); } } logs->push_back(std::move(entry)); diff --git a/tools/jotpluggler/stream.cc b/openpilot/tools/jotpluggler/stream.cc similarity index 100% rename from tools/jotpluggler/stream.cc rename to openpilot/tools/jotpluggler/stream.cc diff --git a/tools/jotpluggler/util.cc b/openpilot/tools/jotpluggler/util.cc similarity index 100% rename from tools/jotpluggler/util.cc rename to openpilot/tools/jotpluggler/util.cc diff --git a/tools/jotpluggler/util.h b/openpilot/tools/jotpluggler/util.h similarity index 100% rename from tools/jotpluggler/util.h rename to openpilot/tools/jotpluggler/util.h diff --git a/tools/joystick/README.md b/openpilot/tools/joystick/README.md similarity index 92% rename from tools/joystick/README.md rename to openpilot/tools/joystick/README.md index eb67060ca8..3ce308927c 100644 --- a/tools/joystick/README.md +++ b/openpilot/tools/joystick/README.md @@ -14,7 +14,7 @@ The car must be off, and openpilot must be offroad before starting `joystick_con SSH into your comma device and start joystick_control with the following command: ```shell -tools/joystick/joystick_control.py --keyboard +openpilot/tools/joystick/joystick_control.py --keyboard ``` The available buttons and axes will print showing their key mappings. In general, the WASD keys control gas and brakes and steering torque in 5% increments. @@ -36,13 +36,13 @@ In order to use a joystick over the network, we need to run joystick_control loc 3. Run bridge with your laptop's IP address. This republishes the `testJoystick` packets sent from your laptop so that openpilot can receive them: ```shell # on your comma device - cereal/messaging/bridge {LAPTOP_IP} testJoystick + openpilot/cereal/messaging/bridge {LAPTOP_IP} testJoystick ``` 4. Start joystick_control on your laptop in ZMQ mode. ```shell # on your laptop export ZMQ=1 - tools/joystick/joystick_control.py + openpilot/tools/joystick/joystick_control.py ``` --- diff --git a/tools/joystick/joystick_control.py b/openpilot/tools/joystick/joystick_control.py similarity index 96% rename from tools/joystick/joystick_control.py rename to openpilot/tools/joystick/joystick_control.py index d9d4f0156f..9a39d564db 100755 --- a/tools/joystick/joystick_control.py +++ b/openpilot/tools/joystick/joystick_control.py @@ -5,7 +5,7 @@ import threading import numpy as np from inputs import UnpluggedError, get_gamepad -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper from openpilot.common.hardware import HARDWARE @@ -140,7 +140,7 @@ if __name__ == '__main__': print('- `R`: Resets axes') print('- `C`: Cancel cruise control') else: - print('Using joystick, make sure to run cereal/messaging/bridge on your device if running over the network!') + print('Using joystick, make sure to run openpilot/cereal/messaging/bridge on your device if running over the network!') print('If not running on a comma device, the mapping may need to be adjusted.') joystick = Keyboard() if args.keyboard else Joystick() diff --git a/tools/joystick/joystickd.py b/openpilot/tools/joystick/joystickd.py similarity index 97% rename from tools/joystick/joystickd.py rename to openpilot/tools/joystick/joystickd.py index 789dad5623..a1c00746b6 100755 --- a/tools/joystick/joystickd.py +++ b/openpilot/tools/joystick/joystickd.py @@ -3,7 +3,8 @@ import math import numpy as np -from cereal import messaging, car +from openpilot.cereal import messaging +from opendbc.car.structs import car from opendbc.car.vehicle_model import VehicleModel from openpilot.common.realtime import DT_CTRL, Ratekeeper from openpilot.common.params import Params diff --git a/tools/lateral_maneuvers/.gitignore b/openpilot/tools/lateral_maneuvers/.gitignore similarity index 100% rename from tools/lateral_maneuvers/.gitignore rename to openpilot/tools/lateral_maneuvers/.gitignore diff --git a/tools/lateral_maneuvers/README.md b/openpilot/tools/lateral_maneuvers/README.md similarity index 95% rename from tools/lateral_maneuvers/README.md rename to openpilot/tools/lateral_maneuvers/README.md index 3a54bc7409..7a4c381b15 100644 --- a/tools/lateral_maneuvers/README.md +++ b/openpilot/tools/lateral_maneuvers/README.md @@ -28,7 +28,7 @@ Test your vehicle's lateral control tuning with this tool. The tool will test th 8. Gather the route ID and then run the report generator. The file will be exported to the same directory: ```sh - $ python tools/lateral_maneuvers/generate_report.py 98395b7c5b27882e/000001cc--5a73bde686 + $ python openpilot/tools/lateral_maneuvers/generate_report.py 98395b7c5b27882e/000001cc--5a73bde686 processing report for KIA_EV6 plotting maneuver: step right 20mph, runs: 3 diff --git a/tools/lateral_maneuvers/generate_report.py b/openpilot/tools/lateral_maneuvers/generate_report.py similarity index 99% rename from tools/lateral_maneuvers/generate_report.py rename to openpilot/tools/lateral_maneuvers/generate_report.py index 5db486a70d..e26690e2da 100755 --- a/tools/lateral_maneuvers/generate_report.py +++ b/openpilot/tools/lateral_maneuvers/generate_report.py @@ -11,7 +11,7 @@ from pathlib import Path import matplotlib.pyplot as plt from openpilot.common.utils import tabulate -from cereal import car +from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.selfdrive.controls.lib.latcontrol_torque import LP_FILTER_CUTOFF_HZ from openpilot.tools.lib.logreader import LogReader diff --git a/tools/lateral_maneuvers/lateral_maneuversd.py b/openpilot/tools/lateral_maneuvers/lateral_maneuversd.py similarity index 98% rename from tools/lateral_maneuvers/lateral_maneuversd.py rename to openpilot/tools/lateral_maneuvers/lateral_maneuversd.py index 1cc2d3560e..ed07c896f9 100755 --- a/tools/lateral_maneuvers/lateral_maneuversd.py +++ b/openpilot/tools/lateral_maneuvers/lateral_maneuversd.py @@ -2,7 +2,8 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging, car +from openpilot.cereal import messaging +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/tools/lib/README.md b/openpilot/tools/lib/README.md similarity index 87% rename from tools/lib/README.md rename to openpilot/tools/lib/README.md index af1ad0de22..17e24816ec 100644 --- a/tools/lib/README.md +++ b/openpilot/tools/lib/README.md @@ -1,6 +1,6 @@ ## LogReader -Route is a class for conveniently accessing all the [logs](/system/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. +Route is a class for conveniently accessing all the [logs](/openpilot/system/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. ```python from openpilot.tools.lib.route import Route diff --git a/tools/__init__.py b/openpilot/tools/lib/__init__.py similarity index 100% rename from tools/__init__.py rename to openpilot/tools/lib/__init__.py diff --git a/tools/lib/api.py b/openpilot/tools/lib/api.py similarity index 97% rename from tools/lib/api.py rename to openpilot/tools/lib/api.py index f84fe75869..7fca9b320f 100644 --- a/tools/lib/api.py +++ b/openpilot/tools/lib/api.py @@ -20,7 +20,7 @@ class CommaApi: resp_json = resp.json() if isinstance(resp_json, dict) and resp_json.get('error'): if resp.status_code in [401, 403]: - raise UnauthorizedError('Unauthorized. Authenticate with tools/lib/auth.py') + raise UnauthorizedError('Unauthorized. Authenticate with openpilot/tools/lib/auth.py') e = APIError(str(resp.status_code) + ":" + resp_json.get('description', str(resp_json['error']))) e.status_code = resp.status_code diff --git a/tools/lib/auth.py b/openpilot/tools/lib/auth.py similarity index 100% rename from tools/lib/auth.py rename to openpilot/tools/lib/auth.py diff --git a/tools/lib/auth_config.py b/openpilot/tools/lib/auth_config.py similarity index 100% rename from tools/lib/auth_config.py rename to openpilot/tools/lib/auth_config.py diff --git a/tools/lib/azure_container.py b/openpilot/tools/lib/azure_container.py similarity index 100% rename from tools/lib/azure_container.py rename to openpilot/tools/lib/azure_container.py diff --git a/tools/lib/bootlog.py b/openpilot/tools/lib/bootlog.py similarity index 100% rename from tools/lib/bootlog.py rename to openpilot/tools/lib/bootlog.py diff --git a/tools/lib/cache.py b/openpilot/tools/lib/cache.py similarity index 100% rename from tools/lib/cache.py rename to openpilot/tools/lib/cache.py diff --git a/tools/lib/comma_car_segments.py b/openpilot/tools/lib/comma_car_segments.py similarity index 100% rename from tools/lib/comma_car_segments.py rename to openpilot/tools/lib/comma_car_segments.py diff --git a/tools/lib/exceptions.py b/openpilot/tools/lib/exceptions.py similarity index 100% rename from tools/lib/exceptions.py rename to openpilot/tools/lib/exceptions.py diff --git a/tools/lib/file_downloader.py b/openpilot/tools/lib/file_downloader.py similarity index 100% rename from tools/lib/file_downloader.py rename to openpilot/tools/lib/file_downloader.py diff --git a/tools/lib/file_sources.py b/openpilot/tools/lib/file_sources.py similarity index 100% rename from tools/lib/file_sources.py rename to openpilot/tools/lib/file_sources.py diff --git a/tools/lib/filereader.py b/openpilot/tools/lib/filereader.py similarity index 100% rename from tools/lib/filereader.py rename to openpilot/tools/lib/filereader.py diff --git a/tools/lib/framereader.py b/openpilot/tools/lib/framereader.py similarity index 100% rename from tools/lib/framereader.py rename to openpilot/tools/lib/framereader.py diff --git a/tools/lib/github_utils.py b/openpilot/tools/lib/github_utils.py similarity index 100% rename from tools/lib/github_utils.py rename to openpilot/tools/lib/github_utils.py diff --git a/tools/lib/helpers.py b/openpilot/tools/lib/helpers.py similarity index 100% rename from tools/lib/helpers.py rename to openpilot/tools/lib/helpers.py diff --git a/tools/lib/kbhit.py b/openpilot/tools/lib/kbhit.py similarity index 100% rename from tools/lib/kbhit.py rename to openpilot/tools/lib/kbhit.py diff --git a/tools/lib/live_logreader.py b/openpilot/tools/lib/live_logreader.py similarity index 87% rename from tools/lib/live_logreader.py rename to openpilot/tools/lib/live_logreader.py index edc4ac1611..20f8c3502c 100644 --- a/tools/lib/live_logreader.py +++ b/openpilot/tools/lib/live_logreader.py @@ -1,6 +1,6 @@ import os -from cereal import log as capnp_log, messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log as capnp_log, messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.logreader import LogIterable, RawLogIterable diff --git a/tools/lib/log_time_series.py b/openpilot/tools/lib/log_time_series.py similarity index 100% rename from tools/lib/log_time_series.py rename to openpilot/tools/lib/log_time_series.py diff --git a/tools/lib/logreader.py b/openpilot/tools/lib/logreader.py similarity index 99% rename from tools/lib/logreader.py rename to openpilot/tools/lib/logreader.py index 9696c8524d..805e411b53 100755 --- a/tools/lib/logreader.py +++ b/openpilot/tools/lib/logreader.py @@ -15,7 +15,7 @@ import zstandard as zstd from collections.abc import Iterable, Iterator from urllib.parse import parse_qs, urlparse -from cereal import log as capnp_log +from openpilot.cereal import log as capnp_log from openpilot.common.swaglog import cloudlog from openpilot.tools.lib.filereader import FileReader from openpilot.tools.lib.file_sources import comma_api_source, internal_source, openpilotci_source, comma_car_segments_source, Source diff --git a/tools/lib/openpilotci.py b/openpilot/tools/lib/openpilotci.py similarity index 100% rename from tools/lib/openpilotci.py rename to openpilot/tools/lib/openpilotci.py diff --git a/tools/lib/openpilotcontainers.py b/openpilot/tools/lib/openpilotcontainers.py similarity index 100% rename from tools/lib/openpilotcontainers.py rename to openpilot/tools/lib/openpilotcontainers.py diff --git a/tools/lib/route.py b/openpilot/tools/lib/route.py similarity index 100% rename from tools/lib/route.py rename to openpilot/tools/lib/route.py diff --git a/tools/lib/sanitizer.py b/openpilot/tools/lib/sanitizer.py similarity index 100% rename from tools/lib/sanitizer.py rename to openpilot/tools/lib/sanitizer.py diff --git a/tools/lib/__init__.py b/openpilot/tools/lib/tests/__init__.py similarity index 100% rename from tools/lib/__init__.py rename to openpilot/tools/lib/tests/__init__.py diff --git a/tools/lib/tests/test_caching.py b/openpilot/tools/lib/tests/test_caching.py similarity index 100% rename from tools/lib/tests/test_caching.py rename to openpilot/tools/lib/tests/test_caching.py diff --git a/tools/lib/tests/test_comma_car_segments.py b/openpilot/tools/lib/tests/test_comma_car_segments.py similarity index 100% rename from tools/lib/tests/test_comma_car_segments.py rename to openpilot/tools/lib/tests/test_comma_car_segments.py diff --git a/tools/lib/tests/test_logreader.py b/openpilot/tools/lib/tests/test_logreader.py similarity index 99% rename from tools/lib/tests/test_logreader.py rename to openpilot/tools/lib/tests/test_logreader.py index 123f142383..a27a348d9e 100644 --- a/tools/lib/tests/test_logreader.py +++ b/openpilot/tools/lib/tests/test_logreader.py @@ -9,7 +9,7 @@ import requests from openpilot.common.parameterized import parameterized -from cereal import log as capnp_log +from openpilot.cereal import log as capnp_log from openpilot.tools.lib.logreader import LogsUnavailable, LogIterable, LogReader, parse_indirect, ReadMode from openpilot.tools.lib.file_sources import comma_api_source, InternalUnavailableException from openpilot.tools.lib.route import SegmentRange diff --git a/tools/lib/tests/test_route_library.py b/openpilot/tools/lib/tests/test_route_library.py similarity index 100% rename from tools/lib/tests/test_route_library.py rename to openpilot/tools/lib/tests/test_route_library.py diff --git a/tools/lib/url_file.py b/openpilot/tools/lib/url_file.py similarity index 100% rename from tools/lib/url_file.py rename to openpilot/tools/lib/url_file.py diff --git a/tools/lib/vidindex.py b/openpilot/tools/lib/vidindex.py similarity index 100% rename from tools/lib/vidindex.py rename to openpilot/tools/lib/vidindex.py diff --git a/tools/longitudinal_maneuvers/.gitignore b/openpilot/tools/longitudinal_maneuvers/.gitignore similarity index 100% rename from tools/longitudinal_maneuvers/.gitignore rename to openpilot/tools/longitudinal_maneuvers/.gitignore diff --git a/tools/longitudinal_maneuvers/README.md b/openpilot/tools/longitudinal_maneuvers/README.md similarity index 95% rename from tools/longitudinal_maneuvers/README.md rename to openpilot/tools/longitudinal_maneuvers/README.md index 643af7fd82..96b989b555 100644 --- a/tools/longitudinal_maneuvers/README.md +++ b/openpilot/tools/longitudinal_maneuvers/README.md @@ -35,7 +35,7 @@ Test your vehicle's longitudinal control tuning with this tool. The tool will te 8. Gather the route ID and then run the report generator. The file will be exported to the same directory: ```sh - $ python tools/longitudinal_maneuvers/generate_report.py 57048cfce01d9625/0000010e--5b26bc3be7 'pcm accel compensation' + $ python openpilot/tools/longitudinal_maneuvers/generate_report.py 57048cfce01d9625/0000010e--5b26bc3be7 'pcm accel compensation' processing report for LEXUS_ES_TSS2 plotting maneuver: start from stop, runs: 4 diff --git a/tools/longitudinal_maneuvers/generate_report.py b/openpilot/tools/longitudinal_maneuvers/generate_report.py similarity index 100% rename from tools/longitudinal_maneuvers/generate_report.py rename to openpilot/tools/longitudinal_maneuvers/generate_report.py diff --git a/tools/longitudinal_maneuvers/maneuver_helpers.py b/openpilot/tools/longitudinal_maneuvers/maneuver_helpers.py similarity index 100% rename from tools/longitudinal_maneuvers/maneuver_helpers.py rename to openpilot/tools/longitudinal_maneuvers/maneuver_helpers.py diff --git a/tools/longitudinal_maneuvers/maneuversd.py b/openpilot/tools/longitudinal_maneuvers/maneuversd.py similarity index 98% rename from tools/longitudinal_maneuvers/maneuversd.py rename to openpilot/tools/longitudinal_maneuvers/maneuversd.py index 48e7384cd3..1ad5370f20 100755 --- a/tools/longitudinal_maneuvers/maneuversd.py +++ b/openpilot/tools/longitudinal_maneuvers/maneuversd.py @@ -2,7 +2,8 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging, car +from openpilot.cereal import messaging +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py b/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py similarity index 95% rename from tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py rename to openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py index ae3fee7355..6b711a0847 100644 --- a/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py +++ b/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py @@ -25,7 +25,7 @@ def get_html_from_results(results, labels, AXIS): plt.close(fig) return fig_buffer.getvalue() + '
' -def generate_mpc_tuning_report(): +def generate_mpc_tuning_report(e2e=False): htmls = [] results = {} @@ -42,6 +42,7 @@ def generate_mpc_tuning_report(): cruise_values=[100, 100], prob_lead_values=[1.0, 1.0], breakpoints=[1., 11], + e2e=e2e, ) valid, results[lead_accel] = man.evaluate() labels.append(f'{lead_accel} m/s^2 lead acceleration') @@ -63,6 +64,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=140., speed_lead_values=[0.0, 0.], breakpoints=[0., 30.], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s approach speed') @@ -85,6 +87,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=desired_follow_distance(speed, speed), speed_lead_values=[speed, speed, speed - oscil, speed + oscil, speed - oscil, speed + oscil, speed - oscil], breakpoints=[0.,2., 5, 8, 15, 18, 25.], + e2e=e2e, ) valid, results[oscil] = man.evaluate() labels.append(f'{oscil} m/s oscillation size') @@ -112,6 +115,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=desired_follow_distance(speed, speed), speed_lead_values=lead_speeds, breakpoints=bps, + e2e=e2e, ) valid, results[oscil] = man.evaluate() labels.append(f'{oscil} m/s oscillation size') @@ -134,6 +138,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=distance, speed_lead_values=[30.0], breakpoints=[0.], + e2e=e2e, ) valid, results[distance] = man.evaluate() labels.append(f'{distance} m initial distance') @@ -155,6 +160,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=distance, speed_lead_values=[20.0], breakpoints=[0.], + e2e=e2e, ) valid, results[distance] = man.evaluate() labels.append(f'{distance} m initial distance') @@ -177,6 +183,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=60.0, speed_lead_values=[30.0, 30.0, 0.0], breakpoints=[0., 5., 5 + stop_time], + e2e=e2e, ) valid, results[stop_time] = man.evaluate() labels.append(f'{stop_time} seconds stop time') @@ -200,6 +207,7 @@ def generate_mpc_tuning_report(): speed_lead_values=[speed, speed, speed], prob_lead_values=[0.0, 0.0, 1.0], breakpoints=[0., 5.0, 5.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -222,6 +230,7 @@ def generate_mpc_tuning_report(): speed_lead_values=[0.0, 0.0, speed], prob_lead_values=[1.0, 1.0, 1.0], breakpoints=[0., 1.0, speed/2], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -245,6 +254,7 @@ def generate_mpc_tuning_report(): cruise_values=[0.0, speed], prob_lead_values=[0.0, 0.0], breakpoints=[1., 1.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -268,6 +278,7 @@ def generate_mpc_tuning_report(): cruise_values=[speed, 10.0], prob_lead_values=[0.0, 0.0], breakpoints=[1., 1.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -279,12 +290,14 @@ def generate_mpc_tuning_report(): return htmls if __name__ == '__main__': - htmls = generate_mpc_tuning_report() + e2e = '--e2e' in sys.argv + file_name = 'long_mpc_tune_report.html' + for arg in sys.argv[1:]: + if not arg.startswith('-'): + file_name = arg + break - if len(sys.argv) < 2: - file_name = 'long_mpc_tune_report.html' - else: - file_name = sys.argv[1] + htmls = generate_mpc_tuning_report(e2e=e2e) with open(file_name, 'w') as f: f.write(markdown.markdown('# MPC longitudinal tuning report')) diff --git a/tools/plotjuggler/README.md b/openpilot/tools/plotjuggler/README.md similarity index 95% rename from tools/plotjuggler/README.md rename to openpilot/tools/plotjuggler/README.md index 3249971bfc..efccbdc0bd 100644 --- a/tools/plotjuggler/README.md +++ b/openpilot/tools/plotjuggler/README.md @@ -6,7 +6,7 @@ Once you've [set up the openpilot environment](../README.md), this command will download PlotJuggler and install our plugins: -`cd tools/plotjuggler && ./juggle.py --install` +`cd openpilot/tools/plotjuggler && ./juggle.py --install` ## Usage @@ -51,7 +51,7 @@ Example using segment range: Explore live data from your car! Follow these steps to stream from your comma device to your laptop: - Enable wifi tethering on your comma device -- [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and run `cd /data/openpilot && ./cereal/messaging/bridge` +- [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and run `cd /data/openpilot && ./openpilot/cereal/messaging/bridge` - On your laptop, connect to the device's wifi hotspot - Start PlotJuggler with `ZMQ=1 ./juggle.py --stream`, find the `Cereal Subscriber` plugin in the dropdown under Streaming, and click `Start`. diff --git a/tools/plotjuggler/juggle.py b/openpilot/tools/plotjuggler/juggle.py similarity index 83% rename from tools/plotjuggler/juggle.py rename to openpilot/tools/plotjuggler/juggle.py index a31c62c940..6ddbdbeb3e 100755 --- a/tools/plotjuggler/juggle.py +++ b/openpilot/tools/plotjuggler/juggle.py @@ -9,7 +9,6 @@ import tempfile import requests import argparse from functools import partial - from opendbc.car.fingerprints import MIGRATION from openpilot.common.basedir import BASEDIR from openpilot.common.swaglog import cloudlog @@ -34,7 +33,7 @@ def print_jotpluggler_banner(): reset = "\033[0m" if purple else "" print(f"{purple}+-------------------------------------------------------------+{reset}") print(f"{purple}|{reset} JotPluggler is the future! Try it like this: {purple}|{reset}") - print(f"{purple}|{reset} ./tools/jotpluggler/jotpluggler --demo --layout tuning {purple}|{reset}") + print(f"{purple}|{reset} ./openpilot/tools/jotpluggler/jotpluggler --demo --layout tuning {purple}|{reset}") print(f"{purple}|{reset} {purple}|{reset}") print(f"{purple}|{reset} PlotJuggler will be deleted soon. {purple}|{reset}") print(f"{purple}|{reset} Missing a feature? Open an issue or post in #dev-openpilot. {purple}|{reset}") @@ -70,7 +69,6 @@ def get_plotjuggler_version(): def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, platform=None): env = os.environ.copy() - env["BASEDIR"] = BASEDIR env["PATH"] = f"{INSTALL_DIR}:{os.getenv('PATH', '')}" if dbc: if os.path.exists(dbc): @@ -86,7 +84,21 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl extra_args += f" --window_title \"{route_or_segment_name}{f' ({platform})' if platform is not None else ''}\"" cmd = f'{PLOTJUGGLER_BIN} --buffer_size {MAX_STREAMING_BUFFER_SIZE} --plugin_folders {INSTALL_DIR}{extra_args}' - subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) + with tempfile.TemporaryDirectory() as schema_root: + tmp_cereal = os.path.join(schema_root, "cereal") + os.mkdir(tmp_cereal) + for schema in ("log.capnp", "deprecated.capnp", "custom.capnp"): + with open(os.path.join(BASEDIR, "openpilot", "cereal", schema)) as src: + contents = src.read() + contents = contents.replace('import "/include/c++.capnp"', 'import "./include/c++.capnp"') + contents = contents.replace('import "/car.capnp"', 'import "car.capnp"') + with open(os.path.join(tmp_cereal, schema), "w") as dst: + dst.write(contents) + os.symlink(os.path.join(BASEDIR, "openpilot", "cereal", "include"), os.path.join(tmp_cereal, "include"), target_is_directory=True) + os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "car.capnp"), os.path.join(tmp_cereal, "car.capnp")) + os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc"), os.path.join(schema_root, "opendbc"), target_is_directory=True) + env["BASEDIR"] = schema_root + subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) def process(can, lr): diff --git a/tools/plotjuggler/layouts/CAN-bus-debug.xml b/openpilot/tools/plotjuggler/layouts/CAN-bus-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/CAN-bus-debug.xml rename to openpilot/tools/plotjuggler/layouts/CAN-bus-debug.xml diff --git a/tools/plotjuggler/layouts/camera-timings.xml b/openpilot/tools/plotjuggler/layouts/camera-timings.xml similarity index 100% rename from tools/plotjuggler/layouts/camera-timings.xml rename to openpilot/tools/plotjuggler/layouts/camera-timings.xml diff --git a/tools/plotjuggler/layouts/can-states.xml b/openpilot/tools/plotjuggler/layouts/can-states.xml similarity index 100% rename from tools/plotjuggler/layouts/can-states.xml rename to openpilot/tools/plotjuggler/layouts/can-states.xml diff --git a/tools/plotjuggler/layouts/controls_mismatch_debug.xml b/openpilot/tools/plotjuggler/layouts/controls_mismatch_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/controls_mismatch_debug.xml rename to openpilot/tools/plotjuggler/layouts/controls_mismatch_debug.xml diff --git a/tools/plotjuggler/layouts/gps.xml b/openpilot/tools/plotjuggler/layouts/gps.xml similarity index 100% rename from tools/plotjuggler/layouts/gps.xml rename to openpilot/tools/plotjuggler/layouts/gps.xml diff --git a/tools/plotjuggler/layouts/gps_vs_llk.xml b/openpilot/tools/plotjuggler/layouts/gps_vs_llk.xml similarity index 100% rename from tools/plotjuggler/layouts/gps_vs_llk.xml rename to openpilot/tools/plotjuggler/layouts/gps_vs_llk.xml diff --git a/tools/plotjuggler/layouts/locationd_debug.xml b/openpilot/tools/plotjuggler/layouts/locationd_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/locationd_debug.xml rename to openpilot/tools/plotjuggler/layouts/locationd_debug.xml diff --git a/tools/plotjuggler/layouts/longitudinal.xml b/openpilot/tools/plotjuggler/layouts/longitudinal.xml similarity index 100% rename from tools/plotjuggler/layouts/longitudinal.xml rename to openpilot/tools/plotjuggler/layouts/longitudinal.xml diff --git a/tools/plotjuggler/layouts/max-torque-debug.xml b/openpilot/tools/plotjuggler/layouts/max-torque-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/max-torque-debug.xml rename to openpilot/tools/plotjuggler/layouts/max-torque-debug.xml diff --git a/tools/plotjuggler/layouts/system_lag_debug.xml b/openpilot/tools/plotjuggler/layouts/system_lag_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/system_lag_debug.xml rename to openpilot/tools/plotjuggler/layouts/system_lag_debug.xml diff --git a/tools/plotjuggler/layouts/thermal_debug.xml b/openpilot/tools/plotjuggler/layouts/thermal_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/thermal_debug.xml rename to openpilot/tools/plotjuggler/layouts/thermal_debug.xml diff --git a/tools/plotjuggler/layouts/torque-controller.xml b/openpilot/tools/plotjuggler/layouts/torque-controller.xml similarity index 100% rename from tools/plotjuggler/layouts/torque-controller.xml rename to openpilot/tools/plotjuggler/layouts/torque-controller.xml diff --git a/tools/plotjuggler/layouts/tuning.xml b/openpilot/tools/plotjuggler/layouts/tuning.xml similarity index 100% rename from tools/plotjuggler/layouts/tuning.xml rename to openpilot/tools/plotjuggler/layouts/tuning.xml diff --git a/tools/plotjuggler/layouts/ublox-debug.xml b/openpilot/tools/plotjuggler/layouts/ublox-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/ublox-debug.xml rename to openpilot/tools/plotjuggler/layouts/ublox-debug.xml diff --git a/tools/plotjuggler/test_plotjuggler.py b/openpilot/tools/plotjuggler/test_plotjuggler.py similarity index 96% rename from tools/plotjuggler/test_plotjuggler.py rename to openpilot/tools/plotjuggler/test_plotjuggler.py index 26bad25c3e..d55aafe9be 100644 --- a/tools/plotjuggler/test_plotjuggler.py +++ b/openpilot/tools/plotjuggler/test_plotjuggler.py @@ -11,7 +11,7 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.timeout import Timeout from openpilot.tools.plotjuggler.juggle import DEMO_ROUTE, install -PJ_DIR = os.path.join(BASEDIR, "tools/plotjuggler") +PJ_DIR = os.path.join(BASEDIR, "openpilot/tools/plotjuggler") class TestPlotJuggler: diff --git a/tools/replay/.gitignore b/openpilot/tools/replay/.gitignore similarity index 100% rename from tools/replay/.gitignore rename to openpilot/tools/replay/.gitignore diff --git a/tools/replay/README.md b/openpilot/tools/replay/README.md similarity index 84% rename from tools/replay/README.md rename to openpilot/tools/replay/README.md index d2beda9940..108df08935 100644 --- a/tools/replay/README.md +++ b/openpilot/tools/replay/README.md @@ -8,7 +8,7 @@ Before starting a replay, you need to authenticate with your comma account using ```bash # Authenticate to access routes from your comma account: -python3 tools/lib/auth.py +python3 openpilot/tools/lib/auth.py ``` ## Replay a Remote Route @@ -16,13 +16,13 @@ You can replay a route from your comma account by specifying the route name. ```bash # Start a replay with a specific route: -tools/replay/replay +openpilot/tools/replay/replay # Example: -tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496' +openpilot/tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496' # Replay the default demo route: -tools/replay/replay --demo +openpilot/tools/replay/replay --demo ``` ## Replay a Local Route @@ -30,14 +30,14 @@ To replay a route stored locally on your machine, specify the route name and pro ```bash # Replay a local route -tools/replay/replay --data_dir="/path_to/route" +openpilot/tools/replay/replay --data_dir="/path_to/route" # Example: # If you have a local route stored at /path_to_routes with segments like: # 5beb9b58bd12b691/0000010a--a51155e496--0 # 5beb9b58bd12b691/0000010a--a51155e496--1 # You can replay it like this: -tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" --data_dir="/path_to_routes" +openpilot/tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" --data_dir="/path_to_routes" ``` ## Send Messages via ZMQ @@ -45,15 +45,15 @@ By default, replay sends messages via MSGQ. To switch to ZMQ, set the ZMQ enviro ```bash # Start replay and send messages via ZMQ: -ZMQ=1 tools/replay/replay +ZMQ=1 openpilot/tools/replay/replay ``` ## Usage For more information on available options and arguments, use the help command: ``` bash -$ tools/replay/replay -h -Usage: tools/replay/replay [options] route +$ openpilot/tools/replay/replay -h +Usage: openpilot/tools/replay/replay [options] route Mock openpilot components by publishing logged messages. Options: @@ -87,16 +87,16 @@ Arguments: To visualize the replay within the openpilot UI, run the following commands: ```bash -tools/replay/replay -cd selfdrive/ui && ./ui.py +openpilot/tools/replay/replay +cd openpilot/selfdrive/ui && ./ui.py ``` ## Work with plotjuggler If you want to use replay with plotjuggler, you can stream messages by running: ```bash -tools/replay/replay -tools/plotjuggler/juggle.py --stream +openpilot/tools/replay/replay +openpilot/tools/plotjuggler/juggle.py --stream ``` ## watch3 @@ -107,10 +107,10 @@ simply replay a route using the `--dcam` and `--ecam` flags: ```bash # start a replay -cd tools/replay && ./replay --demo --dcam --ecam +cd openpilot/tools/replay && ./replay --demo --dcam --ecam # then start watch3 -cd selfdrive/ui && ./watch3.py +cd openpilot/selfdrive/ui && ./watch3.py ``` ![](https://i.imgur.com/IeaOdAb.png) diff --git a/tools/replay/SConscript b/openpilot/tools/replay/SConscript similarity index 82% rename from tools/replay/SConscript rename to openpilot/tools/replay/SConscript index d047415f58..643de97bb9 100644 --- a/tools/replay/SConscript +++ b/openpilot/tools/replay/SConscript @@ -1,4 +1,4 @@ -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'ffmpeg_libs') replay_env = env.Clone() replay_env['CCFLAGS'] += ['-Wno-deprecated-declarations'] @@ -12,9 +12,7 @@ if arch != "Darwin": replay_lib_src.append("qcom_decoder.cc") replay_lib = replay_env.Library("replay", replay_lib_src, LIBS=base_libs, FRAMEWORKS=base_frameworks) Export('replay_lib') -replay_libs = [replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'ncurses'] + base_libs -if arch != "Darwin": - replay_libs += ['va', 'va-drm', 'drm'] +replay_libs = [replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'ncurses'] + base_libs replay_env.Program("replay", ["main.cc"], LIBS=replay_libs, FRAMEWORKS=base_frameworks) if GetOption('extras'): diff --git a/tools/lib/tests/__init__.py b/openpilot/tools/replay/__init__.py similarity index 100% rename from tools/lib/tests/__init__.py rename to openpilot/tools/replay/__init__.py diff --git a/tools/replay/camera.cc b/openpilot/tools/replay/camera.cc similarity index 100% rename from tools/replay/camera.cc rename to openpilot/tools/replay/camera.cc diff --git a/tools/replay/camera.h b/openpilot/tools/replay/camera.h similarity index 100% rename from tools/replay/camera.h rename to openpilot/tools/replay/camera.h diff --git a/tools/replay/can_replay.py b/openpilot/tools/replay/can_replay.py similarity index 100% rename from tools/replay/can_replay.py rename to openpilot/tools/replay/can_replay.py diff --git a/tools/replay/consoleui.cc b/openpilot/tools/replay/consoleui.cc similarity index 100% rename from tools/replay/consoleui.cc rename to openpilot/tools/replay/consoleui.cc diff --git a/tools/replay/consoleui.h b/openpilot/tools/replay/consoleui.h similarity index 100% rename from tools/replay/consoleui.h rename to openpilot/tools/replay/consoleui.h diff --git a/tools/replay/filereader.cc b/openpilot/tools/replay/filereader.cc similarity index 100% rename from tools/replay/filereader.cc rename to openpilot/tools/replay/filereader.cc diff --git a/tools/replay/filereader.h b/openpilot/tools/replay/filereader.h similarity index 100% rename from tools/replay/filereader.h rename to openpilot/tools/replay/filereader.h diff --git a/tools/replay/framereader.cc b/openpilot/tools/replay/framereader.cc similarity index 96% rename from tools/replay/framereader.cc rename to openpilot/tools/replay/framereader.cc index 52db658add..7c6f144148 100644 --- a/tools/replay/framereader.cc +++ b/openpilot/tools/replay/framereader.cc @@ -6,7 +6,7 @@ #include #include "common/util.h" -#include "libyuv.h" +#include "common/yuv.h" #include "tools/replay/py_downloader.h" #include "tools/replay/util.h" #include "common/hardware/hw.h" @@ -258,12 +258,12 @@ bool FFmpegVideoDecoder::copyBuffer(AVFrame *f, VisionBuf *buf) { memcpy(buf->uv + i*buf->stride, f->data[1] + i*f->linesize[1], width); } } else { - libyuv::I420ToNV12(f->data[0], f->linesize[0], - f->data[1], f->linesize[1], - f->data[2], f->linesize[2], - buf->y, buf->stride, - buf->uv, buf->stride, - width, height); + yuv::i420_to_nv12(f->data[0], f->linesize[0], + f->data[1], f->linesize[1], + f->data[2], f->linesize[2], + buf->y, buf->stride, + buf->uv, buf->stride, + width, height); } return true; } diff --git a/tools/replay/framereader.h b/openpilot/tools/replay/framereader.h similarity index 100% rename from tools/replay/framereader.h rename to openpilot/tools/replay/framereader.h diff --git a/tools/replay/__init__.py b/openpilot/tools/replay/lib/__init__.py similarity index 100% rename from tools/replay/__init__.py rename to openpilot/tools/replay/lib/__init__.py diff --git a/tools/replay/lib/ui_helpers.py b/openpilot/tools/replay/lib/ui_helpers.py similarity index 99% rename from tools/replay/lib/ui_helpers.py rename to openpilot/tools/replay/lib/ui_helpers.py index 039dd4f235..6a3e8c20ed 100644 --- a/tools/replay/lib/ui_helpers.py +++ b/openpilot/tools/replay/lib/ui_helpers.py @@ -187,7 +187,7 @@ def plot_model(m, img, calibration, top_down): def plot_lead(rs, top_down): for lead in [rs.leadOne, rs.leadTwo]: - if not lead.status: + if not lead.present: continue x = lead.dRel @@ -201,7 +201,7 @@ def maybe_update_radar_points(lt, lid_overlay): if lt is not None: ar_pts = {} for track in lt: - ar_pts[track.trackId] = [track.dRel, track.yRel, track.vRel, track.aRel] + ar_pts[track.trackId] = [track.dRel, track.yRel, track.vRel] for pt in ar_pts.values(): # negative here since radar is left positive px, py = to_topdown_pt(pt[0], -pt[1]) diff --git a/tools/replay/logreader.cc b/openpilot/tools/replay/logreader.cc similarity index 100% rename from tools/replay/logreader.cc rename to openpilot/tools/replay/logreader.cc diff --git a/tools/replay/logreader.h b/openpilot/tools/replay/logreader.h similarity index 97% rename from tools/replay/logreader.h rename to openpilot/tools/replay/logreader.h index fe11ab0f77..63f7468401 100644 --- a/tools/replay/logreader.h +++ b/openpilot/tools/replay/logreader.h @@ -5,7 +5,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "tools/replay/util.h" const CameraType ALL_CAMERAS[] = {RoadCam, DriverCam, WideRoadCam}; diff --git a/tools/replay/main.cc b/openpilot/tools/replay/main.cc similarity index 100% rename from tools/replay/main.cc rename to openpilot/tools/replay/main.cc diff --git a/tools/replay/py_downloader.cc b/openpilot/tools/replay/py_downloader.cc similarity index 100% rename from tools/replay/py_downloader.cc rename to openpilot/tools/replay/py_downloader.cc diff --git a/tools/replay/py_downloader.h b/openpilot/tools/replay/py_downloader.h similarity index 100% rename from tools/replay/py_downloader.h rename to openpilot/tools/replay/py_downloader.h diff --git a/tools/replay/qcom_decoder.cc b/openpilot/tools/replay/qcom_decoder.cc similarity index 100% rename from tools/replay/qcom_decoder.cc rename to openpilot/tools/replay/qcom_decoder.cc diff --git a/tools/replay/qcom_decoder.h b/openpilot/tools/replay/qcom_decoder.h similarity index 100% rename from tools/replay/qcom_decoder.h rename to openpilot/tools/replay/qcom_decoder.h diff --git a/tools/replay/replay.cc b/openpilot/tools/replay/replay.cc similarity index 99% rename from tools/replay/replay.cc rename to openpilot/tools/replay/replay.cc index d6d02b1a9f..75aecfd0c2 100644 --- a/tools/replay/replay.cc +++ b/openpilot/tools/replay/replay.cc @@ -4,7 +4,7 @@ #include #include #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/params.h" #include "tools/replay/util.h" diff --git a/tools/replay/replay.h b/openpilot/tools/replay/replay.h similarity index 100% rename from tools/replay/replay.h rename to openpilot/tools/replay/replay.h diff --git a/tools/replay/route.cc b/openpilot/tools/replay/route.cc similarity index 98% rename from tools/replay/route.cc rename to openpilot/tools/replay/route.cc index 1560f1dce8..326d28d726 100644 --- a/tools/replay/route.cc +++ b/openpilot/tools/replay/route.cc @@ -123,7 +123,7 @@ bool Route::loadFromServer() { if (json.is_object() && json["error"].is_string()) { const std::string &error = json["error"].string_value(); if (error == "unauthorized") { - rWarning(">> Unauthorized. Authenticate with tools/lib/auth.py <<"); + rWarning(">> Unauthorized. Authenticate with openpilot/tools/lib/auth.py <<"); err_ = RouteLoadError::Unauthorized; } else if (error == "not_found") { rWarning("The specified route could not be found on the server."); diff --git a/tools/replay/route.h b/openpilot/tools/replay/route.h similarity index 100% rename from tools/replay/route.h rename to openpilot/tools/replay/route.h diff --git a/tools/replay/seg_mgr.cc b/openpilot/tools/replay/seg_mgr.cc similarity index 100% rename from tools/replay/seg_mgr.cc rename to openpilot/tools/replay/seg_mgr.cc diff --git a/tools/replay/seg_mgr.h b/openpilot/tools/replay/seg_mgr.h similarity index 100% rename from tools/replay/seg_mgr.h rename to openpilot/tools/replay/seg_mgr.h diff --git a/tools/replay/tests/test_replay.cc b/openpilot/tools/replay/tests/test_replay.cc similarity index 100% rename from tools/replay/tests/test_replay.cc rename to openpilot/tools/replay/tests/test_replay.cc diff --git a/tools/replay/timeline.cc b/openpilot/tools/replay/timeline.cc similarity index 98% rename from tools/replay/timeline.cc rename to openpilot/tools/replay/timeline.cc index 08dca5c89e..34729f5214 100644 --- a/tools/replay/timeline.cc +++ b/openpilot/tools/replay/timeline.cc @@ -3,7 +3,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" Timeline::~Timeline() { should_exit_.store(true); diff --git a/tools/replay/timeline.h b/openpilot/tools/replay/timeline.h similarity index 100% rename from tools/replay/timeline.h rename to openpilot/tools/replay/timeline.h diff --git a/tools/replay/ui.py b/openpilot/tools/replay/ui.py similarity index 98% rename from tools/replay/ui.py rename to openpilot/tools/replay/ui.py index 405c79f425..f5bd3f1d78 100755 --- a/tools/replay/ui.py +++ b/openpilot/tools/replay/ui.py @@ -6,7 +6,7 @@ import sys import numpy as np import pyray as rl -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.basedir import BASEDIR from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.tools.replay.lib.ui_helpers import ( @@ -54,7 +54,7 @@ def ui_thread(addr): rl.set_target_fps(60) # Load font - font_path = os.path.join(BASEDIR, "selfdrive/assets/fonts/JetBrainsMono-Medium.ttf") + font_path = os.path.join(BASEDIR, "openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf") font = rl.load_font_ex(font_path, 32, None, 0) camera_view = CameraView("camerad", VisionStreamType.VISION_STREAM_ROAD) @@ -176,7 +176,7 @@ def ui_thread(addr): plot_arr[-1, name_to_arr_idx['gas']] = sm['carState'].gasDEPRECATED # TODO gas is deprecated plot_arr[-1, name_to_arr_idx['computer_gas']] = np.clip(sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) - plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brake + plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brakePressed plot_arr[-1, name_to_arr_idx['steer_torque']] = sm['carControl'].actuators.torque * ANGLE_SCALE # TODO brake is deprecated plot_arr[-1, name_to_arr_idx['computer_brake']] = np.clip(-sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) diff --git a/tools/replay/util.cc b/openpilot/tools/replay/util.cc similarity index 100% rename from tools/replay/util.cc rename to openpilot/tools/replay/util.cc diff --git a/tools/replay/util.h b/openpilot/tools/replay/util.h similarity index 97% rename from tools/replay/util.h rename to openpilot/tools/replay/util.h index a2d0f6203a..03a15787b2 100644 --- a/tools/replay/util.h +++ b/openpilot/tools/replay/util.h @@ -7,7 +7,7 @@ #include #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" enum CameraType { RoadCam = 0, diff --git a/tools/sim/README.md b/openpilot/tools/sim/README.md similarity index 91% rename from tools/sim/README.md rename to openpilot/tools/sim/README.md index f6ddde2580..b3e60a119b 100644 --- a/tools/sim/README.md +++ b/openpilot/tools/sim/README.md @@ -7,7 +7,7 @@ openpilot implements a [bridge](run_bridge.py) that allows it to run in the [Met First, start openpilot. ``` bash # Run locally -./tools/sim/launch_openpilot.sh +./openpilot/tools/sim/launch_openpilot.sh ``` ## Bridge usage @@ -44,7 +44,7 @@ options: ## MetaDrive ### Launching Metadrive -Start bridge processes located in tools/sim: +Start bridge processes located in openpilot/tools/sim: ``` bash ./run_bridge.py ``` \ No newline at end of file diff --git a/tools/replay/lib/__init__.py b/openpilot/tools/sim/__init__.py similarity index 100% rename from tools/replay/lib/__init__.py rename to openpilot/tools/sim/__init__.py diff --git a/tools/sim/__init__.py b/openpilot/tools/sim/bridge/__init__.py similarity index 100% rename from tools/sim/__init__.py rename to openpilot/tools/sim/bridge/__init__.py diff --git a/tools/sim/bridge/common.py b/openpilot/tools/sim/bridge/common.py similarity index 99% rename from tools/sim/bridge/common.py rename to openpilot/tools/sim/bridge/common.py index 499420ec4b..048bf6cb11 100644 --- a/tools/sim/bridge/common.py +++ b/openpilot/tools/sim/bridge/common.py @@ -7,7 +7,6 @@ from collections import namedtuple from enum import Enum from multiprocessing import Process, Queue, Value from abc import ABC, abstractmethod - from opendbc.car.honda.values import CruiseButtons from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper diff --git a/tools/sim/bridge/metadrive/metadrive_bridge.py b/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_bridge.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py diff --git a/tools/sim/bridge/metadrive/metadrive_common.py b/openpilot/tools/sim/bridge/metadrive/metadrive_common.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_common.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_common.py diff --git a/tools/sim/bridge/metadrive/metadrive_process.py b/openpilot/tools/sim/bridge/metadrive/metadrive_process.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_process.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_process.py diff --git a/tools/sim/bridge/metadrive/metadrive_world.py b/openpilot/tools/sim/bridge/metadrive/metadrive_world.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_world.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_world.py diff --git a/tools/sim/launch_openpilot.sh b/openpilot/tools/sim/launch_openpilot.sh similarity index 100% rename from tools/sim/launch_openpilot.sh rename to openpilot/tools/sim/launch_openpilot.sh diff --git a/tools/sim/bridge/__init__.py b/openpilot/tools/sim/lib/__init__.py similarity index 100% rename from tools/sim/bridge/__init__.py rename to openpilot/tools/sim/lib/__init__.py diff --git a/tools/sim/lib/camerad.py b/openpilot/tools/sim/lib/camerad.py similarity index 98% rename from tools/sim/lib/camerad.py rename to openpilot/tools/sim/lib/camerad.py index 7634b8524d..8efb3e5dab 100644 --- a/tools/sim/lib/camerad.py +++ b/openpilot/tools/sim/lib/camerad.py @@ -1,7 +1,7 @@ import numpy as np from msgq.visionipc import VisionIpcServer, VisionStreamType -from cereal import messaging +from openpilot.cereal import messaging from openpilot.tools.sim.lib.common import W, H diff --git a/tools/sim/lib/common.py b/openpilot/tools/sim/lib/common.py similarity index 100% rename from tools/sim/lib/common.py rename to openpilot/tools/sim/lib/common.py diff --git a/tools/sim/lib/keyboard_ctrl.py b/openpilot/tools/sim/lib/keyboard_ctrl.py similarity index 100% rename from tools/sim/lib/keyboard_ctrl.py rename to openpilot/tools/sim/lib/keyboard_ctrl.py diff --git a/tools/sim/lib/manual_ctrl.py b/openpilot/tools/sim/lib/manual_ctrl.py similarity index 100% rename from tools/sim/lib/manual_ctrl.py rename to openpilot/tools/sim/lib/manual_ctrl.py diff --git a/tools/sim/lib/simulated_car.py b/openpilot/tools/sim/lib/simulated_car.py similarity index 99% rename from tools/sim/lib/simulated_car.py rename to openpilot/tools/sim/lib/simulated_car.py index 950879d394..9c430646f2 100644 --- a/tools/sim/lib/simulated_car.py +++ b/openpilot/tools/sim/lib/simulated_car.py @@ -1,5 +1,5 @@ import traceback -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.can.packer import CANPacker from opendbc.can.parser import CANParser diff --git a/tools/sim/lib/simulated_sensors.py b/openpilot/tools/sim/lib/simulated_sensors.py similarity index 98% rename from tools/sim/lib/simulated_sensors.py rename to openpilot/tools/sim/lib/simulated_sensors.py index d6d822c582..63935d3068 100644 --- a/tools/sim/lib/simulated_sensors.py +++ b/openpilot/tools/sim/lib/simulated_sensors.py @@ -1,7 +1,7 @@ import time -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_DMON from openpilot.tools.sim.lib.camerad import Camerad diff --git a/tools/sim/run_bridge.py b/openpilot/tools/sim/run_bridge.py similarity index 100% rename from tools/sim/run_bridge.py rename to openpilot/tools/sim/run_bridge.py diff --git a/tools/sim/lib/__init__.py b/openpilot/tools/sim/tests/__init__.py similarity index 100% rename from tools/sim/lib/__init__.py rename to openpilot/tools/sim/tests/__init__.py diff --git a/tools/sim/tests/conftest.py b/openpilot/tools/sim/tests/conftest.py similarity index 100% rename from tools/sim/tests/conftest.py rename to openpilot/tools/sim/tests/conftest.py diff --git a/tools/sim/tests/test_metadrive_bridge.py b/openpilot/tools/sim/tests/test_metadrive_bridge.py similarity index 100% rename from tools/sim/tests/test_metadrive_bridge.py rename to openpilot/tools/sim/tests/test_metadrive_bridge.py diff --git a/tools/sim/tests/test_sim_bridge.py b/openpilot/tools/sim/tests/test_sim_bridge.py similarity index 97% rename from tools/sim/tests/test_sim_bridge.py rename to openpilot/tools/sim/tests/test_sim_bridge.py index d58cddff7f..f93cc2ef50 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/openpilot/tools/sim/tests/test_sim_bridge.py @@ -5,11 +5,11 @@ import pytest from multiprocessing import Queue -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.basedir import BASEDIR from openpilot.tools.sim.bridge.common import QueueMessageType -SIM_DIR = os.path.join(BASEDIR, "tools/sim") +SIM_DIR = os.path.join(BASEDIR, "openpilot/tools/sim") class TestSimBridgeBase: @classmethod diff --git a/pyproject.toml b/pyproject.toml index 8c4456efaf..f00717c5a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,10 +11,7 @@ authors = [ dependencies = [ # multiple users "sounddevice", # micd + soundd - "pyserial", # pigeond + qcomgpsd "requests", # many one-off uses - "sympy", # rednose + friends - "crcmod-plus", # cars + qcomgpsd "tqdm", # cars (fw_versions.py) on start + many one-off uses # core @@ -26,33 +23,24 @@ dependencies = [ "numpy >=2.0", # vendored native dependencies - "bzip2 @ git+https://github.com/commaai/dependencies.git@release-bzip2#subdirectory=bzip2", - "bootstrap-icons @ git+https://github.com/commaai/dependencies.git@release-bootstrap-icons#subdirectory=bootstrap-icons", - "capnproto @ git+https://github.com/commaai/dependencies.git@release-capnproto#subdirectory=capnproto", - "catch2 @ git+https://github.com/commaai/dependencies.git@release-catch2#subdirectory=catch2", - "acados @ git+https://github.com/commaai/dependencies.git@release-acados#subdirectory=acados", - "eigen @ git+https://github.com/commaai/dependencies.git@release-eigen#subdirectory=eigen", - "ffmpeg @ git+https://github.com/commaai/dependencies.git@release-ffmpeg#subdirectory=ffmpeg", - "libjpeg @ git+https://github.com/commaai/dependencies.git@release-libjpeg#subdirectory=libjpeg", - "libyuv @ git+https://github.com/commaai/dependencies.git@release-libyuv#subdirectory=libyuv", - "zstd @ git+https://github.com/commaai/dependencies.git@release-zstd#subdirectory=zstd", - "ncurses @ git+https://github.com/commaai/dependencies.git@release-ncurses#subdirectory=ncurses", - "zeromq @ git+https://github.com/commaai/dependencies.git@release-zeromq#subdirectory=zeromq", - "libusb @ git+https://github.com/commaai/dependencies.git@release-libusb#subdirectory=libusb", - "json11 @ git+https://github.com/commaai/dependencies.git@release-json11#subdirectory=json11", - "git-lfs @ git+https://github.com/commaai/dependencies.git@release-git-lfs#subdirectory=git-lfs", - "gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@release-gcc-arm-none-eabi#subdirectory=gcc-arm-none-eabi", - "xvfb @ git+https://github.com/commaai/dependencies.git@release-xvfb#subdirectory=xvfb", + "comma-deps-bzip2", + "comma-deps-bootstrap-icons", + "comma-deps-capnproto", + "comma-deps-catch2", + "comma-deps-acados", + "comma-deps-ffmpeg", + "comma-deps-zstd", + "comma-deps-ncurses", + "comma-deps-zeromq", + "comma-deps-libusb", + "comma-deps-json11", + "comma-deps-git-lfs", + "comma-deps-gcc-arm-none-eabi", # body / webrtcd "av", - "aiohttp", "aiortc", - # panda - "libusb1", - "spidev; platform_system == 'Linux'", - # logging "pyzmq", "sentry-sdk", @@ -60,22 +48,19 @@ dependencies = [ # athena "PyJWT", - "json-rpc", "websocket_client", # joystickd "inputs", # these should be removed - "psutil", - "pycryptodome", # used in panda, body, and a test "setproctitle", # logreader "zstandard", # ui - "raylib @ git+https://github.com/commaai/dependencies.git@release-raylib#subdirectory=raylib", + "comma-deps-raylib", "qrcode", "jeepney", "pillow", @@ -104,32 +89,45 @@ testing = [ dev = [ "matplotlib", - "opencv-python-headless", ] tools = [ - "imgui @ git+https://github.com/commaai/dependencies.git@release-imgui#subdirectory=imgui", - "metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", + "comma-deps-imgui", + + # this can be added back once it's stripped down some more + #"metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", ] [project.urls] Homepage = "https://github.com/commaai/openpilot" +[dependency-groups] +submodules = [ + "msgq", + "opendbc", + "pandacan", + "rednose", + "teleoprtc", + "tinygrad", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = [ "." ] +packages = [ + "openpilot", +] [tool.hatch.metadata] allow-direct-references = true [tool.pytest.ini_options] minversion = "6.0" -addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ --ignore=selfdrive/modeld -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" +addopts = "-Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" cpp_files = "test_*" -cpp_harness = "selfdrive/test/cpp_harness.py" +cpp_harness = "openpilot/selfdrive/test/cpp_harness.py" python_files = "test_*.py" markers = [ "slow: tests that take awhile to run and can be skipped with -m 'not slow'", @@ -140,12 +138,7 @@ markers = [ "xdist_group_class_property: group tests by a property of the class that contains them", ] testpaths = [ - "common", - "selfdrive", - "system", - "tools", - "cereal", - "sunnypilot", + "openpilot", ] [tool.codespell] @@ -153,7 +146,7 @@ quiet-level = 3 # if you've got a short variable name that's getting flagged, add it here ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead,TGE,abl,lite,ser" builtin = "clear,rare,informal,code,names,en-GB_to_en-US" -skip = "./third_party/*, ./tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, *.pem, ./cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html" +skip = "*.po, uv.lock, *.onnx, *.pem, */c_generated_code/*, docs/assets/*, openpilot/tools/plotjuggler/layouts/*, openpilot/selfdrive/assets/offroad/mici_fcc.html, ./openpilot/third_party/*, ./openpilot/cereal/gen/*" # https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml [tool.ruff] @@ -179,25 +172,14 @@ lint.ignore = [ ] line-length = 160 exclude = [ - "cereal", - "panda", - "opendbc", - "opendbc_repo", - "rednose_repo", - "tinygrad_repo", - "teleoprtc", - "teleoprtc_repo", - "third_party/copyparty", + "openpilot/cereal", + "openpilot/third_party", "*.ipynb", "generated", ] lint.flake8-implicit-str-concat.allow-multiline = false [tool.ruff.lint.flake8-tidy-imports.banned-api] -"selfdrive".msg = "Use openpilot.selfdrive" -"common".msg = "Use openpilot.common" -"system".msg = "Use openpilot.system" -"tools".msg = "Use openpilot.tools" "pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" "unittest".msg = "Use pytest" "time.time".msg = "Use time.monotonic" @@ -214,18 +196,7 @@ quote-style = "preserve" [tool.ty.src] exclude = [ - "msgq/", - "msgq_repo/", - "opendbc/", - "opendbc_repo/", - "panda/", - "rednose/", - "rednose_repo/", - "tinygrad/", - "tinygrad_repo/", - "teleoprtc/", - "teleoprtc_repo/", - "third_party/", + "openpilot/third_party/", ] [tool.ty.rules] @@ -242,3 +213,16 @@ not-subscriptable = "ignore" # false positives from dynamic types [tool.uv] python-preference = "only-managed" +default-groups = ["submodules"] +override-dependencies = [ + "opendbc", # panda pins opendbc from git for standalone use; always use our submodule + "av", # teleoprtc's av<13 pin is stale +] + +[tool.uv.sources] +msgq = { path = "msgq_repo", editable = true } +opendbc = { path = "opendbc_repo", editable = true } +pandacan = { path = "panda", editable = true } +rednose = { path = "rednose_repo", editable = true } +teleoprtc = { path = "teleoprtc_repo", editable = true } +tinygrad = { path = "tinygrad_repo", editable = true } diff --git a/rednose b/rednose deleted file mode 120000 index 674cfec35f..0000000000 --- a/rednose +++ /dev/null @@ -1 +0,0 @@ -rednose_repo/rednose \ No newline at end of file diff --git a/rednose_repo b/rednose_repo index 7ffefa3d88..9e19086c26 160000 --- a/rednose_repo +++ b/rednose_repo @@ -1 +1 @@ -Subproject commit 7ffefa3d8811a842f8ec97d311103ce3a45dfae0 +Subproject commit 9e19086c26ca35708870d50ebcf237d65d0b163e diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh index 919e2ca63a..024a743912 100755 --- a/scripts/lint/lint.sh +++ b/scripts/lint/lint.sh @@ -13,9 +13,6 @@ cd $ROOT FAILED=0 -IGNORED_FILES="uv\.lock|docs\/CARS.md|LICENSE\.md" -IGNORED_DIRS="^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*|^third_party.*" - function run() { shopt -s extglob case $1 in @@ -48,14 +45,14 @@ function run_tests() { ALL_FILES=$1 PYTHON_FILES=$2 - run "ruff" ruff check $ROOT --quiet + run "ruff" ruff check openpilot --quiet run "check_added_large_files" python3 -m pre_commit_hooks.check_added_large_files --enforce-all $ALL_FILES --maxkb=120 run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES run "check_nomerge_comments" $DIR/check_nomerge_comments.sh $ALL_FILES if [[ -z "$FAST" ]]; then - run "ty" ty check + run "ty" ty check openpilot run "codespell" codespell $ALL_FILES --ignore-words=$ROOT/.codespellignore fi @@ -105,7 +102,8 @@ done RUN=$([ -z "$RUN" ] && echo "" || echo "!($(echo $RUN | sed 's/ /|/g'))") SKIP="@($(echo $SKIP | sed 's/ /|/g'))" -GIT_FILES="$(git ls-files | sed -E "s/$IGNORED_FILES|$IGNORED_DIRS//g")" +IGNORED_DIRS="^openpilot/third_party/.*" +GIT_FILES="$(git ls-files openpilot | grep -vE "$IGNORED_DIRS")" ALL_FILES="" for f in $GIT_FILES; do if [[ -f $f ]]; then diff --git a/scripts/reporter.py b/scripts/reporter.py index 199f1fae58..5de5521835 100755 --- a/scripts/reporter.py +++ b/scripts/reporter.py @@ -7,7 +7,7 @@ from tinygrad.nn.onnx import OnnxPBParser BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) MASTER_PATH = os.getenv("MASTER_PATH", BASEDIR) -MODEL_PATH = "/selfdrive/modeld/models/" +MODEL_PATH = "/openpilot/selfdrive/modeld/models/" class MetadataOnnxPBParser(OnnxPBParser): diff --git a/scripts/test_pip_install.sh b/scripts/test_pip_install.sh new file mode 100755 index 0000000000..d2dbedff0a --- /dev/null +++ b/scripts/test_pip_install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euxo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel)" +PYTHON_VERSION="$(cat "$REPO_ROOT/.python-version")" +PACKAGE="${1:-$REPO_ROOT}" + +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +cd "$TMPDIR" + +uv venv --python "$PYTHON_VERSION" +source .venv/bin/activate +uv pip install "$PACKAGE" +python3 - <<'PY' +from openpilot.tools.lib.logreader import LogReader + +assert LogReader.__name__ == "LogReader" +print("ok: imported LogReader") +PY diff --git a/scripts/waste.c b/scripts/waste.c index 2e492916a7..fc230846f2 100644 --- a/scripts/waste.c +++ b/scripts/waste.c @@ -11,7 +11,7 @@ #include #include #include -#include "../common/timing.h" +#include "../openpilot/common/timing.h" int get_nprocs(void); double *ttime, *oout; @@ -86,4 +86,3 @@ int main() { sleep(1); } } - diff --git a/selfdrive/assets/sounds/prompt_distracted.wav b/selfdrive/assets/sounds/prompt_distracted.wav deleted file mode 100644 index 750d580f04..0000000000 --- a/selfdrive/assets/sounds/prompt_distracted.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1810ad0418ac234f02dec005883c8f0e1c3e0e5ece7a3157803c5a66cb8e5adc -size 85662 diff --git a/selfdrive/car/tests/big_cars_test.sh b/selfdrive/car/tests/big_cars_test.sh deleted file mode 100755 index bb6e82dd0e..0000000000 --- a/selfdrive/car/tests/big_cars_test.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -SCRIPT_DIR=$(dirname "$0") -BASEDIR=$(realpath "$SCRIPT_DIR/../../../") -cd $BASEDIR - -export MAX_EXAMPLES=300 -export INTERNAL_SEG_CNT=300 -export INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt - -cd selfdrive/car/tests && pytest test_models.py test_car_interfaces.py diff --git a/selfdrive/controls/lib/lateral_mpc_lib/.gitignore b/selfdrive/controls/lib/lateral_mpc_lib/.gitignore deleted file mode 100644 index aff2eb082b..0000000000 --- a/selfdrive/controls/lib/lateral_mpc_lib/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -acados_ocp_lat.json -c_generated_code/ diff --git a/selfdrive/controls/lib/lateral_mpc_lib/SConscript b/selfdrive/controls/lib/lateral_mpc_lib/SConscript deleted file mode 100644 index 5ff526ae83..0000000000 --- a/selfdrive/controls/lib/lateral_mpc_lib/SConscript +++ /dev/null @@ -1,104 +0,0 @@ -Import('env', 'envCython', 'arch', 'msgq_python', 'common_python', 'np_version', 'acados') - -gen = "c_generated_code" - -casadi_model = [ - f'{gen}/lat_model/lat_expl_ode_fun.c', - f'{gen}/lat_model/lat_expl_vde_forw.c', -] - -casadi_cost_y = [ - f'{gen}/lat_cost/lat_cost_y_fun.c', - f'{gen}/lat_cost/lat_cost_y_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_hess.c', -] - -casadi_cost_e = [ - f'{gen}/lat_cost/lat_cost_y_e_fun.c', - f'{gen}/lat_cost/lat_cost_y_e_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_e_hess.c', -] - -casadi_cost_0 = [ - f'{gen}/lat_cost/lat_cost_y_0_fun.c', - f'{gen}/lat_cost/lat_cost_y_0_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_0_hess.c', -] - -build_files = [f'{gen}/acados_solver_lat.c'] + casadi_model + casadi_cost_y + casadi_cost_e + casadi_cost_0 - -# extra generated files used to trigger a rebuild -generated_files = [ - f'{gen}/Makefile', - - f'{gen}/main_lat.c', - f'{gen}/main_sim_lat.c', - f'{gen}/acados_solver_lat.h', - f'{gen}/acados_sim_solver_lat.h', - f'{gen}/acados_sim_solver_lat.c', - f'{gen}/acados_solver.pxd', - - f'{gen}/lat_model/lat_expl_vde_adj.c', - - f'{gen}/lat_model/lat_model.h', - f'{gen}/lat_constraints/lat_constraints.h', - f'{gen}/lat_cost/lat_cost.h', -] + build_files - -acados_include_dir = Dir(acados.INCLUDE_DIR) -acados_template_dir = Dir(acados.TEMPLATE_DIR) - -source_list = ['lat_mpc.py', - '#selfdrive/modeld/constants.py', - acados_include_dir.File('acados_c/ocp_nlp_interface.h'), - acados_template_dir.File('c_templates_tera/acados_solver.in.c'), -] - -lenv = env.Clone() -copied_acados_libs = [] -if arch != "Darwin": - for lib in ["libacados.so", "libblasfeo.so", "libhpipm.so", "libqpOASES_e.so.3.1"]: - copied_acados_libs += lenv.Command(f"{gen}/{lib}", Dir(acados.LIB_DIR).File(lib), [Mkdir(Dir(gen)), Copy("$TARGET", "$SOURCE")]) - lenv["RPATH"] += [lenv.Literal('\\$$ORIGIN')] -else: - acados_rel_path = Dir(gen).rel_path(Dir(acados.LIB_DIR)) - lenv["RPATH"] += [lenv.Literal(f'\\$$ORIGIN/{acados_rel_path}')] -lenv.Clean(generated_files, Dir(gen)) - -generated_lat = lenv.Command(generated_files, - source_list, - f"cd {Dir('.').abspath} && python3 lat_mpc.py") -lenv.Depends(generated_lat, [msgq_python, common_python]) - -lenv["CFLAGS"].append("-DACADOS_WITH_QPOASES") -lenv["CXXFLAGS"].append("-DACADOS_WITH_QPOASES") -lenv["CCFLAGS"].append("-Wno-unused") -if arch != "Darwin": - lenv["LINKFLAGS"].append("-Wl,--disable-new-dtags") -else: - lenv["LINKFLAGS"].append("-Wl,-install_name,@loader_path/libacados_ocp_solver_lat.dylib") - lenv["LINKFLAGS"].append(f"-Wl,-rpath,@loader_path/{acados_rel_path}") -lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_lat", - build_files, - LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e']) - -# generate cython stuff -acados_ocp_solver_pyx = acados_template_dir.File('acados_ocp_solver_pyx.pyx') -acados_ocp_solver_common = acados_template_dir.File('acados_solver_common.pxd') -libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd') -libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c') - -lenv2 = envCython.Clone() -lenv2["LIBPATH"] += [lib_solver[0].dir.abspath] -lenv2["RPATH"] += [lenv2.Literal('\\$$ORIGIN')] -lenv2.Command(libacados_ocp_solver_c, - [acados_ocp_solver_pyx, acados_ocp_solver_common, libacados_ocp_solver_pxd], - f'cython' + \ - f' -o {libacados_ocp_solver_c.get_labspath()}' + \ - f' -I {libacados_ocp_solver_pxd.get_dir().get_labspath()}' + \ - f' -I {acados_ocp_solver_common.get_dir().get_labspath()}' + \ - f' {acados_ocp_solver_pyx.get_labspath()}') -lib_cython = lenv2.Program(f'{gen}/acados_ocp_solver_pyx.so', [libacados_ocp_solver_c], LIBS=['acados_ocp_solver_lat']) -lenv2.Depends(lib_cython, lib_solver) -lenv2.Depends(lib_cython, copied_acados_libs) -lenv2.Depends(libacados_ocp_solver_c, np_version) diff --git a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py b/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py deleted file mode 100755 index 3b597b2e42..0000000000 --- a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python3 -import os -import time -import numpy as np - -from casadi import SX, vertcat, sin, cos -# WARNING: imports outside of constants will not trigger a rebuild -from openpilot.selfdrive.modeld.constants import ModelConstants - -if __name__ == '__main__': # generating code - from acados.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver -else: - from openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython - -LAT_MPC_DIR = os.path.dirname(os.path.abspath(__file__)) -EXPORT_DIR = os.path.join(LAT_MPC_DIR, "c_generated_code") -JSON_FILE = os.path.join(LAT_MPC_DIR, "acados_ocp_lat.json") -X_DIM = 4 -P_DIM = 2 -COST_E_DIM = 3 -COST_DIM = COST_E_DIM + 2 -SPEED_OFFSET = 10.0 -MODEL_NAME = 'lat' -ACADOS_SOLVER_TYPE = 'SQP_RTI' -N = 32 - -def gen_lat_model(): - model = AcadosModel() - model.name = MODEL_NAME - - # set up states & controls - x_ego = SX.sym('x_ego') - y_ego = SX.sym('y_ego') - psi_ego = SX.sym('psi_ego') - psi_rate_ego = SX.sym('psi_rate_ego') - model.x = vertcat(x_ego, y_ego, psi_ego, psi_rate_ego) - - # parameters - v_ego = SX.sym('v_ego') - rotation_radius = SX.sym('rotation_radius') - model.p = vertcat(v_ego, rotation_radius) - - # controls - psi_accel_ego = SX.sym('psi_accel_ego') - model.u = vertcat(psi_accel_ego) - - # xdot - x_ego_dot = SX.sym('x_ego_dot') - y_ego_dot = SX.sym('y_ego_dot') - psi_ego_dot = SX.sym('psi_ego_dot') - psi_rate_ego_dot = SX.sym('psi_rate_ego_dot') - - model.xdot = vertcat(x_ego_dot, y_ego_dot, psi_ego_dot, psi_rate_ego_dot) - - # dynamics model - f_expl = vertcat(v_ego * cos(psi_ego) - rotation_radius * sin(psi_ego) * psi_rate_ego, - v_ego * sin(psi_ego) + rotation_radius * cos(psi_ego) * psi_rate_ego, - psi_rate_ego, - psi_accel_ego) - model.f_impl_expr = model.xdot - f_expl - model.f_expl_expr = f_expl - return model - - -def gen_lat_ocp(): - ocp = AcadosOcp() - ocp.model = gen_lat_model() - - Tf = np.array(ModelConstants.T_IDXS)[N] - - # set dimensions - ocp.dims.N = N - - # set cost module - ocp.cost.cost_type = 'NONLINEAR_LS' - ocp.cost.cost_type_e = 'NONLINEAR_LS' - - Q = np.diag(np.zeros(COST_E_DIM)) - QR = np.diag(np.zeros(COST_DIM)) - - ocp.cost.W = QR - ocp.cost.W_e = Q - - y_ego, psi_ego, psi_rate_ego = ocp.model.x[1], ocp.model.x[2], ocp.model.x[3] - psi_rate_ego_dot = ocp.model.u[0] - v_ego = ocp.model.p[0] - - ocp.parameter_values = np.zeros((P_DIM, )) - - ocp.cost.yref = np.zeros((COST_DIM, )) - ocp.cost.yref_e = np.zeros((COST_E_DIM, )) - # Add offset to smooth out low speed control - # TODO unclear if this right solution long term - v_ego_offset = v_ego + SPEED_OFFSET - # TODO there are two costs on psi_rate_ego_dot, one - # is correlated to jerk the other to steering wheel movement - # the steering wheel movement cost is added to prevent excessive - # wheel movements - ocp.model.cost_y_expr = vertcat(y_ego, - v_ego_offset * psi_ego, - v_ego_offset * psi_rate_ego, - v_ego_offset * psi_rate_ego_dot, - psi_rate_ego_dot / (v_ego + 0.1)) - ocp.model.cost_y_expr_e = vertcat(y_ego, - v_ego_offset * psi_ego, - v_ego_offset * psi_rate_ego) - - # set constraints - ocp.constraints.constr_type = 'BGH' - ocp.constraints.idxbx = np.array([2,3]) - ocp.constraints.ubx = np.array([np.radians(90), np.radians(50)]) - ocp.constraints.lbx = np.array([-np.radians(90), -np.radians(50)]) - x0 = np.zeros((X_DIM,)) - ocp.constraints.x0 = x0 - - ocp.solver_options.qp_solver = 'PARTIAL_CONDENSING_HPIPM' - ocp.solver_options.hessian_approx = 'GAUSS_NEWTON' - ocp.solver_options.integrator_type = 'ERK' - ocp.solver_options.nlp_solver_type = ACADOS_SOLVER_TYPE - ocp.solver_options.qp_solver_iter_max = 1 - ocp.solver_options.qp_solver_cond_N = 1 - - # set prediction horizon - ocp.solver_options.tf = Tf - ocp.solver_options.shooting_nodes = np.array(ModelConstants.T_IDXS)[:N+1] - - ocp.code_export_directory = EXPORT_DIR - return ocp - - -class LateralMpc: - 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=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)) - for i in range(N): - self.solver.cost_set(i, "yref", self.yref[i]) - self.solver.cost_set(N, "yref", self.yref[N][:COST_E_DIM]) - - # Somehow needed for stable init - for i in range(N+1): - self.solver.set(i, 'x', np.zeros(X_DIM)) - self.solver.set(i, 'p', np.zeros(P_DIM)) - self.solver.constraints_set(0, "lbx", x0) - self.solver.constraints_set(0, "ubx", x0) - self.solver.solve() - self.solution_status = 0 - self.solve_time = 0.0 - self.cost = 0 - - def set_weights(self, path_weight, heading_weight, - lat_accel_weight, lat_jerk_weight, - steering_rate_weight): - W = np.asfortranarray(np.diag([path_weight, heading_weight, - lat_accel_weight, lat_jerk_weight, - steering_rate_weight])) - for i in range(N): - self.solver.cost_set(i, 'W', W) - self.solver.cost_set(N, 'W', W[:COST_E_DIM,:COST_E_DIM]) - - def run(self, x0, p, y_pts, heading_pts, yaw_rate_pts): - x0_cp = np.copy(x0) - p_cp = np.copy(p) - self.solver.constraints_set(0, "lbx", x0_cp) - self.solver.constraints_set(0, "ubx", x0_cp) - self.yref[:,0] = y_pts - v_ego = p_cp[0, 0] - # rotation_radius = p_cp[1] - self.yref[:,1] = heading_pts * (v_ego + SPEED_OFFSET) - self.yref[:,2] = yaw_rate_pts * (v_ego + SPEED_OFFSET) - for i in range(N): - self.solver.cost_set(i, "yref", self.yref[i]) - self.solver.set(i, "p", p_cp[i]) - self.solver.set(N, "p", p_cp[N]) - self.solver.cost_set(N, "yref", self.yref[N][:COST_E_DIM]) - - t = time.monotonic() - self.solution_status = self.solver.solve() - self.solve_time = time.monotonic() - t - - for i in range(N+1): - self.x_sol[i] = self.solver.get(i, 'x') - for i in range(N): - self.u_sol[i] = self.solver.get(i, 'u') - self.cost = self.solver.get_cost() - - -if __name__ == "__main__": - ocp = gen_lat_ocp() - AcadosOcpSolver.generate(ocp, json_file=JSON_FILE) - # AcadosOcpSolver.build(ocp.code_export_directory, with_cython=True) diff --git a/selfdrive/controls/tests/test_lateral_mpc.py b/selfdrive/controls/tests/test_lateral_mpc.py deleted file mode 100644 index 3aa0fd1bce..0000000000 --- a/selfdrive/controls/tests/test_lateral_mpc.py +++ /dev/null @@ -1,85 +0,0 @@ -import pytest -import numpy as np -from openpilot.selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc -from openpilot.selfdrive.controls.lib.drive_helpers import CAR_ROTATION_RADIUS -from openpilot.selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import N as LAT_MPC_N - - -def run_mpc(lat_mpc=None, v_ref=30., x_init=0., y_init=0., psi_init=0., curvature_init=0., - lane_width=3.6, poly_shift=0.): - - if lat_mpc is None: - lat_mpc = LateralMpc() - lat_mpc.set_weights(1., .1, 0.0, .05, 800) - - y_pts = poly_shift * np.ones(LAT_MPC_N + 1) - heading_pts = np.zeros(LAT_MPC_N + 1) - curv_rate_pts = np.zeros(LAT_MPC_N + 1) - - x0 = np.array([x_init, y_init, psi_init, curvature_init]) - p = np.column_stack([v_ref * np.ones(LAT_MPC_N + 1), - CAR_ROTATION_RADIUS * np.ones(LAT_MPC_N + 1)]) - - # converge in no more than 10 iterations - for _ in range(10): - lat_mpc.run(x0, p, - y_pts, heading_pts, curv_rate_pts) - return lat_mpc.x_sol - - -class TestLateralMpc: - - def _assert_null(self, sol, curvature=1e-6): - for i in range(len(sol)): - assert sol[0,i,1] == pytest.approx(0, abs=curvature) - assert sol[0,i,2] == pytest.approx(0, abs=curvature) - assert sol[0,i,3] == pytest.approx(0, abs=curvature) - - def _assert_simmetry(self, sol, curvature=1e-6): - for i in range(len(sol)): - assert sol[0,i,1] == pytest.approx(-sol[1,i,1], abs=curvature) - assert sol[0,i,2] == pytest.approx(-sol[1,i,2], abs=curvature) - assert sol[0,i,3] == pytest.approx(-sol[1,i,3], abs=curvature) - assert sol[0,i,0] == pytest.approx(sol[1,i,0], abs=curvature) - - def test_straight(self): - sol = run_mpc() - self._assert_null(np.array([sol])) - - def test_y_symmetry(self): - sol = [] - for y_init in [-0.5, 0.5]: - sol.append(run_mpc(y_init=y_init)) - self._assert_simmetry(np.array(sol)) - - def test_poly_symmetry(self): - sol = [] - for poly_shift in [-1., 1.]: - sol.append(run_mpc(poly_shift=poly_shift)) - self._assert_simmetry(np.array(sol)) - - def test_curvature_symmetry(self): - sol = [] - for curvature_init in [-0.1, 0.1]: - sol.append(run_mpc(curvature_init=curvature_init)) - self._assert_simmetry(np.array(sol)) - - def test_psi_symmetry(self): - sol = [] - for psi_init in [-0.1, 0.1]: - sol.append(run_mpc(psi_init=psi_init)) - self._assert_simmetry(np.array(sol)) - - def test_no_overshoot(self): - y_init = 1. - sol = run_mpc(y_init=y_init) - for y in list(sol[:,1]): - assert y_init >= abs(y) - - def test_switch_convergence(self): - lat_mpc = LateralMpc() - sol = run_mpc(lat_mpc=lat_mpc, poly_shift=3.0, v_ref=7.0) - right_psi_deg = np.degrees(sol[:,2]) - sol = run_mpc(lat_mpc=lat_mpc, poly_shift=-3.0, v_ref=7.0) - left_psi_deg = np.degrees(sol[:,2]) - np.testing.assert_almost_equal(right_psi_deg, -left_psi_deg, decimal=3) diff --git a/selfdrive/modeld/compile_warp.py b/selfdrive/modeld/compile_warp.py deleted file mode 100755 index 1144fc69c3..0000000000 --- a/selfdrive/modeld/compile_warp.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python3 -import time -import pickle -import numpy as np -from pathlib import Path -from tinygrad.tensor import Tensor -from tinygrad.helpers import Context -from tinygrad.device import Device -from tinygrad.engine.jit import TinyJit - -from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.transformations.model import MEDMODEL_INPUT_SIZE, DM_INPUT_SIZE -from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye - -MODELS_DIR = Path(__file__).parent / 'models' - -CAMERA_CONFIGS = [ - (_ar_ox_fisheye.width, _ar_ox_fisheye.height), # tici: 1928x1208 - (_os_fisheye.width, _os_fisheye.height), # mici: 1344x760 -] - -UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) -UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) - -IMG_BUFFER_SHAPE = (30, MEDMODEL_INPUT_SIZE[1] // 2, MEDMODEL_INPUT_SIZE[0] // 2) - - -def warp_pkl_path(w, h): - return MODELS_DIR / f'warp_{w}x{h}_tinygrad.pkl' - - -def dm_warp_pkl_path(w, h): - return MODELS_DIR / f'dm_warp_{w}x{h}_tinygrad.pkl' - - -def warp_perspective_tinygrad(src_flat, M_inv, dst_shape, src_shape, stride_pad): - w_dst, h_dst = dst_shape - h_src, w_src = src_shape - - x = Tensor.arange(w_dst).reshape(1, w_dst).expand(h_dst, w_dst).reshape(-1) - y = Tensor.arange(h_dst).reshape(h_dst, 1).expand(h_dst, w_dst).reshape(-1) - - # inline 3x3 matmul as elementwise to avoid reduce op (enables fusion with gather) - src_x = M_inv[0, 0] * x + M_inv[0, 1] * y + M_inv[0, 2] - src_y = M_inv[1, 0] * x + M_inv[1, 1] * y + M_inv[1, 2] - src_w = M_inv[2, 0] * x + M_inv[2, 1] * y + M_inv[2, 2] - - src_x = src_x / src_w - src_y = src_y / src_w - - x_nn_clipped = Tensor.round(src_x).clip(0, w_src - 1).cast('int') - y_nn_clipped = Tensor.round(src_y).clip(0, h_src - 1).cast('int') - idx = y_nn_clipped * (w_src + stride_pad) + x_nn_clipped - - return src_flat[idx] - - -def frames_to_tensor(frames, model_w, model_h): - H = (frames.shape[0] * 2) // 3 - W = frames.shape[1] - in_img1 = Tensor.cat(frames[0:H:2, 0::2], - frames[1:H:2, 0::2], - frames[0:H:2, 1::2], - frames[1:H:2, 1::2], - frames[H:H+H//4].reshape((H//2, W//2)), - frames[H+H//4:H+H//2].reshape((H//2, W//2)), dim=0).reshape((6, H//2, W//2)) - return in_img1 - - -def make_frame_prepare(cam_w, cam_h, model_w, model_h): - stride, y_height, uv_height, _ = get_nv12_info(cam_w, cam_h) - uv_offset = stride * y_height - stride_pad = stride - cam_w - - def frame_prepare_tinygrad(input_frame, M_inv): - # UV_SCALE @ M_inv @ UV_SCALE_INV simplifies to elementwise scaling - M_inv_uv = M_inv * Tensor([[1.0, 1.0, 0.5], [1.0, 1.0, 0.5], [2.0, 2.0, 1.0]]) - # deinterleave NV12 UV plane (UVUV... -> separate U, V) - uv = input_frame[uv_offset:uv_offset + uv_height * stride].reshape(uv_height, stride) - with Context(SPLIT_REDUCEOP=0): - y = warp_perspective_tinygrad(input_frame[:cam_h*stride], - M_inv, (model_w, model_h), - (cam_h, cam_w), stride_pad).realize() - u = warp_perspective_tinygrad(uv[:cam_h//2, :cam_w:2].flatten(), - M_inv_uv, (model_w//2, model_h//2), - (cam_h//2, cam_w//2), 0).realize() - v = warp_perspective_tinygrad(uv[:cam_h//2, 1:cam_w:2].flatten(), - M_inv_uv, (model_w//2, model_h//2), - (cam_h//2, cam_w//2), 0).realize() - yuv = y.cat(u).cat(v).reshape((model_h * 3 // 2, model_w)) - tensor = frames_to_tensor(yuv, model_w, model_h) - return tensor - return frame_prepare_tinygrad - - -def make_update_img_input(frame_prepare, model_w, model_h): - def update_img_input_tinygrad(tensor, frame, M_inv): - M_inv = M_inv.to(Device.DEFAULT) - new_img = frame_prepare(frame, M_inv) - tensor.assign(tensor[6:].cat(new_img, dim=0).contiguous()) - return Tensor.cat(tensor[:6], tensor[-6:], dim=0).contiguous().reshape(1, 12, model_h//2, model_w//2) - return update_img_input_tinygrad - - -def make_update_both_imgs(frame_prepare, model_w, model_h): - update_img = make_update_img_input(frame_prepare, model_w, model_h) - - def update_both_imgs_tinygrad(calib_img_buffer, new_img, M_inv, - calib_big_img_buffer, new_big_img, M_inv_big): - calib_img_pair = update_img(calib_img_buffer, new_img, M_inv) - calib_big_img_pair = update_img(calib_big_img_buffer, new_big_img, M_inv_big) - return calib_img_pair, calib_big_img_pair - return update_both_imgs_tinygrad - - -def make_warp_dm(cam_w, cam_h, dm_w, dm_h): - stride, y_height, _, _ = get_nv12_info(cam_w, cam_h) - stride_pad = stride - cam_w - - def warp_dm(input_frame, M_inv): - M_inv = M_inv.to(Device.DEFAULT) - result = warp_perspective_tinygrad(input_frame[:cam_h*stride], M_inv, (dm_w, dm_h), (cam_h, cam_w), stride_pad).reshape(-1, dm_h * dm_w) - return result - return warp_dm - - -def compile_modeld_warp(cam_w, cam_h): - model_w, model_h = MEDMODEL_INPUT_SIZE - _, _, _, yuv_size = get_nv12_info(cam_w, cam_h) - - print(f"Compiling modeld warp for {cam_w}x{cam_h}...") - - frame_prepare = make_frame_prepare(cam_w, cam_h, model_w, model_h) - update_both_imgs = make_update_both_imgs(frame_prepare, model_w, model_h) - update_img_jit = TinyJit(update_both_imgs, prune=True) - - full_buffer = Tensor.zeros(IMG_BUFFER_SHAPE, dtype='uint8').contiguous().realize() - big_full_buffer = Tensor.zeros(IMG_BUFFER_SHAPE, dtype='uint8').contiguous().realize() - new_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - new_big_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - for i in range(10): - img_inputs = [full_buffer, - Tensor.from_blob(new_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - big_img_inputs = [big_full_buffer, - Tensor.from_blob(new_big_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - inputs = img_inputs + big_img_inputs - Device.default.synchronize() - - st = time.perf_counter() - _ = update_img_jit(*inputs) - mt = time.perf_counter() - Device.default.synchronize() - et = time.perf_counter() - print(f" [{i+1}/10] enqueue {(mt-st)*1e3:6.2f} ms -- total {(et-st)*1e3:6.2f} ms") - - pkl_path = warp_pkl_path(cam_w, cam_h) - with open(pkl_path, "wb") as f: - pickle.dump(update_img_jit, f) - print(f" Saved to {pkl_path}") - - jit = pickle.load(open(pkl_path, "rb")) - jit(*inputs) - - -def compile_dm_warp(cam_w, cam_h): - dm_w, dm_h = DM_INPUT_SIZE - _, _, _, yuv_size = get_nv12_info(cam_w, cam_h) - - print(f"Compiling DM warp for {cam_w}x{cam_h}...") - - warp_dm = make_warp_dm(cam_w, cam_h, dm_w, dm_h) - warp_dm_jit = TinyJit(warp_dm, prune=True) - - new_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - for i in range(10): - inputs = [Tensor.from_blob(new_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - Device.default.synchronize() - st = time.perf_counter() - warp_dm_jit(*inputs) - mt = time.perf_counter() - Device.default.synchronize() - et = time.perf_counter() - print(f" [{i+1}/10] enqueue {(mt-st)*1e3:6.2f} ms -- total {(et-st)*1e3:6.2f} ms") - - pkl_path = dm_warp_pkl_path(cam_w, cam_h) - with open(pkl_path, "wb") as f: - pickle.dump(warp_dm_jit, f) - print(f" Saved to {pkl_path}") - - -def run_and_save_pickle(): - for cam_w, cam_h in CAMERA_CONFIGS: - compile_modeld_warp(cam_w, cam_h) - compile_dm_warp(cam_w, cam_h) - - -if __name__ == "__main__": - run_and_save_pickle() diff --git a/selfdrive/modeld/helpers.py b/selfdrive/modeld/helpers.py deleted file mode 100644 index 64bf28873f..0000000000 --- a/selfdrive/modeld/helpers.py +++ /dev/null @@ -1,26 +0,0 @@ -import json -from pathlib import Path - -MODELS_DIR = Path(__file__).resolve().parent / 'models' -TG_INPUT_DEVICES_PATH = MODELS_DIR / 'tg_input_devices.json' -USBGPU_VID = 0xADD1 -USBGPU_PID = 0x0001 - - -def get_tg_input_devices(process_name: str, usbgpu: bool): - with open(TG_INPUT_DEVICES_PATH) as f: - return json.load(f)[process_name]['default' if not usbgpu else 'usbgpu'] - -def modeld_pkl_path(usbgpu: bool): - prefix = 'big_' if usbgpu else '' - return MODELS_DIR / f'{prefix}driving_tinygrad.pkl' - -def usbgpu_present() -> bool: - for d in Path("/sys/bus/usb/devices").glob("*"): - try: - if int((d / "idVendor").read_text(), 16) == USBGPU_VID and \ - int((d / "idProduct").read_text(), 16) == USBGPU_PID: - return True - except Exception: - pass - return False diff --git a/selfdrive/modeld/models/README.md b/selfdrive/modeld/models/README.md deleted file mode 100644 index 04b69c61c3..0000000000 --- a/selfdrive/modeld/models/README.md +++ /dev/null @@ -1,66 +0,0 @@ -## Neural networks in openpilot -To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) - -## Driving Model (vision model + temporal policy model) -### Vision inputs (Full size: 799906 x float32) -* **image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -* **wide image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -### Policy inputs -* **desire** - * one-hot encoded buffer to command model to execute certain actions, bit needs to be sent for the past 5 seconds (at 20FPS) : 100 * 8 -* **traffic convention** - * one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2 -* **lateral control params** - * speed and steering delay for predicting the desired curvature: 2 -* **previous desired curvatures** - * vector of previously predicted desired curvatures: 100 * 1 -* **feature buffer** - * a buffer of intermediate features including the current feature to form a 5 seconds temporal context (at 20FPS) : 100 * 512 - - -### Driving Model output format (Full size: XXX x float32) -Refer to **slice_outputs** and **parse_vision_outputs/parse_policy_outputs** in modeld. - - -## Driver Monitoring Model -* .onnx model can be run with onnx runtimes -* .dlc file is a pre-quantized model and only runs on qualcomm DSPs - -### input format -* single image W = 1440 H = 960 luminance channel (Y) from the planar YUV420 format: - * full input size is 1440 * 960 = 1382400 - * normalized ranging from 0.0 to 1.0 in float32 (onnx runner) or ranging from 0 to 255 in uint8 (snpe runner) -* camera calibration angles (roll, pitch, yaw) from liveCalibration: 3 x float32 inputs - -### output format -* 84 x float32 outputs = 2 + 41 * 2 ([parsing example](https://github.com/commaai/openpilot/blob/22ce4e17ba0d3bfcf37f8255a4dd1dc683fe0c38/selfdrive/modeld/models/dmonitoring.cc#L33)) - * for each person in the front seats (2 * 41) - * face pose: 12 = 6 + 6 - * face orientation [pitch, yaw, roll] in camera frame: 3 - * face position [dx, dy] relative to image center: 2 - * normalized face size: 1 - * standard deviations for above outputs: 6 - * face visible probability: 1 - * eyes: 20 = (8 + 1) + (8 + 1) + 1 + 1 - * eye position and size, and their standard deviations: 8 - * eye visible probability: 1 - * eye closed probability: 1 - * wearing sunglasses probability: 1 - * face occluded probability: 1 - * touching wheel probability: 1 - * paying attention probability: 1 - * (deprecated) distracted probabilities: 2 - * using phone probability: 1 - * distracted probability: 1 - * common outputs 1 - * left hand drive probability: 1 diff --git a/selfdrive/modeld/models/big_driving_supercombo.onnx b/selfdrive/modeld/models/big_driving_supercombo.onnx deleted file mode 100644 index de84325912..0000000000 --- a/selfdrive/modeld/models/big_driving_supercombo.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:471f372751d5931e939320c211e35b7255f8fa8015125b3b3fd48ef43020257e -size 195490097 diff --git a/selfdrive/test/setup_xvfb.sh b/selfdrive/test/setup_xvfb.sh deleted file mode 100755 index 50b313658d..0000000000 --- a/selfdrive/test/setup_xvfb.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -# Sets up a virtual display for running map renderer and simulator without an X11 display - -if uname -r | grep -q "WSL2"; then - DISP_ID=0 # WSLg uses display :0 -else - DISP_ID=99 # Standard Xvfb display -fi -export DISPLAY=:$DISP_ID - -Xvfb $DISPLAY -screen 0 2160x1080x24 2>/dev/null & - -# check for x11 socket for the specified display ID -while [ ! -S /tmp/.X11-unix/X$DISP_ID ] -do - echo "Waiting for Xvfb..." - sleep 1 -done - -touch ~/.Xauthority -export XDG_SESSION_TYPE="x11" \ No newline at end of file diff --git a/sunnypilot/selfdrive/car/car_list.json b/sunnypilot/selfdrive/car/car_list.json deleted file mode 120000 index a4ae7b75f9..0000000000 --- a/sunnypilot/selfdrive/car/car_list.json +++ /dev/null @@ -1 +0,0 @@ -../../../opendbc_repo/opendbc/sunnypilot/car/car_list.json \ No newline at end of file diff --git a/system/loggerd/encoder/jpeg_encoder.cc b/system/loggerd/encoder/jpeg_encoder.cc deleted file mode 100644 index 6bb946157c..0000000000 --- a/system/loggerd/encoder/jpeg_encoder.cc +++ /dev/null @@ -1,105 +0,0 @@ -#include "system/loggerd/encoder/jpeg_encoder.h" - -#include -#include - -JpegEncoder::JpegEncoder(const std::string &pusblish_name, int width, int height) - : publish_name(pusblish_name), thumbnail_width(width), thumbnail_height(height) { - yuv_buffer.resize((thumbnail_width * ((thumbnail_height + 15) & ~15) * 3) / 2); - pm = std::make_unique(std::vector{pusblish_name.c_str()}); -} - -JpegEncoder::~JpegEncoder() { - if (out_buffer) { - free(out_buffer); - } -} - -void JpegEncoder::pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra) { - generateThumbnail(buf->y, buf->uv, buf->width, buf->height, buf->stride); - - MessageBuilder msg; - auto thumbnaild = msg.initEvent().initThumbnail(); - thumbnaild.setFrameId(extra.frame_id); - thumbnaild.setTimestampEof(extra.timestamp_eof); - thumbnaild.setThumbnail({out_buffer, out_size}); - - pm->send(publish_name.c_str(), msg); -} - -void JpegEncoder::generateThumbnail(const uint8_t *y_addr, const uint8_t *uv_addr, int width, int height, int stride) { - int downscale = width / thumbnail_width; - assert(downscale * thumbnail_height == height); - - // make the buffer big enough. jpeg_write_raw_data requires 16-pixels aligned height to be used. - uint8_t *y_plane = yuv_buffer.data(); - uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height; - uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4; - { - // subsampled conversion from nv12 to yuv - for (int hy = 0; hy < thumbnail_height / 2; hy++) { - for (int hx = 0; hx < thumbnail_width / 2; hx++) { - int ix = hx * downscale + (downscale - 1) / 2; - int iy = hy * downscale + (downscale - 1) / 2; - y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 0]; - y_plane[(hy * 2 + 0) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 0) * stride + ix * 2 + 1]; - y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 0)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 0]; - y_plane[(hy * 2 + 1) * thumbnail_width + (hx * 2 + 1)] = y_addr[(iy * 2 + 1) * stride + ix * 2 + 1]; - u_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 0]; - v_plane[hy * thumbnail_width / 2 + hx] = uv_addr[iy * stride + ix * 2 + 1]; - } - } - } - - compressToJpeg(y_plane, u_plane, v_plane); -} - -void JpegEncoder::compressToJpeg(uint8_t *y_plane, uint8_t *u_plane, uint8_t *v_plane) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - - if (out_buffer) { - free(out_buffer); - out_buffer = nullptr; - out_size = 0; - } - jpeg_mem_dest(&cinfo, &out_buffer, &out_size); - - cinfo.image_width = thumbnail_width; - cinfo.image_height = thumbnail_height; - cinfo.input_components = 3; - - jpeg_set_defaults(&cinfo); - jpeg_set_colorspace(&cinfo, JCS_YCbCr); - // configure sampling factors for yuv420. - cinfo.comp_info[0].h_samp_factor = 2; // Y - cinfo.comp_info[0].v_samp_factor = 2; - cinfo.comp_info[1].h_samp_factor = 1; // U - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; // V - cinfo.comp_info[2].v_samp_factor = 1; - cinfo.raw_data_in = TRUE; - - jpeg_set_quality(&cinfo, 50, TRUE); - jpeg_start_compress(&cinfo, TRUE); - - JSAMPROW y[16], u[8], v[8]; - JSAMPARRAY planes[3]{y, u, v}; - - for (int line = 0; line < cinfo.image_height; line += 16) { - for (int i = 0; i < 16; ++i) { - y[i] = y_plane + (line + i) * cinfo.image_width; - if (i % 2 == 0) { - int offset = (cinfo.image_width / 2) * ((i + line) / 2); - u[i / 2] = u_plane + offset; - v[i / 2] = v_plane + offset; - } - } - jpeg_write_raw_data(&cinfo, planes, 16); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); -} diff --git a/system/manager/process_config.py b/system/manager/process_config.py deleted file mode 100644 index 510395b93b..0000000000 --- a/system/manager/process_config.py +++ /dev/null @@ -1,209 +0,0 @@ -import os -import operator -import platform - -from cereal import car, custom -from openpilot.common.params import Params -from openpilot.common.hardware import PC, TICI -from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess -from openpilot.common.hardware.hw import Paths - -from openpilot.sunnypilot.mapd.mapd_manager import MAPD_PATH - -from openpilot.sunnypilot.models.helpers import get_active_model_runner -from openpilot.sunnypilot.sunnylink.utils import sunnylink_need_register, sunnylink_ready, use_sunnylink_uploader - -WEBCAM = os.getenv("USE_WEBCAM") is not None - -def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: - return started or params.get_bool("IsDriverViewEnabled") - -def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and CP.notCar - -def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not CP.notCar - -def logging(started: bool, params: Params, CP: car.CarParams) -> bool: - run = (not CP.notCar) or not params.get_bool("DisableLogging") - return started and run - -def ublox_available() -> bool: - return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') - -def ublox(started: bool, params: Params, CP: car.CarParams) -> bool: - use_ublox = ublox_available() - if use_ublox != params.get_bool("UbloxAvailable"): - params.put_bool("UbloxAvailable", use_ublox, block=True) - return started and use_ublox - -def joystick(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("JoystickDebugMode") - -def not_joystick(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not params.get_bool("JoystickDebugMode") - -def long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("LongitudinalManeuverMode") - -def lat_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("LateralManeuverMode") - -def not_long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not params.get_bool("LongitudinalManeuverMode") - -def qcomgps(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not ublox_available() - -def always_run(started: bool, params: Params, CP: car.CarParams) -> bool: - return True - -def only_onroad(started: bool, params: Params, CP: car.CarParams) -> bool: - return started - -def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: - return not started - -def livestream(started: bool, params: Params, CP: car.CarParams) -> bool: - return params.get_bool("IsLiveStreaming") - -def use_github_runner(started, params, CP: car.CarParams) -> bool: - return not PC and params.get_bool("EnableGithubRunner") and ( - not params.get_bool("NetworkMetered") and not params.get_bool("GithubRunnerSufficientVoltage")) - -def use_copyparty(started, params, CP: car.CarParams) -> bool: - return bool(params.get_bool("EnableCopyparty")) - -def sunnylink_ready_shim(started, params, CP: car.CarParams) -> bool: - """Shim for sunnylink_ready to match the process manager signature.""" - return sunnylink_ready(params) - -def sunnylink_need_register_shim(started, params, CP: car.CarParams) -> bool: - """Shim for sunnylink_need_register to match the process manager signature.""" - return sunnylink_need_register(params) - -def use_sunnylink_uploader_shim(started, params, CP: car.CarParams) -> bool: - """Shim for use_sunnylink_uploader to match the process manager signature.""" - return use_sunnylink_uploader(params) - -def is_tinygrad_model(started, params, CP: car.CarParams) -> bool: - """Check if the active model runner is SNPE.""" - return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.tinygrad) - -def is_stock_model(started, params, CP: car.CarParams) -> bool: - """Check if the active model runner is stock.""" - return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.stock) - -def mapd_ready(started: bool, params: Params, CP: car.CarParams) -> bool: - return bool(os.path.exists(Paths.mapd_root())) - -def uploader_ready(started: bool, params: Params, CP: car.CarParams) -> bool: - if not params.get_bool("OnroadUploads"): - return only_offroad(started, params, CP) - - return always_run(started, params, CP) - -def or_(*fns): - return lambda *args: operator.or_(*(fn(*args) for fn in fns)) - -def and_(*fns): - return lambda *args: operator.and_(*(fn(*args) for fn in fns)) - -def not_(*fns): - return lambda *args: operator.not_(*(fn(*args) for fn in fns)) - -procs = [ - DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), - - NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), - NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), - NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("logmessaged", "system.logmessaged", always_run), - - NativeProcess("camerad", "system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), - PythonProcess("webcamerad", "system.camerad.webcam.camerad", driverview, enabled=WEBCAM), - PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), - PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), - PythonProcess("micd", "system.micd", iscar), - PythonProcess("timed", "system.timed", always_run, enabled=not PC), - - PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)), - PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), - - PythonProcess("sensord", "system.sensord.sensord", only_onroad, enabled=not PC), - PythonProcess("ui", "selfdrive.ui.ui", always_run, restart_if_crash=True), - PythonProcess("soundd", "selfdrive.ui.soundd", driverview), - PythonProcess("locationd", "selfdrive.locationd.locationd", only_onroad), - NativeProcess("_pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False), - PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), - PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), - PythonProcess("controlsd", "selfdrive.controls.controlsd", and_(not_joystick, iscar)), - PythonProcess("joystickd", "tools.joystick.joystickd", or_(joystick, notcar)), - PythonProcess("selfdrived", "selfdrive.selfdrived.selfdrived", only_onroad), - PythonProcess("card", "selfdrive.car.card", only_onroad), - PythonProcess("deleter", "system.loggerd.deleter", always_run), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), - PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), - PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), - PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), - PythonProcess("lagd", "selfdrive.locationd.lagd", only_onroad), - PythonProcess("ubloxd", "system.ubloxd.ubloxd", ublox, enabled=TICI), - PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI), - PythonProcess("plannerd", "selfdrive.controls.plannerd", not_long_maneuver), - PythonProcess("maneuversd", "tools.longitudinal_maneuvers.maneuversd", long_maneuver), - PythonProcess("lateral_maneuversd", "tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), - PythonProcess("radard", "selfdrive.controls.radard", only_onroad), - PythonProcess("hardwared", "system.hardware.hardwared", always_run), - PythonProcess("modem", "common.hardware.tici.modem", always_run, enabled=TICI), - PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), - PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), - PythonProcess("uploader", "system.loggerd.uploader", uploader_ready), - PythonProcess("statsd", "system.statsd", always_run), - PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), - - # debug procs - NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), - PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), - - # sunnylink <3 - DaemonProcess("manage_sunnylinkd", "sunnypilot.sunnylink.athena.manage_sunnylinkd", "SunnylinkdPid"), - PythonProcess("sunnylink_registration_manager", "sunnypilot.sunnylink.registration_manager", sunnylink_need_register_shim), - PythonProcess("statsd_sp", "sunnypilot.sunnylink.statsd", and_(always_run, sunnylink_ready_shim)), -] - -# sunnypilot -procs += [ - # Models - PythonProcess("models_manager", "sunnypilot.models.manager", only_offroad), - NativeProcess("modeld_tinygrad", "sunnypilot/modeld_v2", ["./modeld"], and_(only_onroad, is_tinygrad_model)), - - # Backup - PythonProcess("backup_manager", "sunnypilot.sunnylink.backups.manager", and_(only_offroad, sunnylink_ready_shim)), - - # mapd - NativeProcess("mapd", Paths.mapd_root(), ["bash", "-c", f"{MAPD_PATH} > /dev/null 2>&1"], mapd_ready), - PythonProcess("mapd_manager", "sunnypilot.mapd.mapd_manager", always_run), - - # locationd - NativeProcess("locationd_llk", "sunnypilot/selfdrive/locationd", ["./locationd"], only_onroad), -] - -if os.path.exists("./github_runner.sh"): - procs += [NativeProcess("github_runner_start", "system/manager", ["./github_runner.sh", "start"], and_(only_offroad, use_github_runner), sigkill=False)] - -if os.path.exists("../../sunnypilot/sunnylink/uploader.py"): - procs += [PythonProcess("sunnylink_uploader", "sunnypilot.sunnylink.uploader", use_sunnylink_uploader_shim)] - -if os.path.exists("../../third_party/copyparty/copyparty-sfx.py"): - sunnypilot_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) - copyparty_args = [f"-v{Paths.crash_log_root()}:/swaglogs:r"] - copyparty_args += [f"-v{Paths.log_root()}:/routes:r"] - copyparty_args += [f"-v{Paths.model_root()}:/models:rw"] - copyparty_args += [f"-v{sunnypilot_root}:/sunnypilot:rw"] - copyparty_args += ["-p8080"] - copyparty_args += ["-z"] - copyparty_args += ["-q"] - procs += [NativeProcess("copyparty-sfx", "third_party/copyparty", ["./copyparty-sfx.py", *copyparty_args], and_(only_offroad, use_copyparty))] - -managed_processes = {p.name: p for p in procs} diff --git a/teleoprtc b/teleoprtc deleted file mode 120000 index 3d3dbc8dea..0000000000 --- a/teleoprtc +++ /dev/null @@ -1 +0,0 @@ -teleoprtc_repo/teleoprtc \ No newline at end of file diff --git a/tinygrad b/tinygrad deleted file mode 120000 index cb003823c6..0000000000 --- a/tinygrad +++ /dev/null @@ -1 +0,0 @@ -tinygrad_repo/tinygrad \ No newline at end of file diff --git a/tools/CTF.md b/tools/CTF.md index 609c82ad5a..2b877a0e25 100644 --- a/tools/CTF.md +++ b/tools/CTF.md @@ -5,16 +5,16 @@ Welcome to the first part of the comma CTF! * there's 2 flags in each segment, with roughly increasing difficulty * everything you'll need to find the flags is in the openpilot repo * grep is also your friend - * first, [setup](https://github.com/commaai/openpilot/tree/master/tools#setup-your-pc) your PC - * read the docs & checkout out the tools in tools/ + * first, [setup](https://github.com/commaai/openpilot/tree/master/openpilot/tools#setup-your-pc) your PC + * read the docs & checkout out the tools in openpilot/tools/ * tip: once you get the replay and UI up, start by familiarizing yourself with seeking in replay getting started ```bash # start the route replay -cd tools/replay +cd openpilot/tools/replay ./replay '0c7f0c7f0c7f0c7f|2021-10-13--13-00-00' --dcam --ecam # start the UI in another terminal -selfdrive/ui/ui +openpilot/selfdrive/ui/ui ``` diff --git a/tools/car_porting/README.md b/tools/car_porting/README.md index 77492035ca..07ca2d0eba 100644 --- a/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -6,13 +6,13 @@ Check out [this blog post](https://blog.comma.ai/how-to-write-a-car-port-for-ope Testing car ports in your car is very time-consuming. Check out these utilities to do basic checks on your work before running it in your car. -### [Cabana](/tools/cabana/README.md) +### [Cabana](/openpilot/tools/cabana/README.md) View your car's CAN signals through DBC files, which openpilot uses to parse and create messages that talk to the car. Example: ```bash -> tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43' +> openpilot/tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43' ``` ### [tools/car_porting/auto_fingerprint.py](/tools/car_porting/auto_fingerprint.py) @@ -25,17 +25,17 @@ Example: Attempting to add fw version for: OUTBACK ``` -### [selfdrive/car/tests/test_car_interfaces.py](/selfdrive/car/tests/test_car_interfaces.py) +### [openpilot/selfdrive/car/tests/test_car_interfaces.py](/openpilot/selfdrive/car/tests/test_car_interfaces.py) Finds common bugs for car interfaces, without even requiring a route. #### Example: Typo in signal name ```bash -> pytest selfdrive/car/tests/test_car_interfaces.py -k subaru # replace with the brand you are working on +> pytest openpilot/selfdrive/car/tests/test_car_interfaces.py -k subaru # replace with the brand you are working on ===================================================================== -FAILED selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS' +FAILED openpilot/selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS' ``` diff --git a/tools/car_porting/measure_steering_accuracy.py b/tools/car_porting/measure_steering_accuracy.py index ae3344c2eb..fa1da959a7 100755 --- a/tools/car_porting/measure_steering_accuracy.py +++ b/tools/car_porting/measure_steering_accuracy.py @@ -6,7 +6,7 @@ import argparse import signal from collections import defaultdict -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.tools.lib.logreader import LogReader def sigint_handler(signal, frame): diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index dd248f562e..20e7d136ea 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -2,7 +2,6 @@ import argparse import sys import unittest # noqa: TID251 - from opendbc.car.tests.routes import CarTestRoute from openpilot.selfdrive.car.tests.test_models import TestCarModel from openpilot.tools.lib.route import SegmentRange @@ -20,7 +19,7 @@ def create_test_models_suite(routes: list[CarTestRoute]) -> unittest.TestSuite: if __name__ == "__main__": parser = argparse.ArgumentParser(description="Test any route against common issues with a new car port. " + - "Uses selfdrive/car/tests/test_models.py") + "Uses openpilot/selfdrive/car/tests/test_models.py") parser.add_argument("route_or_segment_name", help="Specify route to run tests on") parser.add_argument("--car", help="Specify car model for test route") args = parser.parse_args() diff --git a/tools/op.sh b/tools/op.sh index ecef240b5b..1ee7b232b0 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -75,7 +75,7 @@ function op_get_openpilot_dir() { # Fallback to hardcoded directories if not found SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" - for dir in "${SCRIPT_DIR%/tools}" "$HOME/openpilot" "/data/openpilot"; do + for dir in "$(readlink -f "$SCRIPT_DIR/../..")" "$HOME/openpilot" "/data/openpilot"; do if [[ -f "$dir/launch_openpilot.sh" ]]; then OPENPILOT_ROOT="$dir" return 0 @@ -116,7 +116,7 @@ function op_check_git() { fi echo "Checking for git lfs files..." - if [[ $(file -b $OPENPILOT_ROOT/selfdrive/modeld/models/dmonitoring_model.onnx) == "data" ]]; then + if [[ $(file -b $OPENPILOT_ROOT/openpilot/selfdrive/modeld/models/dmonitoring_model.onnx) == "data" ]]; then echo -e " ↳ [${GREEN}✔${NC}] git lfs files found." else echo -e " ↳ [${RED}✗${NC}] git lfs files not found! Run 'git lfs pull'" @@ -199,6 +199,17 @@ function op_setup() { op_check_openpilot_dir op_check_os + # Submodules must be present before uv sync: pyproject path sources + # (pandacan, opendbc, msgq, ...) live in the submodule checkouts. + echo "Getting git submodules..." + st="$(date +%s)" + if ! retry 3 git submodule update --jobs 4 --init --recursive; then + echo -e " ↳ [${RED}✗${NC}] Getting git submodules failed!" + return 1 + fi + et="$(date +%s)" + echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully in $((et - st)) seconds." + echo "Installing dependencies..." st="$(date +%s)" SETUP_SCRIPT="tools/setup_dependencies.sh" @@ -211,15 +222,6 @@ function op_setup() { op_activate_venv - echo "Getting git submodules..." - st="$(date +%s)" - if ! retry 3 git submodule update --jobs 4 --init --recursive; then - echo -e " ↳ [${RED}✗${NC}] Getting git submodules failed!" - return 1 - fi - et="$(date +%s)" - echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully in $((et - st)) seconds." - echo "Pulling git lfs files..." st="$(date +%s)" if ! retry 3 git lfs pull; then @@ -234,7 +236,7 @@ function op_setup() { function op_auth() { op_before_cmd - op_run_command tools/lib/auth.py "$@" + op_run_command openpilot/tools/lib/auth.py "$@" } function op_activate_venv() { @@ -298,7 +300,7 @@ function op_check() { function op_esim() { op_before_cmd - op_run_command common/esim/esim.py "$@" + op_run_command openpilot/common/esim/esim.py "$@" } function op_build() { @@ -307,16 +309,15 @@ function op_build() { cd "$CDIR" if [[ -f "/AGNOS" ]]; then # needed on AGNOS to not run out of memory - op_run_command system/manager/build.py + op_run_command openpilot/system/manager/build.py else - # scons is fine on PC - op_run_command scons "$@" + op_run_command scons -u "$@" fi } function op_juggle() { op_before_cmd - op_run_command tools/plotjuggler/juggle.py "$@" + op_run_command openpilot/tools/plotjuggler/juggle.py "$@" } function op_lint() { @@ -331,23 +332,23 @@ function op_test() { function op_replay() { op_before_cmd - op_run_command tools/replay/replay "$@" + op_run_command openpilot/tools/replay/replay "$@" } function op_cabana() { op_before_cmd - op_run_command tools/cabana/cabana "$@" + op_run_command openpilot/tools/cabana/cabana "$@" } function op_sim() { op_before_cmd - op_run_command exec tools/sim/run_bridge.py & - op_run_command exec tools/sim/launch_openpilot.sh + op_run_command exec openpilot/tools/sim/run_bridge.py & + op_run_command exec openpilot/tools/sim/launch_openpilot.sh } function op_clip() { op_before_cmd - op_run_command tools/clip/run.py "$@" + op_run_command openpilot/tools/clip/run.py "$@" } function op_switch() { diff --git a/release/README.md b/tools/release/README.md similarity index 82% rename from release/README.md rename to tools/release/README.md index 7aeea9fe4a..862836bf90 100644 --- a/release/README.md +++ b/tools/release/README.md @@ -11,8 +11,8 @@ - [ ] push the new branch - [ ] push to staging: - [ ] make sure you are on the newly created release master branch (`zerotentwo`) - - [ ] run `BRANCH=devel-staging release/build_stripped.sh`. Jenkins will then automatically build staging on device, run `test_onroad` and update the staging branch -- [ ] bump version on master: `common/version.h` and `RELEASES.md` + - [ ] run `BRANCH=devel-staging tools/release/build_stripped.sh`. Jenkins will then automatically build staging on device, run `test_onroad` and update the staging branch +- [ ] bump version on master: `openpilot/common/version.h` and `RELEASES.md` - [ ] post on Discord, tag `@release crew` ### Go to release diff --git a/release/build_release.sh b/tools/release/build_release.sh similarity index 76% rename from release/build_release.sh rename to tools/release/build_release.sh index c038e0e78e..6a019a80d0 100755 --- a/release/build_release.sh +++ b/tools/release/build_release.sh @@ -33,7 +33,7 @@ git checkout --orphan $BUILD_BRANCH # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./release/release_files.py) $BUILD_DIR/ +cp -pR --parents $(./tools/release/release_files.py) $BUILD_DIR/ # in the directory cd $BUILD_DIR @@ -41,7 +41,7 @@ cd $BUILD_DIR rm -f panda/board/obj/panda.bin.signed rm -f panda/board/obj/panda_h7.bin.signed -VERSION=$(cat sunnypilot/common/version.h | awk -F[\"-] '{print $2}') +VERSION=$(cat openpilot/sunnypilot/common/version.h | awk -F[\"-] '{print $2}') echo "[-] committing version $VERSION T=$SECONDS" git add -f . git commit -a -m "openpilot v$VERSION release" @@ -73,16 +73,16 @@ find . -name '*.os' -delete find . -name '*.pyc' -delete find . -name 'moc_*' -delete find . -name '__pycache__' -delete -rm -rf .sconsign.dblite Jenkinsfile release/ -rm -f selfdrive/modeld/models/*.onnx* -rm -f sunnypilot/modeld*/models/*.onnx* +rm -rf .sconsign.dblite Jenkinsfile tools/release/ +rm -f openpilot/selfdrive/modeld/models/*.onnx* +rm -f openpilot/sunnypilot/modeld*/models/*.onnx* -find third_party/ -name '*x86*' -exec rm -r {} + -find third_party/ -name '*Darwin*' -exec rm -r {} + +find openpilot/third_party/ -name '*x86*' -exec rm -r {} + +find openpilot/third_party/ -name '*Darwin*' -exec rm -r {} + # Restore third_party -git checkout third_party/ +git checkout openpilot/third_party/ # Mark as prebuilt release touch prebuilt @@ -93,8 +93,8 @@ git commit --amend -m "openpilot v$VERSION" # Run tests cd $BUILD_DIR -RELEASE=1 pytest -n0 -s selfdrive/test/test_onroad.py -#pytest selfdrive/car/tests/test_car_interfaces.py +RELEASE=1 pytest -n0 -s openpilot/selfdrive/test/test_onroad.py +#pytest openpilot/selfdrive/car/tests/test_car_interfaces.py echo "[-] pushing release T=$SECONDS" REFS=() diff --git a/release/build_stripped.sh b/tools/release/build_stripped.sh similarity index 87% rename from release/build_stripped.sh rename to tools/release/build_stripped.sh index 8e73a8aaab..b5092b15a7 100755 --- a/release/build_stripped.sh +++ b/tools/release/build_stripped.sh @@ -38,20 +38,20 @@ git submodule foreach --recursive git clean -xdff # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./release/release_files.py) $TARGET_DIR/ +./tools/release/release_files.py | xargs -d '\n' cp -pR --parents -t "$TARGET_DIR" # in the directory cd $TARGET_DIR rm -rf .git/modules/ rm -f panda/board/obj/panda.bin.signed -find selfdrive/modeld/models -name '*.onnx' -size +95M -exec ./common/file_chunker.py {} \; +find openpilot/selfdrive/modeld/models -name '*.onnx' -size +95M -exec ./openpilot/common/file_chunker.py {} \; # include source commit hash and build date in commit GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) GIT_COMMIT_DATE=$(git --git-dir=$SOURCE_DIR/.git show --no-patch --format='%ct %ci' HEAD) DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') -VERSION=$(cat $SOURCE_DIR/sunnypilot/common/version.h | awk -F\" '{print $2}') +VERSION=$(cat $SOURCE_DIR/openpilot/sunnypilot/common/version.h | awk -F\" '{print $2}') echo -n "$GIT_HASH" > git_src_commit echo -n "$GIT_COMMIT_DATE" > git_src_commit_date diff --git a/release/check-dirty.sh b/tools/release/check-dirty.sh similarity index 100% rename from release/check-dirty.sh rename to tools/release/check-dirty.sh diff --git a/release/check-submodules.sh b/tools/release/check-submodules.sh similarity index 100% rename from release/check-submodules.sh rename to tools/release/check-submodules.sh diff --git a/release/identity.sh b/tools/release/identity.sh similarity index 100% rename from release/identity.sh rename to tools/release/identity.sh diff --git a/release/pack.py b/tools/release/pack.py similarity index 96% rename from release/pack.py rename to tools/release/pack.py index 560500e7a7..f29ea034db 100755 --- a/release/pack.py +++ b/tools/release/pack.py @@ -11,9 +11,9 @@ from pathlib import Path from openpilot.common.basedir import BASEDIR -DIRS = ['cereal', 'openpilot'] +DIRS = ['openpilot'] EXTS = ['.png', '.py', '.ttf', '.capnp', '.json', '.fnt', '.mo', '.po'] -EXCLUDE = ['selfdrive/assets/training'] +EXCLUDE = ['openpilot/selfdrive/assets/training'] INTERPRETER = '/usr/bin/env python3' diff --git a/release/release_files.py b/tools/release/release_files.py similarity index 93% rename from release/release_files.py rename to tools/release/release_files.py index 0b9e034bf1..7f08719ea8 100755 --- a/release/release_files.py +++ b/tools/release/release_files.py @@ -4,7 +4,7 @@ import re from pathlib import Path HERE = os.path.abspath(os.path.dirname(__file__)) -ROOT = HERE + "/.." +ROOT = os.path.abspath(os.path.join(HERE, "../..")) blacklist = [ ".git/", diff --git a/tools/scripts/adb_ssh.sh b/tools/scripts/adb_ssh.sh index b9668e7e0b..c584a72f2b 100755 --- a/tools/scripts/adb_ssh.sh +++ b/tools/scripts/adb_ssh.sh @@ -5,7 +5,7 @@ set -euo pipefail while IFS=' ' read -r name port; do adb forward "tcp:${port}" "tcp:${port}" > /dev/null done < <(python3 - <<'PY' -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST FNV_PRIME = 0x100000001b3 FNV_OFFSET_BASIS = 0xcbf29ce484222325 diff --git a/tools/scripts/car/can_print_changes.py b/tools/scripts/car/can_print_changes.py index c2e152e1e0..e466cd2968 100755 --- a/tools/scripts/car/can_print_changes.py +++ b/tools/scripts/car/can_print_changes.py @@ -4,8 +4,8 @@ import binascii import time from collections import defaultdict -import cereal.messaging as messaging -from openpilot.tools.scripts.can_table import can_table +import openpilot.cereal.messaging as messaging +from tools.scripts.car.can_table import can_table from openpilot.tools.lib.logreader import LogIterable, LogReader RED = '\033[91m' diff --git a/tools/scripts/car/can_printer.py b/tools/scripts/car/can_printer.py index f2ed6730d3..85f129f795 100755 --- a/tools/scripts/car/can_printer.py +++ b/tools/scripts/car/can_printer.py @@ -4,7 +4,7 @@ import binascii import time from collections import defaultdict -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def can_printer(bus, max_msg, addr, ascii_decode): diff --git a/tools/scripts/car/can_table.py b/tools/scripts/car/can_table.py index 11d070e708..e2d9874fec 100755 --- a/tools/scripts/car/can_table.py +++ b/tools/scripts/car/can_table.py @@ -2,7 +2,7 @@ import argparse import pandas as pd -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def can_table(dat): diff --git a/tools/scripts/car/disable_ecu.py b/tools/scripts/car/disable_ecu.py index 14d0cbb9cf..884b86896b 100755 --- a/tools/scripts/car/disable_ecu.py +++ b/tools/scripts/car/disable_ecu.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.disable_ecu import disable_ecu from openpilot.selfdrive.car.card import can_comm_callbacks diff --git a/tools/scripts/car/ecu_addrs.py b/tools/scripts/car/ecu_addrs.py index f3f06406c0..0dfce880b0 100755 --- a/tools/scripts/car/ecu_addrs.py +++ b/tools/scripts/car/ecu_addrs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.carlog import carlog from opendbc.car.ecu_addrs import get_all_ecu_addrs from openpilot.common.params import Params @@ -26,9 +26,9 @@ if __name__ == "__main__": # Set up params for pandad params = Params() params.remove("FirmwareQueryDone") - params.put_bool("IsOnroad", False, block=True) + params.put_bool("IsOffroad", True, block=True) time.sleep(0.2) # thread is 10 Hz - params.put_bool("IsOnroad", True, block=True) + params.put_bool("IsOffroad", False, block=True) obd_callback(params)(not args.no_obd) diff --git a/tools/scripts/car/fw_versions.py b/tools/scripts/car/fw_versions.py index b04f9cd2a6..e68447d69e 100755 --- a/tools/scripts/car/fw_versions.py +++ b/tools/scripts/car/fw_versions.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 import time import argparse -import cereal.messaging as messaging -from cereal import car +import openpilot.cereal.messaging as messaging +from opendbc.car.structs import car from opendbc.car.carlog import carlog from opendbc.car.fw_versions import get_fw_versions, match_fw_to_car from opendbc.car.vin import get_vin @@ -30,9 +30,9 @@ if __name__ == "__main__": # Set up params for pandad params = Params() params.remove("FirmwareQueryDone") - params.put_bool("IsOnroad", False, block=True) + params.put_bool("IsOffroad", True, block=True) time.sleep(0.2) # thread is 10 Hz - params.put_bool("IsOnroad", True, block=True) + params.put_bool("IsOffroad", False, block=True) set_obd_multiplexing = obd_callback(params) extra: Any = None diff --git a/tools/scripts/car/hyundai_enable_radar_points.py b/tools/scripts/car/hyundai_enable_radar_points.py index 1cab7b0270..5fbd13f2b0 100755 --- a/tools/scripts/car/hyundai_enable_radar_points.py +++ b/tools/scripts/car/hyundai_enable_radar_points.py @@ -15,7 +15,6 @@ import sys import argparse from typing import NamedTuple from subprocess import check_output, CalledProcessError - from opendbc.car.carlog import carlog from opendbc.car.uds import UdsClient, SESSION_TYPE, DATA_IDENTIFIER_TYPE from opendbc.car.structs import CarParams diff --git a/tools/scripts/car/measure_torque_time_to_max.py b/tools/scripts/car/measure_torque_time_to_max.py index e99aeae464..df41e5738e 100755 --- a/tools/scripts/car/measure_torque_time_to_max.py +++ b/tools/scripts/car/measure_torque_time_to_max.py @@ -6,8 +6,8 @@ import struct from collections import deque from statistics import mean -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging if __name__ == "__main__": diff --git a/tools/scripts/car/vin.py b/tools/scripts/car/vin.py index 9b1d6528cc..732d3d3f4a 100755 --- a/tools/scripts/car/vin.py +++ b/tools/scripts/car/vin.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.carlog import carlog from opendbc.car.vin import get_vin from openpilot.selfdrive.car.card import can_comm_callbacks diff --git a/tools/scripts/count_events.py b/tools/scripts/count_events.py index 76e02d414e..a7e71210ac 100755 --- a/tools/scripts/count_events.py +++ b/tools/scripts/count_events.py @@ -6,7 +6,7 @@ from collections import Counter from pprint import pprint from typing import cast -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.logreader import LogReader, ReadMode from openpilot.selfdrive.test.process_replay.migration import migrate_all diff --git a/tools/scripts/cpu_usage_stat.py b/tools/scripts/cpu_usage_stat.py deleted file mode 100755 index 5b72eacc65..0000000000 --- a/tools/scripts/cpu_usage_stat.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -''' -System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs. - Features: - Use psutil library to sample cpu usage(avergage for all cores) of openpilot processes, at a rate of 5 samples/sec. - Do cpu usage statistics periodically, 5 seconds as a cycle. - Calculate the average cpu usage within this cycle. - Calculate minumium/maximum/accumulated_average cpu usage as long term inspections. - Monitor multiple processes simuteneously. - Sample usage: - root@localhost:/data/openpilot$ python tools/scripts/cpu_usage_stat.py pandad,ubloxd - ('Add monitored proc:', './pandad') - ('Add monitored proc:', 'python locationd/ubloxd.py') - pandad: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% - ubloxd.py: 0.39%, min: 0.39%, max: 0.39%, acc: 0.39% -''' -import psutil -import time -import os -import sys -import numpy as np -import argparse -import re -from collections import defaultdict - -from openpilot.system.manager.process_config import managed_processes - -# Do statistics every 5 seconds -PRINT_INTERVAL = 5 -SLEEP_INTERVAL = 0.2 - -monitored_proc_names = [ - # android procs - 'SurfaceFlinger', 'sensors.qcom' -] + list(managed_processes.keys()) - -cpu_time_names = ['user', 'system', 'children_user', 'children_system'] - - -def get_arg_parser(): - parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument("proc_names", nargs="?", default='', - help="Process names to be monitored, comma separated") - parser.add_argument("--list_all", action='store_true', - help="Show all running processes' cmdline") - parser.add_argument("--detailed_times", action='store_true', - help="show cpu time details (split by user, system, child user, child system)") - return parser - - -if __name__ == "__main__": - args = get_arg_parser().parse_args(sys.argv[1:]) - if args.list_all: - for p in psutil.process_iter(): - print('cmdline', p.cmdline(), 'name', p.name()) - sys.exit(0) - - if len(args.proc_names) > 0: - monitored_proc_names = args.proc_names.split(',') - monitored_procs = [] - stats = {} - for p in psutil.process_iter(): - if p == psutil.Process(): - continue - matched = any(l for l in p.cmdline() if any(pn for pn in monitored_proc_names if re.match(fr'.*{pn}.*', l, re.M | re.I))) - if matched: - k = ' '.join(p.cmdline()) - print('Add monitored proc:', k) - stats[k] = {'cpu_samples': defaultdict(list), 'min': defaultdict(lambda: None), 'max': defaultdict(lambda: None), - 'avg': defaultdict(float), 'last_cpu_times': None, 'last_sys_time': None} - stats[k]['last_sys_time'] = time.monotonic() - stats[k]['last_cpu_times'] = p.cpu_times() - monitored_procs.append(p) - i = 0 - interval_int = int(PRINT_INTERVAL / SLEEP_INTERVAL) - while True: - for p in monitored_procs: - k = ' '.join(p.cmdline()) - cur_sys_time = time.monotonic() - cur_cpu_times = p.cpu_times() - cpu_times = np.subtract(cur_cpu_times, stats[k]['last_cpu_times']) / (cur_sys_time - stats[k]['last_sys_time']) - stats[k]['last_sys_time'] = cur_sys_time - stats[k]['last_cpu_times'] = cur_cpu_times - cpu_percent = 0 - for num, name in enumerate(cpu_time_names): - stats[k]['cpu_samples'][name].append(cpu_times[num]) - cpu_percent += cpu_times[num] - stats[k]['cpu_samples']['total'].append(cpu_percent) - time.sleep(SLEEP_INTERVAL) - i += 1 - if i % interval_int == 0: - l = [] - for k, stat in stats.items(): - if len(stat['cpu_samples']) <= 0: - continue - for name, samples in stat['cpu_samples'].items(): - samples = np.array(samples) - avg = samples.mean() - c = samples.size - min_cpu = np.amin(samples) - max_cpu = np.amax(samples) - if stat['min'][name] is None or min_cpu < stat['min'][name]: - stat['min'][name] = min_cpu - if stat['max'][name] is None or max_cpu > stat['max'][name]: - stat['max'][name] = max_cpu - stat['avg'][name] = (stat['avg'][name] * (i - c) + avg * c) / (i) - stat['cpu_samples'][name] = [] - - msg = f"avg: {stat['avg']['total']:.2%}, min: {stat['min']['total']:.2%}, max: {stat['max']['total']:.2%} {os.path.basename(k)}" - if args.detailed_times: - for stat_type in ['avg', 'min', 'max']: - msg += f"\n {stat_type}: {[(name + ':' + str(round(stat[stat_type][name] * 100, 2))) for name in cpu_time_names]}" - l.append((os.path.basename(k), stat['avg']['total'], msg)) - l.sort(key=lambda x: -x[1]) - for x in l: - print(x[2]) - print('avg sum: {:.2%} over {} samples {} seconds\n'.format( - sum(stat['avg']['total'] for k, stat in stats.items()), i, i * SLEEP_INTERVAL - )) diff --git a/tools/scripts/cycle_alerts.py b/tools/scripts/cycle_alerts.py index 4b1def4fc6..0bd42bcd3f 100755 --- a/tools/scripts/cycle_alerts.py +++ b/tools/scripts/cycle_alerts.py @@ -2,8 +2,9 @@ import time import random -from cereal import car, log -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from opendbc.car.honda.interface import CarInterface from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.selfdrived.events import ET, Events diff --git a/tools/scripts/debug_fw_fingerprinting_offline.py b/tools/scripts/debug_fw_fingerprinting_offline.py index d36b350bbc..b33817e944 100755 --- a/tools/scripts/debug_fw_fingerprinting_offline.py +++ b/tools/scripts/debug_fw_fingerprinting_offline.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 import argparse - from opendbc.car import uds from openpilot.tools.lib.live_logreader import live_logreader from openpilot.tools.lib.logreader import LogReader, ReadMode diff --git a/tools/scripts/dump.py b/tools/scripts/dump.py index 78cf51e3db..e4f5495f9b 100755 --- a/tools/scripts/dump.py +++ b/tools/scripts/dump.py @@ -4,8 +4,8 @@ import argparse import json import codecs -from cereal import log -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.live_logreader import raw_live_logreader @@ -25,7 +25,7 @@ def hexdump(msg): if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Dump communication sockets. See cereal/services.py for a complete list of available sockets.') + parser = argparse.ArgumentParser(description='Dump communication sockets. See openpilot/cereal/services.py for a complete list of available sockets.') parser.add_argument('--pipe', action='store_true') parser.add_argument('--raw', action='store_true') parser.add_argument('--json', action='store_true') diff --git a/tools/scripts/filter_log_message.py b/tools/scripts/filter_log_message.py index 9cbab0b41f..1ec0333169 100755 --- a/tools/scripts/filter_log_message.py +++ b/tools/scripts/filter_log_message.py @@ -2,7 +2,7 @@ import argparse import json -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.tools.lib.logreader import LogReader LEVELS = { @@ -13,7 +13,7 @@ LEVELS = { "CRITICAL": 50, } -ANDROID_LOG_SOURCE = { +OPERATING_SYSTEM_LOG_SOURCE = { 0: "MAIN", 1: "RADIO", 2: "EVENTS", @@ -34,8 +34,8 @@ def print_logmessage(t, msg, min_level): print(f"[{t / 1e9:.6f}] decode error: {msg}") -def print_androidlog(t, msg): - source = ANDROID_LOG_SOURCE[msg.id] +def print_operating_system_log(t, msg): + source = msg.tag or OPERATING_SYSTEM_LOG_SOURCE.get(msg.id, "SYSTEM") try: m = json.loads(msg.message)['MESSAGE'] except Exception: @@ -65,15 +65,15 @@ if __name__ == "__main__": print_logmessage(m.logMonoTime-st, m.logMessage, min_level) elif m.which() == 'errorLogMessage': print_logmessage(m.logMonoTime-st, m.errorLogMessage, min_level) - elif m.which() == 'androidLog': - print_androidlog(m.logMonoTime-st, m.androidLog) + elif m.which() == 'operatingSystemLog': + print_operating_system_log(m.logMonoTime-st, m.operatingSystemLog) else: - sm = messaging.SubMaster(['logMessage', 'androidLog'], addr=args.addr) + sm = messaging.SubMaster(['logMessage', 'operatingSystemLog'], addr=args.addr) while True: sm.update() if sm.updated['logMessage']: print_logmessage(sm.logMonoTime['logMessage'], sm['logMessage'], min_level) - if sm.updated['androidLog']: - print_androidlog(sm.logMonoTime['androidLog'], sm['androidLog']) + if sm.updated['operatingSystemLog']: + print_operating_system_log(sm.logMonoTime['operatingSystemLog'], sm['operatingSystemLog']) diff --git a/tools/scripts/fuzz_fw_fingerprint.py b/tools/scripts/fuzz_fw_fingerprint.py index b4276c0c1a..5b0ba9cfd0 100755 --- a/tools/scripts/fuzz_fw_fingerprint.py +++ b/tools/scripts/fuzz_fw_fingerprint.py @@ -3,7 +3,6 @@ import random from collections import defaultdict from tqdm import tqdm - from opendbc.car.fw_versions import match_fw_to_car_fuzzy from opendbc.car.toyota.values import FW_VERSIONS as TOYOTA_FW_VERSIONS from opendbc.car.honda.values import FW_VERSIONS as HONDA_FW_VERSIONS diff --git a/tools/scripts/get_fingerprint.py b/tools/scripts/get_fingerprint.py index 75c3d5579f..1e5e8eca5a 100755 --- a/tools/scripts/get_fingerprint.py +++ b/tools/scripts/get_fingerprint.py @@ -4,13 +4,13 @@ # Instructions: # - connect to a Panda -# - run selfdrive/pandad/pandad +# - run openpilot/selfdrive/pandad/pandad # - launching this script # Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint # - since some messages are published at low frequency, keep this script running for at least 30s, # until all messages are received at least once -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging logcan = messaging.sub_sock('can') msgs = {} diff --git a/tools/scripts/live_cpu_and_temp.py b/tools/scripts/live_cpu_and_temp.py index ee0524ec9d..484207d0fe 100755 --- a/tools/scripts/live_cpu_and_temp.py +++ b/tools/scripts/live_cpu_and_temp.py @@ -4,7 +4,7 @@ import numpy as np import capnp from collections import defaultdict -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster def cputime_total(ct): return ct.user + ct.nice + ct.system + ct.idle + ct.iowait + ct.irq + ct.softirq diff --git a/tools/scripts/mem_usage.py b/tools/scripts/mem_usage.py index bc0e97e7ca..9b13a56ce2 100755 --- a/tools/scripts/mem_usage.py +++ b/tools/scripts/mem_usage.py @@ -1,216 +1,13 @@ #!/usr/bin/env python3 import argparse import os -from collections import defaultdict +import sys -import numpy as np +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) -from openpilot.common.utils import tabulate +from openpilot.selfdrive.test.mem_usage import DEMO_ROUTE, print_report from openpilot.tools.lib.logreader import LogReader -DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496" -MB = 1024 * 1024 -TABULATE_OPTS = dict(tablefmt="simple_grid", stralign="center", numalign="center") - - -def _get_procs(): - from openpilot.selfdrive.test.test_onroad import PROCS - return PROCS - - -def is_openpilot_proc(name): - if any(p in name for p in _get_procs()): - return True - # catch openpilot processes not in PROCS (athenad, manager, etc.) - return 'openpilot' in name or name.startswith(('selfdrive.', 'system.')) - - -def get_proc_name(proc): - if len(proc.cmdline) > 0: - return list(proc.cmdline)[0] - return proc.name - - -def pct(val_mb, total_mb): - return val_mb / total_mb * 100 if total_mb else 0 - - -def has_pss(proc_logs): - """Check if logs contain PSS data (new field, not in old logs).""" - try: - for proc in proc_logs[-1].procLog.procs: - if proc.memPss > 0: - return True - except AttributeError: - pass - return False - - -def print_summary(proc_logs, device_states): - mem = proc_logs[-1].procLog.mem - total = mem.total / MB - used = (mem.total - mem.available) / MB - cached = mem.cached / MB - shared = mem.shared / MB - buffers = mem.buffers / MB - - lines = [ - f" Total: {total:.0f} MB", - f" Used (total-avail): {used:.0f} MB ({pct(used, total):.0f}%)", - f" Cached: {cached:.0f} MB ({pct(cached, total):.0f}%) Buffers: {buffers:.0f} MB ({pct(buffers, total):.0f}%)", - f" Shared/MSGQ: {shared:.0f} MB ({pct(shared, total):.0f}%)", - ] - - if device_states: - mem_pcts = [m.deviceState.memoryUsagePercent for m in device_states] - lines.append(f" deviceState memory: {np.min(mem_pcts)}-{np.max(mem_pcts)}% (avg {np.mean(mem_pcts):.0f}%)") - - print("\n-- Memory Summary --") - print("\n".join(lines)) - return total - - -def collect_per_process_mem(proc_logs, use_pss): - """Collect per-process memory samples. Returns {name: {metric: [values_per_sample_in_MB]}}.""" - by_proc = defaultdict(lambda: defaultdict(list)) - - for msg in proc_logs: - sample = defaultdict(lambda: defaultdict(float)) - for proc in msg.procLog.procs: - name = get_proc_name(proc) - sample[name]['rss'] += proc.memRss / MB - if use_pss: - sample[name]['pss'] += proc.memPss / MB - sample[name]['pss_anon'] += proc.memPssAnon / MB - sample[name]['pss_shmem'] += proc.memPssShmem / MB - - for name, metrics in sample.items(): - for metric, val in metrics.items(): - by_proc[name][metric].append(val) - - return by_proc - - -def _has_pss_detail(by_proc) -> bool: - """Check if any process has non-zero pss_anon/pss_shmem (unavailable on some kernels).""" - return any(sum(v.get('pss_anon', [])) > 0 or sum(v.get('pss_shmem', [])) > 0 for v in by_proc.values()) - - -def process_table_rows(by_proc, total_mb, use_pss, show_detail): - """Build table rows. Returns (rows, total_row).""" - mem_key = 'pss' if use_pss else 'rss' - rows = [] - for name in sorted(by_proc, key=lambda n: np.mean(by_proc[n][mem_key]), reverse=True): - m = by_proc[name] - vals = m[mem_key] - avg = round(np.mean(vals)) - row = [name, f"{avg} MB", f"{round(np.max(vals))} MB", f"{round(pct(avg, total_mb), 1)}%"] - if show_detail: - row.append(f"{round(np.mean(m['pss_anon']))} MB") - row.append(f"{round(np.mean(m['pss_shmem']))} MB") - rows.append(row) - - # Total row - total_row = None - if by_proc: - max_samples = max(len(v[mem_key]) for v in by_proc.values()) - totals = [] - for i in range(max_samples): - s = sum(v[mem_key][i] for v in by_proc.values() if i < len(v[mem_key])) - totals.append(s) - avg_total = round(np.mean(totals)) - total_row = ["TOTAL", f"{avg_total} MB", f"{round(np.max(totals))} MB", f"{round(pct(avg_total, total_mb), 1)}%"] - if show_detail: - total_row.append(f"{round(sum(np.mean(v['pss_anon']) for v in by_proc.values()))} MB") - total_row.append(f"{round(sum(np.mean(v['pss_shmem']) for v in by_proc.values()))} MB") - - return rows, total_row - - -def print_process_tables(op_procs, other_procs, total_mb, use_pss): - all_procs = {**op_procs, **other_procs} - show_detail = use_pss and _has_pss_detail(all_procs) - - header = ["process", "avg", "max", "%"] - if show_detail: - header += ["anon", "shmem"] - - op_rows, op_total = process_table_rows(op_procs, total_mb, use_pss, show_detail) - # filter other: >5MB avg and not bare interpreter paths (test infra noise) - other_filtered = {n: v for n, v in other_procs.items() - if np.mean(v['pss' if use_pss else 'rss']) > 5.0 - and os.path.basename(n.split()[0]) not in ('python', 'python3')} - other_rows, other_total = process_table_rows(other_filtered, total_mb, use_pss, show_detail) - - rows = op_rows - if op_total: - rows.append(op_total) - if other_rows: - sep_width = len(header) - rows.append([""] * sep_width) - rows.extend(other_rows) - if other_total: - other_total[0] = "TOTAL (other)" - rows.append(other_total) - - metric = "PSS (no shared double-count)" if use_pss else "RSS (includes shared, overcounts)" - print(f"\n-- Per-Process Memory: {metric} --") - print(tabulate(rows, header, **TABULATE_OPTS)) - - -def print_memory_accounting(proc_logs, op_procs, other_procs, total_mb, use_pss): - last = proc_logs[-1].procLog.mem - used = (last.total - last.available) / MB - shared = last.shared / MB - cached_buf = (last.buffers + last.cached) / MB - shared # shared (MSGQ) is in Cached; separate it - msgq = shared - - mem_key = 'pss' if use_pss else 'rss' - op_total = sum(v[mem_key][-1] for v in op_procs.values()) if op_procs else 0 - other_total = sum(v[mem_key][-1] for v in other_procs.values()) if other_procs else 0 - proc_sum = op_total + other_total - remainder = used - (cached_buf + msgq) - proc_sum - - if not use_pss: - # RSS double-counts shared; add back once to partially correct - remainder += shared - - header = ["", "MB", "%", ""] - label = "PSS" if use_pss else "RSS*" - rows = [ - ["Used (total - avail)", f"{used:.0f}", f"{pct(used, total_mb):.1f}", "memory in use by the system"], - [" Cached + Buffers", f"{cached_buf:.0f}", f"{pct(cached_buf, total_mb):.1f}", "pagecache + fs metadata, reclaimable"], - [" MSGQ (shared)", f"{msgq:.0f}", f"{pct(msgq, total_mb):.1f}", "/dev/shm tmpfs, also in process PSS"], - [f" openpilot {label}", f"{op_total:.0f}", f"{pct(op_total, total_mb):.1f}", "sum of openpilot process memory"], - [f" other {label}", f"{other_total:.0f}", f"{pct(other_total, total_mb):.1f}", "sum of non-openpilot process memory"], - [" kernel/ION/GPU", f"{remainder:.0f}", f"{pct(remainder, total_mb):.1f}", "slab, ION/DMA-BUF, GPU, page tables"], - ] - note = "" if use_pss else " (*RSS overcounts shared mem)" - print(f"\n-- Memory Accounting (last sample){note} --") - print(tabulate(rows, header, tablefmt="simple_grid", stralign="right")) - - -def print_report(proc_logs, device_states=None): - """Print full memory analysis report. Can be called from tests or CLI.""" - if not proc_logs: - print("No procLog messages found") - return - - print(f"{len(proc_logs)} procLog samples, {len(device_states or [])} deviceState samples") - - use_pss = has_pss(proc_logs) - if not use_pss: - print(" (no PSS data — re-record with updated proclogd for accurate numbers)") - - total_mb = print_summary(proc_logs, device_states or []) - - by_proc = collect_per_process_mem(proc_logs, use_pss) - op_procs = {n: v for n, v in by_proc.items() if is_openpilot_proc(n)} - other_procs = {n: v for n, v in by_proc.items() if not is_openpilot_proc(n)} - - print_process_tables(op_procs, other_procs, total_mb, use_pss) - print_memory_accounting(proc_logs, op_procs, other_procs, total_mb, use_pss) - if __name__ == "__main__": parser = argparse.ArgumentParser(description="Analyze memory usage from route logs") diff --git a/tools/scripts/profiling/snapdragon/README.md b/tools/scripts/profiling/snapdragon/README.md index f56ca182a7..383d83ba9b 100644 --- a/tools/scripts/profiling/snapdragon/README.md +++ b/tools/scripts/profiling/snapdragon/README.md @@ -4,10 +4,10 @@ snapdragon profiler * download from https://developer.qualcomm.com/software/snapdragon-profiler/tools-archive (need a qc developer account) * choose v2021.5 (verified working with 24.04 dev environment) -* unzip to selfdrive/debug/profiling/snapdragon/SnapdragonProfiler +* unzip to openpilot/selfdrive/debug/profiling/snapdragon/SnapdragonProfiler * run ```./setup-profiler.sh``` * run ```./setup-agnos.sh``` -* run ```selfdrive/debug/adb.sh``` on device +* run ```openpilot/selfdrive/debug/adb.sh``` on device * run the ```adb connect xxx``` command that was given to you on local pc * cd to SnapdragonProfiler and run ```./run_sdp.sh``` * connect to device -> choose device you just setup diff --git a/tools/scripts/qlog_size.py b/tools/scripts/qlog_size.py index 2b54cfeebf..46ef4b8be0 100755 --- a/tools/scripts/qlog_size.py +++ b/tools/scripts/qlog_size.py @@ -5,7 +5,7 @@ from collections import defaultdict import matplotlib.pyplot as plt -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import LOG_COMPRESSION_LEVEL from openpilot.tools.lib.logreader import LogReader from tqdm import tqdm diff --git a/tools/scripts/set_car_params.py b/tools/scripts/set_car_params.py index dabb6b7065..3864de0838 100755 --- a/tools/scripts/set_car_params.py +++ b/tools/scripts/set_car_params.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import sys -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.tools.lib.route import Route from openpilot.tools.lib.logreader import LogReader diff --git a/tools/scripts/ssh.py b/tools/scripts/ssh.py index 33eac4081d..86e86c7eed 100755 --- a/tools/scripts/ssh.py +++ b/tools/scripts/ssh.py @@ -14,7 +14,7 @@ if __name__ == "__main__": parser.add_argument("device", help="device name or dongle id") parser.add_argument("--host", help="ssh jump server host", default="ssh.comma.ai") parser.add_argument("--port", help="ssh jump server port", default=22, type=int) - parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "common/hardware/tici/id_rsa")) + parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "openpilot/common/hardware/tici/id_rsa")) parser.add_argument("--debug", help="enable debug output", action="store_true") args = parser.parse_args() diff --git a/tools/scripts/uiview.py b/tools/scripts/uiview.py index d2244cf4b6..f28ba3b2ec 100755 --- a/tools/scripts/uiview.py +++ b/tools/scripts/uiview.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 import time -from cereal import car, log, messaging +from openpilot.cereal import log, messaging +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes, is_tinygrad_model, is_stock_model from openpilot.common.hardware import HARDWARE diff --git a/tools/scripts/watch_timings.py b/tools/scripts/watch_timings.py index 874720dd22..0df9db2033 100755 --- a/tools/scripts/watch_timings.py +++ b/tools/scripts/watch_timings.py @@ -7,8 +7,8 @@ from dataclasses import dataclass, field import numpy as np -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST @dataclass diff --git a/tools/setup_dependencies.sh b/tools/setup_dependencies.sh index 6cfd75ce17..80f3ac4e45 100755 --- a/tools/setup_dependencies.sh +++ b/tools/setup_dependencies.sh @@ -2,7 +2,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -ROOT="$(cd "$DIR/../" && pwd)" +ROOT="$(git -C "$DIR" rev-parse --show-toplevel)" function retry() { local attempts=$1 diff --git a/tools/sim/tests/__init__.py b/tools/sim/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/uv.lock b/uv.lock index 3413e4da04..d9adb09f0b 100644 --- a/uv.lock +++ b/uv.lock @@ -2,21 +2,19 @@ version = 1 revision = 3 requires-python = ">=3.12.3, <3.13" -[[package]] -name = "acados" -version = "0.2.2" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#25933c81c7db5573afe38f012f52befc15cdb804" } -dependencies = [ - { name = "numpy" }, +[manifest] +overrides = [ + { name = "av" }, + { name = "opendbc", editable = "opendbc_repo" }, ] [[package]] name = "aiohappyeyeballs" -version = "2.6.2" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/33/c6/61a2d7b7572279226bb2e7f61d7a19ca7c90da0329c93fa0d560cbf288d8/aiohappyeyeballs-2.6.2.tar.gz", hash = "sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64", size = 22591, upload-time = "2026-05-20T15:12:24.631Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl", hash = "sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4", size = 15062, upload-time = "2026-05-20T15:12:23.328Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, ] [[package]] @@ -123,33 +121,13 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/b9/275df9607f7fb44317ccb1d4be74827185c0d410f52b6e2cd770fe209118/av-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:f49243b1d27c91cd8c66fdba90a674e344eb8eb917264f36117bf2b6879118fd", size = 31752045, upload-time = "2026-01-11T09:57:45.106Z" }, ] -[[package]] -name = "bootstrap-icons" -version = "1.10.5.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#d7e41838af9320328dd7102f9288a94f0cf0fa9f" } - -[[package]] -name = "bzip2" -version = "1.0.8" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#12916f9f84848239e5a69a8c5a282f3dcb0d86a3" } - -[[package]] -name = "capnproto" -version = "1.0.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#a75eb83bd98440e890261f82aa8dcfbda0b0a206" } - -[[package]] -name = "catch2" -version = "2.13.10" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#7287b4c99d23fdd87e66f9941b0e35ece6b4d91b" } - [[package]] name = "certifi" -version = "2026.5.20" +version = "2026.6.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, ] [[package]] @@ -202,14 +180,14 @@ wheels = [ [[package]] name = "click" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, ] [[package]] @@ -230,6 +208,168 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "comma-deps-acados" +version = "0.2.2.post95" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/83/e76d3f89de07a672c5fc452d81b6f00f972721342eb75de2171d2c3a8b19/comma_deps_acados-0.2.2.post95-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fd7c583ac2a33b414540c0601173e3a9c28c5d8f825cb24736c64e3c07271f56", size = 10631724, upload-time = "2026-06-24T23:58:31.726Z" }, + { url = "https://files.pythonhosted.org/packages/64/96/4b8e50a153dcb5f34628f854dc58774588b8dbfb26b6bedd0b99acb4aa71/comma_deps_acados-0.2.2.post95-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:1f47c3a665193937c993d3ee15989be5ba75eb427c9733fe1b9e800bf33c56aa", size = 11663713, upload-time = "2026-06-24T23:58:33.725Z" }, + { url = "https://files.pythonhosted.org/packages/1b/2f/bf57b9656e86950ba19c7a88992fccc0abb89878f9c30fb1b2252d57f0a7/comma_deps_acados-0.2.2.post95-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:00b49d5b691fa97d07fa5e5b842e0d2e1a6faa6856d2a081eefcee649f93329b", size = 13167209, upload-time = "2026-06-24T23:58:35.941Z" }, +] + +[[package]] +name = "comma-deps-bootstrap-icons" +version = "1.10.5.0.post95" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/0b/bb713dd4bed94b0b2b21657b7337e264953bd785a2b2f5c1b0706cdcde29/comma_deps_bootstrap_icons-1.10.5.0.post95-py3-none-any.whl", hash = "sha256:d59fc8d3e642e00f83d7a4854164f1dee21c3d17c726d5537b1b72b149f5788b", size = 386001, upload-time = "2026-06-24T23:58:37.84Z" }, +] + +[[package]] +name = "comma-deps-bzip2" +version = "1.0.8.post95" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ac/539d76e9bcebbc53d62274a19c47522b118dce3261fc6baea045f93c98b6/comma_deps_bzip2-1.0.8.post95-py3-none-macosx_11_0_arm64.whl", hash = "sha256:be466743b7fc56fa18c2c389a46bdeb0fc885cf3cf39b779d748ce540609ebd5", size = 42832, upload-time = "2026-06-24T23:58:39.592Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fe/5206bd6d716022cea259c4878c6a1927ab3555f4caa48a74efaa83d8f418/comma_deps_bzip2-1.0.8.post95-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7c015d720cc5462f87062b4482c54684de6a237b4edb60612c2f58721413682f", size = 38629, upload-time = "2026-06-24T23:58:40.496Z" }, + { url = "https://files.pythonhosted.org/packages/39/0e/78218f9a645ad9d27000153795d6819b3b52ca62d882aa46a413e40887be/comma_deps_bzip2-1.0.8.post95-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:3188a197aaf3efbfac975193887c59600b91a3b4eb7f62cc975377133cd48834", size = 36271, upload-time = "2026-06-24T23:58:41.2Z" }, +] + +[[package]] +name = "comma-deps-capnproto" +version = "1.0.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/a6/97c22a112e23f530db28f8ecf7b191ec16685d282fdbe892dff7437bdf6d/comma_deps_capnproto-1.0.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6717e8e34ef12116502f244b23f092984c1d15afa4e40b956450b74a0d4d2520", size = 2407330, upload-time = "2026-07-08T19:30:41.395Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f2/79a15ff5f2c97a741923a97357f6a4235e4ced928ba1d4079d01c66df4b0/comma_deps_capnproto-1.0.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a70349446e2ec17b281ebaaae02ca4c35495f4210043c716c55139a05a826090", size = 2506341, upload-time = "2026-07-08T19:30:45.607Z" }, + { url = "https://files.pythonhosted.org/packages/80/a9/f61fe62045c4ea867f51f2d74b4edfabd6c272c62a3281a9f1f33825a725/comma_deps_capnproto-1.0.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f98cdba8f8c7f08a7a0c0a4b7cc0bfcf515e29ad8f1b5cb8eda4e253bef5e6e3", size = 2590769, upload-time = "2026-07-08T19:30:49.728Z" }, +] + +[[package]] +name = "comma-deps-catch2" +version = "2.13.10.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ee/b4ef7758d04a024775d49558ca930fec19aa37cd691ad9182b7141f4d4d7/comma_deps_catch2-2.13.10.post93-py3-none-any.whl", hash = "sha256:8f23293251b5db48c08885d8816ca252b3fb11b0c1c26775bae36e8b217e865e", size = 137085, upload-time = "2026-07-08T19:30:53.44Z" }, +] + +[[package]] +name = "comma-deps-eigen" +version = "3.4.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/3c/b262d6103a3b7a5cb0296b821eb4f1385b349e527bba75d7efe057cea802/comma_deps_eigen-3.4.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f90433cea3f59f1b9ed58bd92d0f1b55721eff8b473d579ed40fa2fcdc2c1787", size = 2275895, upload-time = "2026-07-08T19:31:08.983Z" }, + { url = "https://files.pythonhosted.org/packages/00/a1/b9bf332a096267ff26ebd546b104d9a92b905857c59bae899794897c790b/comma_deps_eigen-3.4.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3169d82b825ca8accdae5f3e1a9cddd9f28f8bd5f66e4353fedae68b23f13cdb", size = 2275897, upload-time = "2026-07-08T19:31:12.66Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c6/1132467acd1257ea159cf4608c6f00ef0b3ca353fd86aaced0d76dcce62c/comma_deps_eigen-3.4.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:d0b042c817070a0124b8c0e78b87ff5e8b44db21a1abea740afe7115f5bd8447", size = 2275900, upload-time = "2026-07-08T19:31:16.352Z" }, +] + +[[package]] +name = "comma-deps-ffmpeg" +version = "7.1.0.post94" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/5c/47e10049fd96b581e8ddc9fba31c3397562732fcc99db6c062690e862300/comma_deps_ffmpeg-7.1.0.post94-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e87b4dd0fb0fc25d6992167ee266b5c9e92305aefa3d343ddd22a17219363b8", size = 7329953, upload-time = "2026-07-09T03:07:11.516Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/c4edfbbe488983ff45fb6cacab78342fc56cc0f28010a946e8697613ffe2/comma_deps_ffmpeg-7.1.0.post94-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7ea34368c5b564cecab0fd77d6423bc15d8f100051648f64ad79a3499f43dafb", size = 4441314, upload-time = "2026-07-09T03:07:15.679Z" }, + { url = "https://files.pythonhosted.org/packages/80/8f/76a876a26572c52d52dbcf8ed39227f5023d343201a32af4b992c4b9f13e/comma_deps_ffmpeg-7.1.0.post94-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:5b2d6cfbba59ecd673dd0c8bd8eb5a5b3472bdfa025e1063c011e6234877fe84", size = 4685134, upload-time = "2026-07-09T03:07:19.596Z" }, +] + +[[package]] +name = "comma-deps-gcc-arm-none-eabi" +version = "13.2.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/9f/9a6c7f04faf18fdc4ab3e5b55ecfdbcb3998333a450fd5a1c986af571d15/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:00de06a94ecf4379c79b150d36b3116d0f37bc341bbf1ef2ad850c8a5985eeb1", size = 15238809, upload-time = "2026-07-08T19:31:33.509Z" }, + { url = "https://files.pythonhosted.org/packages/83/94/1cdb11c170b96f2677dfd1be7cfb9a2994d3518555c154f2a131929057da/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:de1cf3ff89ea84fac5df62c65d843af877eaa2634439d793f527f0cfeea66e59", size = 17367238, upload-time = "2026-07-08T19:31:38.137Z" }, + { url = "https://files.pythonhosted.org/packages/23/3c/4b2f60274f080b9583da2fdaad54f692f4f8719bd360558d4460d79f8fb4/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:3cf7f022ffa1b3d3e20eb32610c7e59f84932e516d9ed11236df787546d82d67", size = 16941134, upload-time = "2026-07-08T19:31:43.102Z" }, +] + +[[package]] +name = "comma-deps-git-lfs" +version = "3.6.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/62/e06ea6fb98b8cee2686fb409fb28426d902f3318b077cbd78d9bbec0354b/comma_deps_git_lfs-3.6.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89cbffd3d6800fa8e366301b98c09c4ccbc973fb59721aa2546b36158b9b64c0", size = 4685107, upload-time = "2026-07-08T19:31:47.273Z" }, + { url = "https://files.pythonhosted.org/packages/ce/cf/f08dc359e8bc7e1b21b7f4a93167a14ac61dc78f1bfb27a0e7554c78cb09/comma_deps_git_lfs-3.6.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:39844960733a3885d99bbfdf4f7b414e7d0bf4b4d56f9d77a88ea10d72f549c5", size = 4485276, upload-time = "2026-07-08T19:31:51.253Z" }, + { url = "https://files.pythonhosted.org/packages/2f/af/3dfae2a56320165b45ceab0d7a2c6dea69cc5766928f408d17997ff2a525/comma_deps_git_lfs-3.6.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:e445cbadec41856997de775d5d415d1e707db0ba563c705df1b55ce198179bbe", size = 4889583, upload-time = "2026-07-08T19:31:55.153Z" }, +] + +[[package]] +name = "comma-deps-imgui" +version = "1.92.7.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/e8/a5f99714d4b2ef85744bd6af9ee46b016a70cea8383c9cca3097847c6940/comma_deps_imgui-1.92.7.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ae7cbb655cd61157b785e7f388cc1bfe17bf6a2bf8c40ff9484702bd9be71074", size = 1688022, upload-time = "2026-07-08T19:31:58.849Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/0ebcbb7d55ef1ad0f516831c52f37cafdf0ed94b73e0396c531ecd89dbc1/comma_deps_imgui-1.92.7.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:efc689e8279900c10e3922e9bf188fe34e16ab28d8660878e82b7192d7d86c68", size = 2522798, upload-time = "2026-07-08T19:32:02.435Z" }, + { url = "https://files.pythonhosted.org/packages/c3/94/6f0bd31d599f5748736b57e0b71a42d15ec0782906155f268bc7056fd0ac/comma_deps_imgui-1.92.7.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:b08a763c00a1f037dc5e2e2e0322c46960fe8a2cc972ce17781d547ccce3eaa6", size = 2655457, upload-time = "2026-07-08T19:32:06.273Z" }, +] + +[[package]] +name = "comma-deps-json11" +version = "20170411.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/3e/f2bb5d0e0d9e63535007c64859b2ab5e17164ca1f4cfa279fd228dbcef80/comma_deps_json11-20170411.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0088d66fd76ea27712d09f2ffa783596f7d70b5b152a039c36d65befcebe3863", size = 34033, upload-time = "2026-07-08T19:32:10.175Z" }, + { url = "https://files.pythonhosted.org/packages/b8/6e/9576bb1ba5d8371f32664268401fa61231ca1092aa5da45141c37984d868/comma_deps_json11-20170411.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:659c18d4b2634bf7d2388c6e855c6f083f384d2a70052945c1c9ddabbb0dcb21", size = 41846, upload-time = "2026-07-08T19:32:13.457Z" }, + { url = "https://files.pythonhosted.org/packages/cc/34/6d673c311c9a23e65a0db56352878b53b575aca0539e57c71121d2fe544b/comma_deps_json11-20170411.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:4c24a9c9db71b38192ec9c515f13fd14b4495b8080bb1f687b84b193613d95be", size = 42603, upload-time = "2026-07-08T19:32:16.601Z" }, +] + +[[package]] +name = "comma-deps-libusb" +version = "1.0.29.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/a3/4fb912d8af7af134a0a54eeb893beecc9e1cb3ed8371e055319faa74a580/comma_deps_libusb-1.0.29.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1dba5fe7832877994ea9ff3daf056851f1b5c9a47552525af08b35074c5ff65e", size = 102339, upload-time = "2026-07-08T19:32:19.785Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ad/6d36327352fa1030997409ee650de3f307cc26e3fec4f2a8ea6254430e6a/comma_deps_libusb-1.0.29.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:c2a29c888668cb4c0ab549ac71206d6b53da8d2db5e581a55a113574aaabe950", size = 94439, upload-time = "2026-07-08T19:32:23.104Z" }, + { url = "https://files.pythonhosted.org/packages/84/47/f4f2da67db202bacc3fa578fdebdb916f45c97bee0c3d2c5fbe845a6f129/comma_deps_libusb-1.0.29.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f136dbbfc461d228378731361cc66a90a483e17d55f8ba43f23eeab6bcf41963", size = 93461, upload-time = "2026-07-08T19:32:26.434Z" }, +] + +[[package]] +name = "comma-deps-ncurses" +version = "6.5.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/3d/f85c036037e9d72c8cc444a1613ae8ca6967c0997148fbc8c03b8cdeb21c/comma_deps_ncurses-6.5.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0fbc94bdb42577389ec9e475deb7425f027b4e6a097b7b326ee0ee3ecb4c26ff", size = 264892, upload-time = "2026-07-08T22:08:58.325Z" }, + { url = "https://files.pythonhosted.org/packages/f4/da/13881cefe9ca963665a57f066683fd9995c15349839f0268686741942cd7/comma_deps_ncurses-6.5.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a8786c9e7693fbe235044ed068292ddae1e8c25e9cc3ffba9364c233b6df9f9c", size = 260837, upload-time = "2026-07-08T22:09:02.514Z" }, + { url = "https://files.pythonhosted.org/packages/11/98/6a278e4436ca901c084ae111dc23f064e3eb5f64481dc970111aff8a91fd/comma_deps_ncurses-6.5.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1de1011e71833d46d545a0d64150316f980385d13731eb138f9fc53642942c55", size = 248341, upload-time = "2026-07-08T22:09:06.591Z" }, +] + +[[package]] +name = "comma-deps-raylib" +version = "6.0.0.1.post93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/5a/1abdc781fc242e0db517e22c53fa676fc81b76344c5d6c86677bdd5d6a9a/comma_deps_raylib-6.0.0.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ef4dbc7036e4449f9ee029cec077c23f64975b55b60cce0be818b70640c1732a", size = 2004199, upload-time = "2026-07-08T22:09:10.731Z" }, + { url = "https://files.pythonhosted.org/packages/79/90/919fd98aa72c8c1d31e657abc0bc28b3933d7408f4dc8ccbb7272ef638a9/comma_deps_raylib-6.0.0.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a64f2a77ad55b05350ed4301f3a1a814176810d1d408c77bdbaa1bd5a3ab5135", size = 7203010, upload-time = "2026-07-08T22:09:15.323Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b6/419b387b132efe43ace20dced9852448f36195d71d1305fccfd5e0617083/comma_deps_raylib-6.0.0.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:11bf076441b636434bc76a00b2e349c22a825e0b83416a4fb3dd4b8217638f8a", size = 5055450, upload-time = "2026-07-08T22:09:19.844Z" }, +] + +[[package]] +name = "comma-deps-zeromq" +version = "4.3.5.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/6f/d50752a3a6f6ecd4b4289bf76090fd35c11ac8d4b9353534e91e9a640512/comma_deps_zeromq-4.3.5.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b5951b302ec3db7ad3638161af00dff6ad1d8e0272aa242a0b57d692a093bacc", size = 815166, upload-time = "2026-07-08T22:09:24.48Z" }, + { url = "https://files.pythonhosted.org/packages/57/24/0fa08db746438533a67e44886bffb1cd7e2a587c68d57fba745e84036965/comma_deps_zeromq-4.3.5.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a7d4813155ea13548158204a60e6a37e2dedfcf7ae34cbb78491474ac784ac24", size = 833412, upload-time = "2026-07-08T22:09:28.872Z" }, + { url = "https://files.pythonhosted.org/packages/c5/83/9083466d8269bf273a7ff4ff154fbcd300a8d9c79ca7754fb98215caf602/comma_deps_zeromq-4.3.5.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:378f121eea1084c7cd45ee73c3dbc437e3d07547e8333d230174711e963f958d", size = 798729, upload-time = "2026-07-08T22:09:32.859Z" }, +] + +[[package]] +name = "comma-deps-zstd" +version = "1.5.6.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/32/e62e39d77d356675b07fa0c03286d3f5620bb39fe8619285bfaf3c085f6b/comma_deps_zstd-1.5.6.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9c40c10fa541c5ed975a06327f4e5cc5fe380d49c50fd2899f367c52e0d535a1", size = 1065092, upload-time = "2026-07-08T22:09:37.023Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f9/80e530ffed74b767591e50367dd51413c99e8aa10a975745086f2f10eac8/comma_deps_zstd-1.5.6.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3a1da859191a9b4c778498afdaa80a7000e5967d4851d827e422c467aa159f9a", size = 1006181, upload-time = "2026-07-08T22:09:41.332Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b1/5b544af0a50235b1efe9a9de469180ded30814feb8e6a2cd89d4064f995e/comma_deps_zstd-1.5.6.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:fe85e5fd24ac81964cac30ad04327ae157b5976a69725604ec960e773f06a9a8", size = 1030331, upload-time = "2026-07-08T22:09:45.535Z" }, +] + [[package]] name = "contourpy" version = "1.3.3" @@ -254,81 +394,63 @@ wheels = [ [[package]] name = "coverage" -version = "7.14.1" +version = "7.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/fd/0ab2772530e946e1be1abd0bc09e647ec9b02e88f0867857601fefca8953/coverage-7.14.1.tar.gz", hash = "sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be", size = 920132, upload-time = "2026-05-26T20:41:36.783Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/8b/adeb62ea8951f13c4c7fef2e7a85e1a06b499c8d8237ea589d496029e53f/coverage-7.15.0.tar.gz", hash = "sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f", size = 925362, upload-time = "2026-07-02T13:10:50.535Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/b7/bdbb725ba02c5b42825b200c940f38b7a54fcad24627b7192f78f8110d76/coverage-7.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c", size = 220022, upload-time = "2026-05-26T20:39:03.702Z" }, - { url = "https://files.pythonhosted.org/packages/72/81/fdc0898a55c6219223291ec1a1fe89966ef212ce82276aa0899df84b5de0/coverage-7.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c", size = 220379, upload-time = "2026-05-26T20:39:05.381Z" }, - { url = "https://files.pythonhosted.org/packages/de/72/de048c4a25e13bce59ac6a339351c10bdf2515e07459afcdaf04dc3143a2/coverage-7.14.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b", size = 251888, upload-time = "2026-05-26T20:39:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/28/30/300c343f68beb9d4cbb64ec81e58c5b6b80b56927f72d2b38654ac26e013/coverage-7.14.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6", size = 254624, upload-time = "2026-05-26T20:39:09.037Z" }, - { url = "https://files.pythonhosted.org/packages/b1/ed/7b25642496e8170b6bac14adce00537c6e5fa2d586159401a4de3e8b49e6/coverage-7.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37", size = 255739, upload-time = "2026-05-26T20:39:10.889Z" }, - { url = "https://files.pythonhosted.org/packages/7f/a2/abd210b8c4e29c24e4624916db97bb519097a91034aaeb767f937e7da794/coverage-7.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad", size = 257998, upload-time = "2026-05-26T20:39:12.722Z" }, - { url = "https://files.pythonhosted.org/packages/7f/24/7c50beed3792fe62f6ce0545c6686ce83379719e2c0276179333d97eae92/coverage-7.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84", size = 252296, upload-time = "2026-05-26T20:39:14.259Z" }, - { url = "https://files.pythonhosted.org/packages/15/05/0f874628ebcbfc77ead559ff210281ef06a97db08481832e7dd39274a135/coverage-7.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54", size = 253658, upload-time = "2026-05-26T20:39:15.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/6f/ca6ad067364b337ef997802115e7ecad2abd2248b05471464b0dea02b4d4/coverage-7.14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7", size = 251803, upload-time = "2026-05-26T20:39:17.537Z" }, - { url = "https://files.pythonhosted.org/packages/c0/30/b9b4d377cd9f40baf228068f5a81faf8450c6228503011bd499708483a50/coverage-7.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9", size = 255873, upload-time = "2026-05-26T20:39:19.414Z" }, - { url = "https://files.pythonhosted.org/packages/3c/21/7c721a9e5e6bb88547d30a787aefb97512d3f54c1324c7488d9b3743f7f9/coverage-7.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02", size = 251372, upload-time = "2026-05-26T20:39:21.169Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f8ae5a2200130e1503cd7661a6cd3b2b7bacef98277fbf3571fb13f8b766/coverage-7.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a", size = 253245, upload-time = "2026-05-26T20:39:23.097Z" }, - { url = "https://files.pythonhosted.org/packages/34/62/70a9024672a5f6910517d9628c52c9afbdd3cf8f46426af52bb148a56fff/coverage-7.14.1-cp312-cp312-win32.whl", hash = "sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1", size = 222567, upload-time = "2026-05-26T20:39:24.868Z" }, - { url = "https://files.pythonhosted.org/packages/f6/81/8b7cd386839b039ebe1855733b9f9449a8dec5d79564018234f185a7fa70/coverage-7.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e", size = 223372, upload-time = "2026-05-26T20:39:26.603Z" }, - { url = "https://files.pythonhosted.org/packages/ae/ba/b44d472022f620d289d95fa830143235c0c36461c6f2437ea8d51e5481ed/coverage-7.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a", size = 221989, upload-time = "2026-05-26T20:39:28.242Z" }, - { url = "https://files.pythonhosted.org/packages/8a/3c/1a983b9a745d7f83d53f057bcc5bf79ba6a2bbc08266b3f0c7d6fe630c9b/coverage-7.14.1-py3-none-any.whl", hash = "sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2", size = 211815, upload-time = "2026-05-26T20:41:34.078Z" }, -] - -[[package]] -name = "crcmod-plus" -version = "2.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/0c/71733bbaf38e9f1eaecfdf7f8e350993f3dcac208a5297c41503ae66e513/crcmod_plus-2.3.1.tar.gz", hash = "sha256:732ffe3c3ce3ef9b272e1827d8fb894590c4d6ff553f2a2b41ae30f4f94b0f5d", size = 22319, upload-time = "2025-10-10T22:14:21.691Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/47/e0/2dad2e6f0cd4914b4144496d9785780ec820e200816c080df785cfa34da6/crcmod_plus-2.3.1-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:b7e35e0f7d93d7571c2c9c3d6760e456999ea4c1eae5ead6acac247b5a79e469", size = 23279, upload-time = "2025-10-10T22:13:47.281Z" }, - { url = "https://files.pythonhosted.org/packages/66/76/53c0b65b9679b903f98fc54efa32b0e5a19634712a45200c7a80674aa6f5/crcmod_plus-2.3.1-cp311-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6853243120db84677b94b625112116f0ef69cd581741d20de58dce4c34242654", size = 20185, upload-time = "2025-10-10T22:13:48.06Z" }, - { url = "https://files.pythonhosted.org/packages/98/79/2b4dc9bb26394873d7699737124408b5106264ae33053fdec600e9a9fa65/crcmod_plus-2.3.1-cp311-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:17735bc4e944d552ea18c8609fc6d08a5e64ee9b29cc216ba4d623754029cc3a", size = 26999, upload-time = "2025-10-10T22:13:48.854Z" }, - { url = "https://files.pythonhosted.org/packages/bb/e8/f5d66778b5a1bff915807016561a02b5cebf6b3840fb8a2be40bbb0c8575/crcmod_plus-2.3.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ac755040a2a35f43ab331978c48a9acb4ff64b425f282a296be467a410f00c3", size = 27536, upload-time = "2025-10-10T22:13:49.956Z" }, - { url = "https://files.pythonhosted.org/packages/f3/2c/0113ad30cadad40c22eef08c0f2618f2446dd282f02268fecbcfc9fda3c1/crcmod_plus-2.3.1-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bdcfb838ca093ca673a3bbb37f62d1e5ec7182e00cc5ee2d00759f9f9f8ab11", size = 27385, upload-time = "2025-10-10T22:13:50.765Z" }, - { url = "https://files.pythonhosted.org/packages/8e/ba/501ef1b02119402cf1a31c01eb2cb8399660bca863c2f4dd3dc060220284/crcmod_plus-2.3.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9166bc3c9b5e7b07b4e6854cac392b4a451b31d58d3950e48c140ab7b5d05394", size = 27135, upload-time = "2025-10-10T22:13:51.889Z" }, - { url = "https://files.pythonhosted.org/packages/49/90/d4556c9db69c83e726c5b88da3d656fdaac7d60c4d27b43cb939bed80069/crcmod_plus-2.3.1-cp311-abi3-win32.whl", hash = "sha256:cb99b694cce5c862560cf332a8b5e793620e28f0de3726995608bbd6f9b6e09a", size = 22384, upload-time = "2025-10-10T22:13:53.016Z" }, - { url = "https://files.pythonhosted.org/packages/4d/7e/57bb97a8c7b4e19900744f58b67dc83bc9c83aaac670deeede9fb3bfab6a/crcmod_plus-2.3.1-cp311-abi3-win_amd64.whl", hash = "sha256:82b0f7e968c430c5a80fe0fc59e75cb54f2e84df2ed0cee5a3ff9cadfbf8a220", size = 22912, upload-time = "2025-10-10T22:13:53.849Z" }, + { url = "https://files.pythonhosted.org/packages/2a/74/fd4c0901137c4f8d81a76ada99e43c65163b4c94a02ece107a4ec0c6b615/coverage-7.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b75ee5e8cb7575636ac598719b4307ac529ec8fcd79608a35c3cd4d4dada812d", size = 220838, upload-time = "2026-07-02T13:09:02.084Z" }, + { url = "https://files.pythonhosted.org/packages/0f/2e/2347583467bd7f0402635101a916961915cc68fce652cd0db5f173ea04fc/coverage-7.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffb31267816b93b075302248cc1737506081b4f163df4401e9df1a6424aafabe", size = 221197, upload-time = "2026-07-02T13:09:03.617Z" }, + { url = "https://files.pythonhosted.org/packages/f0/17/99fa688541ae1d6e84543a0e544f83de0c944815b63e9e7b1ed411d15036/coverage-7.15.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c", size = 252705, upload-time = "2026-07-02T13:09:05.059Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/6a95a5cd83b74839017ef9cf48d2d8c9ae60af919e17a3f336e6f9f1b7bd/coverage-7.15.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4", size = 255441, upload-time = "2026-07-02T13:09:06.559Z" }, + { url = "https://files.pythonhosted.org/packages/67/f2/406f6c57d600f68185942422c4c00f1a3255d60aee6e5fd961425cd9987e/coverage-7.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5", size = 256556, upload-time = "2026-07-02T13:09:08.197Z" }, + { url = "https://files.pythonhosted.org/packages/74/8e/d3fa48489c15ecdec1ba48fd61f68798555dddd2f6716f9ad42adeb1a2a9/coverage-7.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01", size = 258815, upload-time = "2026-07-02T13:09:09.691Z" }, + { url = "https://files.pythonhosted.org/packages/47/2e/2d40ddd110462c6a2769677cf7f1c119a52b45f568978fc6c98e4cc0dd0f/coverage-7.15.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4", size = 253117, upload-time = "2026-07-02T13:09:11.212Z" }, + { url = "https://files.pythonhosted.org/packages/51/c0/310782f0d7c3cb2b5ac05ba8d205fe91f24a36f6bf3256098f1782181c38/coverage-7.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796", size = 254475, upload-time = "2026-07-02T13:09:13.029Z" }, + { url = "https://files.pythonhosted.org/packages/86/f7/702da6c275f8ae6ade423d2877243122932c9b27f5403003b9ef8c927d12/coverage-7.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382", size = 252619, upload-time = "2026-07-02T13:09:14.699Z" }, + { url = "https://files.pythonhosted.org/packages/fb/84/c5b15a7e5ecba4e56218d772d99fe80a63e63f8d11f12783723a6005ab45/coverage-7.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c", size = 256689, upload-time = "2026-07-02T13:09:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/95/2f/c8b07559b57701230c61b23a953858c052890c12ef568d81780c6c46e92e/coverage-7.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766", size = 252189, upload-time = "2026-07-02T13:09:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/6b/80/6d2f049dd3fd3dbfd60b62ba6b2162a04009e2c002ce70b24cf3878dec7a/coverage-7.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da", size = 254059, upload-time = "2026-07-02T13:09:19.304Z" }, + { url = "https://files.pythonhosted.org/packages/ce/92/b0287a2c42031d25c628f815f89a3cd9f8268ee78bb1252c9356cda1c689/coverage-7.15.0-cp312-cp312-win32.whl", hash = "sha256:5f764a3fa339bde6b3aa97657f5a6a3a9451e4a5b4ea98a2892c773a43525f77", size = 222893, upload-time = "2026-07-02T13:09:20.812Z" }, + { url = "https://files.pythonhosted.org/packages/a9/69/e34c481915fecb499b3146975061dac528752e37706edc1804f32c822469/coverage-7.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:52f9a4d2c4c56c8848bc2f524916698354b0211488b38c49ad9ae54f6cafbff6", size = 223429, upload-time = "2026-07-02T13:09:22.315Z" }, + { url = "https://files.pythonhosted.org/packages/fe/98/6e878f0b571d32684ef3f38d7c03db241ca5b82a5da8a5391596a8f209c4/coverage-7.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:31e5c3e70c85307ea35a12964e2e40f56ca2ee4b1c8c721ccf4609d17071080b", size = 222810, upload-time = "2026-07-02T13:09:23.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, ] [[package]] name = "cryptography" -version = "48.0.0" +version = "49.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" }, - { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" }, - { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" }, - { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" }, - { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" }, - { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" }, - { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" }, - { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" }, - { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" }, - { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" }, - { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" }, - { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" }, - { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" }, - { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" }, - { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" }, - { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" }, - { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" }, - { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" }, - { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" }, - { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" }, - { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" }, + { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" }, + { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, + { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, + { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, + { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, + { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, + { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, + { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, + { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" }, + { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" }, + { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, + { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, + { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, + { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" }, ] [[package]] @@ -342,33 +464,33 @@ wheels = [ [[package]] name = "cython" -version = "3.2.5" +version = "3.2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/3b/ebd94c8b85f8e41b5015a9ed94ee3df866024d480d05cd08b774684fb81d/cython-3.2.5.tar.gz", hash = "sha256:3dd42e4cf36ad15f265bdfec2337cc00c688c8eb6d374ffd13bb19437c27bba1", size = 3286381, upload-time = "2026-05-23T19:34:08.439Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/6b/80101e02ebacaf9232ecf32bf6a788d36b27d820ee02434746252569ef98/cython-3.2.8.tar.gz", hash = "sha256:f4f23a56b25221a06f91817fe8f3114ab8b48a4fac73187dbb64bc2c4a87961f", size = 3290300, upload-time = "2026-06-30T07:41:57.874Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/a6/efc97000fdb2f34e2431eb09a6ab4de9fbd3bcdb73a8f9d224afa4a9abd3/cython-3.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:eb38b89e5a8eb2508a1a0832063826b0703dfb02be84e4aa34b8818ce0ca50fe", size = 2979670, upload-time = "2026-05-23T19:34:41.281Z" }, - { url = "https://files.pythonhosted.org/packages/84/b7/951206add609c11f3bb9e82329a653c39a8bc9039c13bce57362caf84bb6/cython-3.2.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80e1e5cba5b4b9890364e9360939fc298c474f25754bb4bb861270d24bda6d6", size = 3232779, upload-time = "2026-05-23T19:34:43.347Z" }, - { url = "https://files.pythonhosted.org/packages/a1/aa/8a1d02eabe8bc1e5066fde920010a4a4a4c5f0bac3625d8e7c946f72ef98/cython-3.2.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e2c976ee96da4deff50506c7882ccebb4a932fc178ef27eb42bfde959839", size = 3400054, upload-time = "2026-05-23T19:34:45.6Z" }, - { url = "https://files.pythonhosted.org/packages/57/30/67a1b6192c828456f096d4bf4d840b9a749904b9030d9f857549fc1f9b53/cython-3.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:29243859d6824e2d33bae92fc83d591c3671b6d9ac1b757fa264b894ae906c2b", size = 2759539, upload-time = "2026-05-23T19:34:47.341Z" }, - { url = "https://files.pythonhosted.org/packages/a3/de/e3e0cf5704fe569d54b8cd5dc316c9fbf08b1b74728732f86e90168b7a3f/cython-3.2.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:224149d18d980e6ea5001b70fc7ce096c1891d59035dfa9cc5ede50f55804913", size = 2879054, upload-time = "2026-05-23T19:35:18.265Z" }, - { url = "https://files.pythonhosted.org/packages/3c/d1/0a6a8caa35c4c57a1f1866b1141c2d00c6af67f73edbe34b2baec6919ccf/cython-3.2.5-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:992a50e90d01813333752f374a4405863113059ec67102ab8d6a431a171ee328", size = 3210422, upload-time = "2026-05-23T19:35:20.641Z" }, - { url = "https://files.pythonhosted.org/packages/07/b8/2523398ec96bb0c9bf69ada625a2256a581940b09fe11fcd0029f26ef4ad/cython-3.2.5-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8d7b81e6a52a84a02993f01aa5873786ba1dd593c892d93d5fe9866da0bad297", size = 2863809, upload-time = "2026-05-23T19:35:22.416Z" }, - { url = "https://files.pythonhosted.org/packages/ff/3d/6b2f316d97bdb02283d79934e50da5cedfec65a536cdd3d69cc3a93486f9/cython-3.2.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:34d21aeb08477c9173e8be7a566b19e880a7c8109ec6bb47a4b20cb680141114", size = 2992518, upload-time = "2026-05-23T19:35:24.737Z" }, - { url = "https://files.pythonhosted.org/packages/68/2c/c9238db1eba208e226d363c00c8b74bf531a6b40c75df2334baa85e142bf/cython-3.2.5-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c4c79e697db55f082a2d3ba97702e71881d5bb1f56f0a80fa338e69101e4c59b", size = 2886221, upload-time = "2026-05-23T19:35:26.64Z" }, - { url = "https://files.pythonhosted.org/packages/2d/15/229cc5c2ed92bb8b43c73a3d31c2b4eaf498409300c34a06d93147f7a42b/cython-3.2.5-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:39acb30eba78ba6d995d5cf3d97d57d450663d93aac6f8b93753d2b89d768c60", size = 3226990, upload-time = "2026-05-23T19:35:28.979Z" }, - { url = "https://files.pythonhosted.org/packages/56/31/9c0024f2c772fc303f8cae2a204bcad2fedfaf921ba71cf13a878639432d/cython-3.2.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:382122de8d6b6024fc374fabc3a2b14ba5860ed981c25055ed14fe44278b9dc7", size = 3111004, upload-time = "2026-05-23T19:35:30.957Z" }, - { url = "https://files.pythonhosted.org/packages/82/71/8b528247e42ee63cbe1c1d53805d30b28663fa782c88da4a9b69a1a412dd/cython-3.2.5-cp39-abi3-win32.whl", hash = "sha256:0bc29c7f870b09efdb1f583fbec9592b33af81a7ce273b89c8f5163d7572d5c1", size = 2440395, upload-time = "2026-05-23T19:35:33.082Z" }, - { url = "https://files.pythonhosted.org/packages/50/4d/81c91d3279d156ee2c9ead7ed9eaa862e498066d759e92fb83d0d842c5a7/cython-3.2.5-cp39-abi3-win_arm64.whl", hash = "sha256:85b2944c3eddfc230f9082720195a2e9f869908e5a8b3185be1be832755ee7fc", size = 2446963, upload-time = "2026-05-23T19:35:35.267Z" }, - { url = "https://files.pythonhosted.org/packages/d4/5c/9cd909e6a8bb178e4e0f9a2a9227c8201a2be38abe45ada4a4c3e9154277/cython-3.2.5-py3-none-any.whl", hash = "sha256:dc1c8cebb7df5bce37f5f8dc1e5bf04313272a5973d50a55c0ec76c83812911b", size = 1257622, upload-time = "2026-05-23T19:34:05.163Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c4/47e0bcfc15b36b1c5cbde5235c60bf88df552ab216ddb836d7f816386ae6/cython-3.2.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2547a31fbd3b1610a8859a16edee2a141f7781691cb98a2c6fd54870c5f7541", size = 2995546, upload-time = "2026-06-30T07:42:23.618Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f4/bc5830abeb57a7c7498cd9a0f2df953fd9fc7f33e3f5352c9824802b83bb/cython-3.2.8-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab1fe11ebd61e497a848622cdd157a4324ac06e7935b1219715408844e15dd13", size = 3179546, upload-time = "2026-06-30T07:42:25.566Z" }, + { url = "https://files.pythonhosted.org/packages/89/38/a70e879ea52debac11d2810e066a5a2cb16e71229edae303f024506bc142/cython-3.2.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3bce1f079734753649f8a3d3a95832297207feb120d0ef4fd5db4c813cc6c04", size = 3351714, upload-time = "2026-06-30T07:42:27.513Z" }, + { url = "https://files.pythonhosted.org/packages/45/f1/f071c5e7050a7924ffad9822558c74d489afe4764f7486cb68555a509219/cython-3.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:8297efe129e6421c34ddbeb09ed5627ef6c0fc4868bf7f9bdf6c147f595ccaed", size = 2774196, upload-time = "2026-06-30T07:42:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/92/a2/0f2eaa5076bcaef52567471a54ce02ffd70007bf8688cd054f7aab9bc3b8/cython-3.2.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:127bc4039be48c6eebe7f1d68c33d23eb3a0c5ae95e1d730bdd048837751438b", size = 2892527, upload-time = "2026-06-30T07:42:55.45Z" }, + { url = "https://files.pythonhosted.org/packages/a4/08/b5488aef44662e48ac09b42d4cb398207f591c770797036fb1d6fbeb7a52/cython-3.2.8-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e480ae9f195cd29e5ce334e3d434c83dbac0783c0cc88f2407e31ba997724192", size = 3220335, upload-time = "2026-06-30T07:42:57.403Z" }, + { url = "https://files.pythonhosted.org/packages/7c/96/d04a3621045e9fe9c7c5e406a688ee3d6e04a65f545ea7c622ead4b4afd8/cython-3.2.8-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3142407b9d63f233c766e17000e2aac782411bf0409b9adc97cb7c320aecd199", size = 2876481, upload-time = "2026-06-30T07:42:59.406Z" }, + { url = "https://files.pythonhosted.org/packages/71/9a/daa259b638c5eabb8a8c36f203b85b01b5362101ff8fc4ec6ad592d34bb3/cython-3.2.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:41c118fd91d320cd72af26e29232ff3f1a0a170c47d477c9a176d766067a4718", size = 2999974, upload-time = "2026-06-30T07:43:01.29Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/71cc5b4be5ee4d34c3302b6e7272189106a4072e9890d284d05239d2b645/cython-3.2.8-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6335c6e8737a39734e20d25f89f425bf3274c104fc7efc05aacc7ed1a4858c9d", size = 2897932, upload-time = "2026-06-30T07:43:03.606Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0c/da68b9d3056e90b2060970b50d575cd7fcd1c778e8f23cc467f346e1d471/cython-3.2.8-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:1034facc082cb882e1e5beb61e136ae8e282df2eafa11e9771e9b0a15c860801", size = 3235980, upload-time = "2026-06-30T07:43:05.486Z" }, + { url = "https://files.pythonhosted.org/packages/36/0b/d88bc50e66fd1f1160dd2677d9af18273a2fb2f102c086d21f64a5a9c78b/cython-3.2.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8896ff6b133f346ebcf22aa23706c4031e8d9d5ae184433dfc67dc1053318b69", size = 3118504, upload-time = "2026-06-30T07:43:07.485Z" }, + { url = "https://files.pythonhosted.org/packages/db/de/511c4364808b3b4036d051a0301b0b142a3ddf8a319bfdbbd474fcfdc879/cython-3.2.8-cp39-abi3-win32.whl", hash = "sha256:3fd6464433d925cba66ae31bf5780c8a469a06da1d109180cffb39ee3c88ae20", size = 2435866, upload-time = "2026-06-30T07:43:09.367Z" }, + { url = "https://files.pythonhosted.org/packages/18/4f/911b2b2a0a02be15829ccbf0c906029a318efbf53d9f8e021e438261c206/cython-3.2.8-cp39-abi3-win_arm64.whl", hash = "sha256:4e9447d9b652396a285cdfbd4f9f0721842c63c6df281720e87dcc4b9ea65af5", size = 2457829, upload-time = "2026-06-30T07:43:11.645Z" }, + { url = "https://files.pythonhosted.org/packages/c4/19/31aa63ab719b2e1eea5f200a8a54e2591dc1966a6b75e3de30ef8be9bc2c/cython-3.2.8-py3-none-any.whl", hash = "sha256:f635e113677666de13a2ec2979e9b1d5b90617cdfd1a691d3559be81e2dd6cb9", size = 1258688, upload-time = "2026-06-30T07:41:55.624Z" }, ] [[package]] name = "deepmerge" -version = "2.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a8/3a/b0ba594708f1ad0bc735884b3ad854d3ca3bdc1d741e56e40bbda6263499/deepmerge-2.0.tar.gz", hash = "sha256:5c3d86081fbebd04dd5de03626a0607b809a98fb6ccba5770b62466fe940ff20", size = 19890, upload-time = "2024-08-30T05:31:50.308Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/78/6e9e20106224083cfb817d2d3c26e80e72258d617b616721a169b87081e0/deepmerge-2.1.0.tar.gz", hash = "sha256:07ca7a7b8935df596c512fa8161877c0487ac61f691c07766e7d71d2b23bdd2f", size = 21449, upload-time = "2026-06-22T05:46:07.669Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/82/e5d2c1c67d19841e9edc74954c827444ae826978499bde3dfc1d007c8c11/deepmerge-2.0-py3-none-any.whl", hash = "sha256:6de9ce507115cff0bed95ff0ce9ecc31088ef50cbdf09bc90a09349a318b3d00", size = 13475, upload-time = "2024-08-30T05:31:48.659Z" }, + { url = "https://files.pythonhosted.org/packages/51/25/2a75b47cb057b1e164c604fb81ab690a6cdb5e2260ce651194eae90f64a3/deepmerge-2.1.0-py3-none-any.whl", hash = "sha256:8f148339a91d680a75ecb74ade235d9e759a93df373a0b04e9d31c8666cfeb75", size = 14345, upload-time = "2026-06-22T05:46:06.742Z" }, ] [[package]] @@ -380,11 +502,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, ] -[[package]] -name = "eigen" -version = "3.4.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#f855b17636a376d8399f3df03629ff3e535f6b22" } - [[package]] name = "execnet" version = "2.1.2" @@ -394,11 +511,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, ] -[[package]] -name = "ffmpeg" -version = "7.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#f5153626027621f8ac0cdec056d254d3a1ef6acd" } - [[package]] name = "fonttools" version = "4.63.0" @@ -441,16 +553,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] -[[package]] -name = "gcc-arm-none-eabi" -version = "13.2.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#15791161bd7a752ef821ad6d999a364b13d6e9ca" } - -[[package]] -name = "git-lfs" -version = "3.6.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#035fb711541a6d8609bb57b26c2f31813c743eb3" } - [[package]] name = "google-crc32c" version = "1.8.0" @@ -496,9 +598,13 @@ wheels = [ ] [[package]] -name = "imgui" -version = "1.92.7" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#af4a30c3930c5e19cf8cea128e342686ba283624" } +name = "importlib-resources" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/06/b56dfa750b44e86157093bc8fca0ab81dccbf5260510de4eaf1cb69b5b99/importlib_resources-7.1.0.tar.gz", hash = "sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708", size = 44985, upload-time = "2026-04-12T16:36:09.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/db/55a262f3606bebcae07cc14095338471ad7c0bbcaa37707e6f0ee49725b7/importlib_resources-7.1.0-py3-none-any.whl", hash = "sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1", size = 37232, upload-time = "2026-04-12T16:36:08.219Z" }, +] [[package]] name = "iniconfig" @@ -539,20 +645,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] -[[package]] -name = "json-rpc" -version = "1.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/9e/59f4a5b7855ced7346ebf40a2e9a8942863f644378d956f68bcef2c88b90/json-rpc-1.15.0.tar.gz", hash = "sha256:e6441d56c1dcd54241c937d0a2dcd193bdf0bdc539b5316524713f554b7f85b9", size = 28854, upload-time = "2023-06-11T09:45:49.078Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/9e/820c4b086ad01ba7d77369fb8b11470a01fac9b4977f02e18659cf378b6b/json_rpc-1.15.0-py2.py3-none-any.whl", hash = "sha256:4a4668bbbe7116feb4abbd0f54e64a4adcf4b8f648f19ffa0848ad0f6606a9bf", size = 39450, upload-time = "2023-06-11T09:45:47.136Z" }, -] - -[[package]] -name = "json11" -version = "20170411.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#0443a506c32eadfec2071a7c163c38c6c7b81d66" } - [[package]] name = "kiwisolver" version = "1.5.0" @@ -581,14 +673,22 @@ wheels = [ ] [[package]] -name = "libjpeg" -version = "3.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#a615ec26d971cc4cca9a1a426e2c996760fe3c7f" } - -[[package]] -name = "libusb" -version = "1.0.29" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#23132cff0d629bf69590e23b6a682950433aaec8" } +name = "libusb-package" +version = "1.0.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-resources" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/a8/8b3d5dae7340880d556f9f866874b9674b2e3a22fee1e2b96f1ab0feae36/libusb_package-1.0.30.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:2b98784bac3bedda7e95bb5039dd0eded84b02f36110e4d5d607375366c61090", size = 69516, upload-time = "2026-06-30T07:41:02.451Z" }, + { url = "https://files.pythonhosted.org/packages/52/6f/26de4e9f858ab50e87931f0be268f3c1bbfce33e8584add60da857632142/libusb_package-1.0.30.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:4ad25f8d254bbbdd234446d5580b24d62d59bb0e690d8090457dac347f044437", size = 65700, upload-time = "2026-06-30T07:41:03.557Z" }, + { url = "https://files.pythonhosted.org/packages/11/12/9ba8fa91dc95b1cbfa4a68207d4048b08b900fd3686fa72b99846608de01/libusb_package-1.0.30.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c71b5f8c65b286425c02c7d624eee1fd7f08bfb1dfa492ddc20e27f06fee3829", size = 76166, upload-time = "2026-06-30T07:41:04.462Z" }, + { url = "https://files.pythonhosted.org/packages/6f/e1/a7c83535749332825f02d6693868f8ee9ae99c4104e60a483773bb652c0e/libusb_package-1.0.30.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f502ad5a0527b8c0431de817662325c88a1bba2cc334173665b04ad168d7b6d3", size = 76159, upload-time = "2026-06-30T07:41:05.543Z" }, + { url = "https://files.pythonhosted.org/packages/de/56/a1fb1726fc96a8ee3bd0e04e5e505500f022dd310dd348ecebf5cdae7a60/libusb_package-1.0.30.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7a2a1c82f6ef85d9920cbe2898aa6927d4c487744ef9f20b0d7d6d95705095bb", size = 77162, upload-time = "2026-06-30T07:41:06.581Z" }, + { url = "https://files.pythonhosted.org/packages/7b/03/264cefc51275ecb047194c4973bc40b3b278566a64bbe6e74f86bf1e0afc/libusb_package-1.0.30.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5ef8ac6f08402b4e8334f7404850316bdd26037c9a97f2a7456ee9a5d1550", size = 76676, upload-time = "2026-06-30T07:41:07.505Z" }, + { url = "https://files.pythonhosted.org/packages/e5/95/d166eeefe0d9dd5833d5724a97b023ec380c3a2d364040ec0485fd57703c/libusb_package-1.0.30.0-py3-none-win32.whl", hash = "sha256:79728146e1f01e525786900b2ccd8298a8eca53cd94b37fb0885e56aa6f9d60a", size = 78769, upload-time = "2026-06-30T07:41:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/60/4a/ff49bd77f33af05ca26fee29d601beb1e19ca791bb86efece82a3833885c/libusb_package-1.0.30.0-py3-none-win_amd64.whl", hash = "sha256:90808da724c8939a333d931d0c7226372ca5fefd98e2f2f3ef79fd918aa37522", size = 90711, upload-time = "2026-06-30T07:41:09.318Z" }, +] [[package]] name = "libusb1" @@ -601,11 +701,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5f/08/02aecf6dad627534a5835244ece14d7f187ef430354d9b8551199934d059/libusb1-3.4.0-py3-none-win_amd64.whl", hash = "sha256:b7dcc1f324a895af6aac708bc5513a17373f97349cc2ab8a277519c788bd18ca", size = 141212, upload-time = "2026-05-16T20:59:17.286Z" }, ] -[[package]] -name = "libyuv" -version = "1922.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#70295e7a22d89f9c5bdb61dd93c30f0cbb55d815" } - [[package]] name = "markdown" version = "3.10.2" @@ -636,7 +731,7 @@ wheels = [ [[package]] name = "matplotlib" -version = "3.10.9" +version = "3.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -649,25 +744,15 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/c6/5581e26c72233ebb2a2a6fed2d24fb7c66b4700120b813f51b0555acf0b6/matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1", size = 8319908, upload-time = "2026-04-24T00:12:21.323Z" }, - { url = "https://files.pythonhosted.org/packages/b7/18/4880dd762e40cd360c1bf06e890c5a97b997e91cb324602b1a19950ad5ce/matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320", size = 8216016, upload-time = "2026-04-24T00:12:23.4Z" }, - { url = "https://files.pythonhosted.org/packages/32/91/d024616abdba99e83120e07a20658976f6a343646710760c4a51df126029/matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285", size = 8789336, upload-time = "2026-04-24T00:12:26.096Z" }, - { url = "https://files.pythonhosted.org/packages/5c/04/030a2f61ef2158f5e4c259487a92ac877732499fb33d871585d89e03c42d/matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2", size = 9604602, upload-time = "2026-04-24T00:12:29.052Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c2/541e4d09d87bb6b5830fc28b4c887a9a8cf4e1c6cee698a8c05552ae2003/matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf", size = 9670966, upload-time = "2026-04-24T00:12:32.131Z" }, - { url = "https://files.pythonhosted.org/packages/04/a1/4571fc46e7702de8d0c2dc54ad1b2f8e29328dea3ee90831181f7353d93c/matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6", size = 8217462, upload-time = "2026-04-24T00:12:35.226Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688, upload-time = "2026-04-24T00:12:37.442Z" }, -] - -[[package]] -name = "metadrive-simulator" -version = "0.4.2.3" -source = { git = "https://github.com/commaai/metadrive.git?rev=minimal#2716f55a9c7b928ce957a497a15c2c19840c08bc" } -dependencies = [ - { name = "numpy" }, - { name = "panda3d" }, - { name = "panda3d-gltf" }, + { url = "https://files.pythonhosted.org/packages/da/17/f5276b496c61477a6c4fc5e7401f4bfe1c2e5ef7c6cd67896f2ade3809cb/matplotlib-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06b5872e9cf11adc8f589ded3ce11bc3e1061ad498259664fabc1f6615beb918", size = 9449976, upload-time = "2026-06-12T02:27:50.989Z" }, + { url = "https://files.pythonhosted.org/packages/82/34/bdd77418adb2178a1d59f044bd67bfebb115896e91b840b8a197eb3f4f4e/matplotlib-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0515d495124be3124340e59f164d901ed4484e2246a5b74cfa483cac3b80bd97", size = 9279307, upload-time = "2026-06-12T02:27:53.247Z" }, + { url = "https://files.pythonhosted.org/packages/94/95/7f522393c88313336b20d70fc849555757b2e5febc22b83b3a3f0fd4bce9/matplotlib-3.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be5f93a1d21981bfb802ded0d77a0caa92d4342a47d45754fac77e314a506344", size = 10031353, upload-time = "2026-06-12T02:27:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/87/ce/8f25a0e3186aefd61913e7467d1b999465bcd0d0c03ac695c1b26ca559b7/matplotlib-3.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41635d7909d19e52e924a521dde6d8f670b0f53ab1d0e8c331fa831554f681d1", size = 10839232, upload-time = "2026-06-12T02:27:57.746Z" }, + { url = "https://files.pythonhosted.org/packages/85/c2/db15da2bbdf9e3ca66df7db8e2c33a1dfed67be24a24d2c878efaaff01d6/matplotlib-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:94f5000f67ca9faa300863ea17f8bce9175cb67b88bec4bc7780502d53dd7c9e", size = 10923899, upload-time = "2026-06-12T02:28:00.223Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2f/a58a4443a4d052a4ea77557478336aefc26c7981f6408d37adba763aa758/matplotlib-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ac6f1ef39f3d0f9e2463303013094992cdbe0f85f43bc54155bc472b2042768e", size = 9329528, upload-time = "2026-06-12T02:28:02.27Z" }, + { url = "https://files.pythonhosted.org/packages/61/0f/4b669589d47733b97ab9df4b58d6fc1e68acb5ea42a928dc7cbdd6bf5871/matplotlib-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:9dd11fb612ce7bc60b1de5b4fc87ff959d22317b5de42aabf392f66f97af22eb", size = 9003413, upload-time = "2026-06-12T02:28:04.49Z" }, ] [[package]] @@ -679,6 +764,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] +[[package]] +name = "msgq" +version = "0.0.1" +source = { editable = "msgq_repo" } + +[package.metadata] +requires-dist = [ + { name = "catch2", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, + { name = "codespell", marker = "extra == 'dev'" }, + { name = "cppcheck", marker = "extra == 'dev'" }, + { name = "cpplint", marker = "extra == 'dev'" }, + { name = "cython", marker = "extra == 'dev'" }, + { name = "lefthook", marker = "extra == 'dev'" }, + { name = "parameterized", marker = "extra == 'dev'" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scons", marker = "extra == 'dev'" }, + { name = "setuptools", marker = "extra == 'dev'" }, + { name = "ty", marker = "extra == 'dev'" }, +] +provides-extras = ["dev"] + [[package]] name = "multidict" version = "6.7.1" @@ -706,46 +812,63 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, ] -[[package]] -name = "ncurses" -version = "6.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#eae89aae0266b3fbae7b808a3c0c19a97a82a81c" } - [[package]] name = "numpy" -version = "2.4.6" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/05/3d27272d30698dc0ecb7fdfaa41ad70303b444f81722bb99bce1d818638a/numpy-2.5.0.tar.gz", hash = "sha256:5a129578019311b6e56bdd714250f19b518f7dceeeb8d1af5490f4942d3f891c", size = 20652461, upload-time = "2026-06-21T20:57:51.95Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, - { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, - { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, - { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, - { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, - { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, - { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, - { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, - { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fa/0a/11486d02add7b1384dff7374d124b1cfbb0ee864dcc9f6a2c0380638cf84/numpy-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:489780423903667933b4ed6197b6ec3b75ea5dd17d1d8f0f38d798feb6921561", size = 16789987, upload-time = "2026-06-21T20:56:16.657Z" }, + { url = "https://files.pythonhosted.org/packages/55/b2/285f48640a181947b4587a3766d21ec1eaa7fea833d4b49957e09da467a2/numpy-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ece55976ced6bca95a03ae2839e2e5ccffe8eb6a3e7022415645eb154a81e4e6", size = 11760322, upload-time = "2026-06-21T20:56:19.813Z" }, + { url = "https://files.pythonhosted.org/packages/dd/67/b032db1eb03ca30d16eda3b0c22aaa615338b9263c2fd559d0f29451aca4/numpy-2.5.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:c83b664b0e6eee9594fa920cf0639d8af796606d3fad6cc70180c87e4b97c7be", size = 5319605, upload-time = "2026-06-21T20:56:22.173Z" }, + { url = "https://files.pythonhosted.org/packages/b9/83/03fc7300c7c6b6c84c487b1dc80d322817b95fbd1f4dd57a85e23b7198de/numpy-2.5.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bf80333980bf37f523341ddd72c783f39d6829ec7736b9eb99086388a2d52cc2", size = 6653628, upload-time = "2026-06-21T20:56:23.914Z" }, + { url = "https://files.pythonhosted.org/packages/82/49/2ec21730bc63ccfda829323f7040a8ed4715b3852ce658689cf74ee96a8c/numpy-2.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1a4874217b36d5ac8fc876f52e39df56f8182c88463e9e2dceabf7ca8b7efb8", size = 15153691, upload-time = "2026-06-21T20:56:25.631Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/f4a3d0637692c49da8ef99d72d52526f92e0a8d6ac4f0ca9f31441b9d9ea/numpy-2.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaa760137137e8d3c920d27927748215b56014f92667dc9b6c27dfc61249255a", size = 16660066, upload-time = "2026-06-21T20:56:28.009Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2f/c354ec86d1f3f5c19649463b0d39652e160736e5b0a4cd18dff0576715c4/numpy-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7174ce8265fc7f7417d171c9ea8fe905220748893ea67a2a7abe726ec331c4b0", size = 16514638, upload-time = "2026-06-21T20:56:30.26Z" }, + { url = "https://files.pythonhosted.org/packages/06/34/43efdcb319988648580f93c11f1ae82cf7e2faa74925e98e454ae3aa95f8/numpy-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b8c3daaf99de52415d20b42f8e8155c78642cb04207d02f9d317a0dcf1b3fb54", size = 18419647, upload-time = "2026-06-21T20:56:32.41Z" }, + { url = "https://files.pythonhosted.org/packages/71/e2/f5d1676b1d7fb682eb5e9a1641e7ebd2414b3216c370661d1029778908b4/numpy-2.5.0-cp312-cp312-win32.whl", hash = "sha256:6206db0af545d73d068add6d992279145f158428d1da6cc49adc4b630c5d6ee5", size = 6056688, upload-time = "2026-06-21T20:56:34.657Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7c/48f115d1c58a34032facebcd51fdf2d02df2c51d4a46a81dd1197bb2ea6b/numpy-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:6f2d6873e2940c860a309d21e25b1e69af6aaffdd80aa056b04c16380db1c4f2", size = 12419237, upload-time = "2026-06-21T20:56:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/86/26/2e0882f4044d1b1a1b63e875151fb2393389032022a8b7f5657a7996d3b2/numpy-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:a55e1eb2bca2cfd17a16b213c99dfc8502d47b0d494224d2122277d0400935ca", size = 10339912, upload-time = "2026-06-21T20:56:38.733Z" }, ] [[package]] -name = "opencv-python-headless" -version = "4.13.0.92" -source = { registry = "https://pypi.org/simple" } +name = "opendbc" +version = "0.3.1" +source = { editable = "opendbc_repo" } dependencies = [ { name = "numpy" }, + { name = "pycapnp" }, + { name = "pycryptodome" }, + { name = "tqdm" }, ] -wheels = [ - { url = "https://files.pythonhosted.org/packages/79/42/2310883be3b8826ac58c3f2787b9358a2d46923d61f88fedf930bc59c60c/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1a7d040ac656c11b8c38677cc8cccdc149f98535089dbe5b081e80a4e5903209", size = 46247192, upload-time = "2026-02-05T07:01:35.187Z" }, - { url = "https://files.pythonhosted.org/packages/2d/1e/6f9e38005a6f7f22af785df42a43139d0e20f169eb5787ce8be37ee7fcc9/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:3e0a6f0a37994ec6ce5f59e936be21d5d6384a4556f2d2da9c2f9c5dc948394c", size = 32568914, upload-time = "2026-02-05T07:01:51.989Z" }, - { url = "https://files.pythonhosted.org/packages/21/76/9417a6aef9def70e467a5bf560579f816148a4c658b7d525581b356eda9e/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c8cfc8e87ed452b5cecb9419473ee5560a989859fe1d10d1ce11ae87b09a2cb", size = 33703709, upload-time = "2026-02-05T10:24:46.469Z" }, - { url = "https://files.pythonhosted.org/packages/92/ce/bd17ff5772938267fd49716e94ca24f616ff4cb1ff4c6be13085108037be/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0525a3d2c0b46c611e2130b5fdebc94cf404845d8fa64d2f3a3b679572a5bd22", size = 56016764, upload-time = "2026-02-05T10:26:48.904Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b4/b7bcbf7c874665825a8c8e1097e93ea25d1f1d210a3e20d4451d01da30aa/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d", size = 35010236, upload-time = "2026-02-05T10:28:11.031Z" }, - { url = "https://files.pythonhosted.org/packages/4b/33/b5db29a6c00eb8f50708110d8d453747ca125c8b805bc437b289dbdcc057/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0bd48544f77c68b2941392fcdf9bcd2b9cdf00e98cb8c29b2455d194763cf99e", size = 60391106, upload-time = "2026-02-05T10:30:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/fb/c3/52cfea47cd33e53e8c0fbd6e7c800b457245c1fda7d61660b4ffe9596a7f/opencv_python_headless-4.13.0.92-cp37-abi3-win32.whl", hash = "sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b", size = 30812232, upload-time = "2026-02-05T07:02:29.594Z" }, - { url = "https://files.pythonhosted.org/packages/4a/90/b338326131ccb2aaa3c2c85d00f41822c0050139a4bfe723cfd95455bd2d/opencv_python_headless-4.13.0.92-cp37-abi3-win_amd64.whl", hash = "sha256:77a82fe35ddcec0f62c15f2ba8a12ecc2ed4207c17b0902c7a3151ae29f37fb6", size = 40070414, upload-time = "2026-02-05T07:02:26.448Z" }, + +[package.metadata] +requires-dist = [ + { name = "cffi", marker = "extra == 'testing'" }, + { name = "codespell", marker = "extra == 'testing'" }, + { name = "cpplint", marker = "extra == 'testing'" }, + { name = "gcovr", marker = "extra == 'testing'" }, + { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, + { name = "inputs", marker = "extra == 'examples'" }, + { name = "jinja2", marker = "extra == 'docs'" }, + { name = "lefthook", marker = "extra == 'testing'" }, + { name = "numpy" }, + { name = "pycapnp" }, + { name = "pycryptodome" }, + { name = "ruff", marker = "extra == 'testing'" }, + { name = "tqdm" }, + { name = "tree-sitter", marker = "extra == 'testing'" }, + { name = "tree-sitter-c", marker = "extra == 'testing'" }, + { name = "ty", marker = "extra == 'testing'" }, + { name = "unittest-parallel", marker = "extra == 'testing'" }, + { name = "zstandard", marker = "extra == 'testing'" }, +] +provides-extras = ["testing", "docs", "examples"] + +[package.metadata.requires-dev] +testing = [ + { name = "comma-car-segments", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" }, + { name = "cppcheck", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, ] [[package]] @@ -753,61 +876,47 @@ name = "openpilot" version = "0.1.0" source = { editable = "." } dependencies = [ - { name = "acados" }, - { name = "aiohttp" }, { name = "aiortc" }, { name = "av" }, - { name = "bootstrap-icons" }, - { name = "bzip2" }, - { name = "capnproto" }, - { name = "catch2" }, { name = "cffi" }, - { name = "crcmod-plus" }, + { name = "comma-deps-acados" }, + { name = "comma-deps-bootstrap-icons" }, + { name = "comma-deps-bzip2" }, + { name = "comma-deps-capnproto" }, + { name = "comma-deps-catch2" }, + { name = "comma-deps-ffmpeg" }, + { name = "comma-deps-gcc-arm-none-eabi" }, + { name = "comma-deps-git-lfs" }, + { name = "comma-deps-json11" }, + { name = "comma-deps-libusb" }, + { name = "comma-deps-ncurses" }, + { name = "comma-deps-raylib" }, + { name = "comma-deps-zeromq" }, + { name = "comma-deps-zstd" }, { name = "cython" }, - { name = "eigen" }, - { name = "ffmpeg" }, - { name = "gcc-arm-none-eabi" }, - { name = "git-lfs" }, { name = "inputs" }, { name = "jeepney" }, - { name = "json-rpc" }, - { name = "json11" }, - { name = "libjpeg" }, - { name = "libusb" }, - { name = "libusb1" }, - { name = "libyuv" }, - { name = "ncurses" }, { name = "numpy" }, { name = "pillow" }, - { name = "psutil" }, { name = "pycapnp" }, - { name = "pycryptodome" }, { name = "pyjwt" }, - { name = "pyserial" }, { name = "pyzmq" }, { name = "qrcode" }, - { name = "raylib" }, { name = "requests" }, { name = "scons" }, { name = "sentry-sdk" }, { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, - { name = "sympy" }, { name = "tqdm" }, { name = "websocket-client" }, { name = "xattr" }, - { name = "xvfb" }, - { name = "zeromq" }, { name = "zstandard" }, - { name = "zstd" }, ] [package.optional-dependencies] dev = [ { name = "matplotlib" }, - { name = "opencv-python-headless" }, ] docs = [ { name = "jinja2" }, @@ -827,52 +936,52 @@ testing = [ { name = "ty" }, ] tools = [ - { name = "imgui" }, - { name = "metadrive-simulator", marker = "platform_machine != 'aarch64'" }, + { name = "comma-deps-imgui" }, +] + +[package.dev-dependencies] +submodules = [ + { name = "msgq" }, + { name = "opendbc" }, + { name = "pandacan" }, + { name = "rednose" }, + { name = "teleoprtc" }, + { name = "tinygrad" }, ] [package.metadata] requires-dist = [ - { name = "acados", git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados" }, - { name = "aiohttp" }, { name = "aiortc" }, { name = "av" }, - { name = "bootstrap-icons", git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons" }, - { name = "bzip2", git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2" }, - { name = "capnproto", git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto" }, - { name = "catch2", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, { name = "cffi" }, { name = "codespell", marker = "extra == 'testing'" }, + { name = "comma-deps-acados" }, + { name = "comma-deps-bootstrap-icons" }, + { name = "comma-deps-bzip2" }, + { name = "comma-deps-capnproto" }, + { name = "comma-deps-catch2" }, + { name = "comma-deps-ffmpeg" }, + { name = "comma-deps-gcc-arm-none-eabi" }, + { name = "comma-deps-git-lfs" }, + { name = "comma-deps-imgui", marker = "extra == 'tools'" }, + { name = "comma-deps-json11" }, + { name = "comma-deps-libusb" }, + { name = "comma-deps-ncurses" }, + { name = "comma-deps-raylib" }, + { name = "comma-deps-zeromq" }, + { name = "comma-deps-zstd" }, { name = "coverage", marker = "extra == 'testing'" }, - { name = "crcmod-plus" }, { name = "cython" }, - { name = "eigen", git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen" }, - { name = "ffmpeg", git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg" }, - { name = "gcc-arm-none-eabi", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, - { name = "git-lfs", git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs" }, { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, - { name = "imgui", marker = "extra == 'tools'", git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui" }, { name = "inputs" }, { name = "jeepney" }, { name = "jinja2", marker = "extra == 'docs'" }, - { name = "json-rpc" }, - { name = "json11", git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11" }, - { name = "libjpeg", git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg" }, - { name = "libusb", git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb" }, - { name = "libusb1" }, - { name = "libyuv", git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv" }, { name = "matplotlib", marker = "extra == 'dev'" }, - { name = "metadrive-simulator", marker = "platform_machine != 'aarch64' and extra == 'tools'", git = "https://github.com/commaai/metadrive.git?rev=minimal" }, - { name = "ncurses", git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses" }, { name = "numpy", specifier = ">=2.0" }, - { name = "opencv-python-headless", marker = "extra == 'dev'" }, { name = "pillow" }, { name = "pre-commit-hooks", marker = "extra == 'testing'" }, - { name = "psutil" }, { name = "pycapnp", specifier = "==2.1.0" }, - { name = "pycryptodome" }, { name = "pyjwt" }, - { name = "pyserial" }, { name = "pytest", marker = "extra == 'testing'" }, { name = "pytest-cpp", marker = "extra == 'testing'" }, { name = "pytest-mock", marker = "extra == 'testing'" }, @@ -880,7 +989,6 @@ requires-dist = [ { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da" }, { name = "pyzmq" }, { name = "qrcode" }, - { name = "raylib", git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib" }, { name = "requests" }, { name = "ruff", marker = "extra == 'testing'" }, { name = "scons" }, @@ -888,20 +996,25 @@ requires-dist = [ { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, - { name = "sympy" }, { name = "tqdm" }, { name = "ty", marker = "extra == 'testing'" }, { name = "websocket-client" }, { name = "xattr" }, - { name = "xvfb", git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb" }, { name = "zensical", marker = "extra == 'docs'" }, - { name = "zeromq", git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq" }, { name = "zstandard" }, - { name = "zstd", git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd" }, ] provides-extras = ["docs", "testing", "dev", "tools"] +[package.metadata.requires-dev] +submodules = [ + { name = "msgq", editable = "msgq_repo" }, + { name = "opendbc", editable = "opendbc_repo" }, + { name = "pandacan", editable = "panda" }, + { name = "rednose", editable = "rednose_repo" }, + { name = "teleoprtc", editable = "teleoprtc_repo" }, + { name = "tinygrad", editable = "tinygrad_repo" }, +] + [[package]] name = "packaging" version = "26.2" @@ -912,61 +1025,50 @@ wheels = [ ] [[package]] -name = "panda3d" -version = "1.10.14" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/d4/90e98993b1a3f3c9fae83267f8c51186e676a8c1365c4180dfc65cd7ba62/panda3d-1.10.14-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1bfbcee77779f12ecce6a3d5a856e573b25d6343f8c4b107e814d9702e70a65d", size = 67839196, upload-time = "2024-01-08T19:01:00.417Z" }, - { url = "https://files.pythonhosted.org/packages/dc/e5/862821575073863ce49cc57b8349b47cb25ce11feae0e419b3d023ac1a69/panda3d-1.10.14-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:bc6540c5559d7e14a8992eff7de0157b7c42406b7ba221941ed224289496841c", size = 119271341, upload-time = "2024-01-08T19:01:09.455Z" }, - { url = "https://files.pythonhosted.org/packages/f4/20/f16d91805777825e530037177d9075c83da7384f12b778b133e3164a31f3/panda3d-1.10.14-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:143daab1ce6bedcba711ea3f6cab0ebe5082f22c5f43e7178fadd2dd01209da7", size = 47604077, upload-time = "2024-05-28T20:25:37.118Z" }, - { url = "https://files.pythonhosted.org/packages/11/69/806dcdbaee3e8deee1956abeea0d3d3e504315d2e9814de82a44809a8617/panda3d-1.10.14-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:3c4399a286a142de7ff86f9356d7e526bbbd38892d7f7d39fecb5c33064972bc", size = 55539594, upload-time = "2024-01-08T19:01:15.979Z" }, - { url = "https://files.pythonhosted.org/packages/ad/25/005de5e2b6d0acd546f8b3f2b547cd29e308cdd04a397f0ea68046e26571/panda3d-1.10.14-cp312-cp312-win32.whl", hash = "sha256:e92e0dd907e2af33085a2c31ca2263dc8023b1b7bc70ce1b9fbc84631e130e51", size = 53479813, upload-time = "2024-01-08T19:01:20.923Z" }, - { url = "https://files.pythonhosted.org/packages/74/bb/cb57563855da994614a33f57bd5691fbcd69f12e5ccddd30d387d0be287f/panda3d-1.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:a5f2defd822d38848f8ae1956115adcb6cc7f464f03a67e73681cc72df125ef4", size = 64893222, upload-time = "2024-01-08T19:01:26.347Z" }, +name = "pandacan" +version = "0.0.10" +source = { editable = "panda" } +dependencies = [ + { name = "libusb-package" }, + { name = "libusb1" }, + { name = "opendbc" }, ] -[[package]] -name = "panda3d-gltf" -version = "0.13" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "panda3d" }, - { name = "panda3d-simplepbr" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/07/7f/9f18fc3fa843a080acb891af6bcc12262e7bdf1d194a530f7042bebfc81f/panda3d-gltf-0.13.tar.gz", hash = "sha256:d06d373bdd91cf530909b669f43080e599463bbf6d3ef00c3558bad6c6b19675", size = 25573, upload-time = "2021-05-21T05:46:32.738Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/94/98ed1f81ca0f5daf6de80533805cc1e98ac162abe4e3e1d382caa7ba5c3c/panda3d_gltf-0.13-py3-none-any.whl", hash = "sha256:02d1a980f447bb1895ff4b48c667f289ba78f07a28ef308d8839b665a621efe2", size = 25568, upload-time = "2021-05-21T05:46:31.28Z" }, -] - -[[package]] -name = "panda3d-simplepbr" -version = "0.13.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "panda3d" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0d/be/c4d1ded04c22b357277cf6e6a44c1ab4abb285a700bd1991460460e05b99/panda3d_simplepbr-0.13.1.tar.gz", hash = "sha256:c83766d7c8f47499f365a07fe1dff078fc8b3054c2689bdc8dceabddfe7f1a35", size = 6216055, upload-time = "2025-03-30T16:57:41.087Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/5d/3744c6550dddf933785a37cdd4a9921fe13284e6d115b5a2637fe390f158/panda3d_simplepbr-0.13.1-py3-none-any.whl", hash = "sha256:cda41cb57cff035b851646956cfbdcc408bee42511dabd4f2d7bd4fbf48c57a9", size = 2457097, upload-time = "2025-03-30T16:57:39.729Z" }, +[package.metadata] +requires-dist = [ + { name = "cffi", marker = "extra == 'dev'" }, + { name = "cppcheck", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, + { name = "flaky", marker = "extra == 'dev'" }, + { name = "gcc-arm-none-eabi", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, + { name = "libusb-package" }, + { name = "libusb1" }, + { name = "opendbc", git = "https://github.com/sunnypilot/opendbc.git?rev=master" }, + { name = "pycryptodome", marker = "extra == 'dev'", specifier = ">=3.9.8" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-mock", marker = "extra == 'dev'" }, + { name = "pytest-timeout", marker = "extra == 'dev'" }, + { name = "pytest-xdist", marker = "extra == 'dev'" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scons", marker = "extra == 'dev'" }, + { name = "setuptools", marker = "extra == 'dev'" }, ] +provides-extras = ["dev"] [[package]] name = "pillow" -version = "12.2.0" +version = "12.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279, upload-time = "2026-04-01T14:43:13.246Z" }, - { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490, upload-time = "2026-04-01T14:43:15.584Z" }, - { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462, upload-time = "2026-04-01T14:43:18.268Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744, upload-time = "2026-04-01T14:43:20.716Z" }, - { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371, upload-time = "2026-04-01T14:43:23.443Z" }, - { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215, upload-time = "2026-04-01T14:43:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783, upload-time = "2026-04-01T14:43:29.56Z" }, - { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112, upload-time = "2026-04-01T14:43:32.091Z" }, - { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489, upload-time = "2026-04-01T14:43:34.601Z" }, - { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129, upload-time = "2026-04-01T14:43:37.213Z" }, - { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, ] [[package]] @@ -1016,22 +1118,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, ] -[[package]] -name = "psutil" -version = "7.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, - { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, - { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, - { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, - { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, - { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, - { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, -] - [[package]] name = "pycapnp" version = "2.1.0" @@ -1134,28 +1220,28 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.21.3" +version = "11.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140, upload-time = "2026-05-13T12:57:32.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/a9/5f0c535ba3b08fe09270c16808e053a968868242ecbd5676d4e3a488bf28/pymdown_extensions-11.0.1.tar.gz", hash = "sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0", size = 857113, upload-time = "2026-07-02T17:59:22.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002, upload-time = "2026-05-13T12:57:30.296Z" }, + { url = "https://files.pythonhosted.org/packages/d6/54/da572c98c0b77626a91b5d3b89f0231d8bff5125c225420908632f8b342d/pymdown_extensions-11.0.1-py3-none-any.whl", hash = "sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2", size = 269455, upload-time = "2026-07-02T17:59:21.271Z" }, ] [[package]] name = "pyopenssl" -version = "26.2.0" +version = "26.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1a/51/27a5ad5f939d08f690a326ef9582cda7140555180db71695f6fb747d6a36/pyopenssl-26.2.0.tar.gz", hash = "sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387", size = 182195, upload-time = "2026-05-04T23:06:09.72Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/b7/da07bae88f5a9506b4def6f2f4903cf4c3b8831e560dba8fa18ca08f758f/pyopenssl-26.3.0.tar.gz", hash = "sha256:589de7fae1c9ea670d18422ed00fc04da787bbde8e1454aea872aa57b49ad341", size = 182024, upload-time = "2026-06-12T20:28:07.458Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl", hash = "sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70", size = 55823, upload-time = "2026-05-04T23:06:08.395Z" }, + { url = "https://files.pythonhosted.org/packages/54/18/1dd71c9b43192ab83f1d531ad6002dc81108ac36c475f79fb7a295abe2f4/pyopenssl-26.3.0-py3-none-any.whl", hash = "sha256:46367f8f66b92271e6d218da9c87607e1ef5a0bc5c8dea5bb3db82f395c385a3", size = 56008, upload-time = "2026-06-12T20:28:05.999Z" }, ] [[package]] @@ -1167,18 +1253,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] -[[package]] -name = "pyserial" -version = "3.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125, upload-time = "2020-11-23T03:59:15.045Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585, upload-time = "2020-11-23T03:59:13.41Z" }, -] - [[package]] name = "pytest" -version = "9.0.3" +version = "9.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1187,9 +1264,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] [[package]] @@ -1231,7 +1308,7 @@ wheels = [ [[package]] name = "pytest-xdist" -version = "3.7.1.dev24+g2b4372bd6" +version = "3.7.1.dev24+g2b4372b" source = { git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da#2b4372bd62699fb412c4fe2f95bf9f01bd2018da" } dependencies = [ { name = "execnet" }, @@ -1302,13 +1379,34 @@ wheels = [ ] [[package]] -name = "raylib" -version = "6.0.0.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#dbf05cd774c2f74a70a0ee9ebb80015ed70ce718" } +name = "rednose" +version = "0.0.1" +source = { editable = "rednose_repo" } dependencies = [ { name = "cffi" }, + { name = "comma-deps-eigen" }, + { name = "cython" }, + { name = "numpy" }, + { name = "scons" }, + { name = "setuptools" }, + { name = "sympy" }, ] +[package.metadata] +requires-dist = [ + { name = "cffi" }, + { name = "comma-deps-eigen" }, + { name = "cython" }, + { name = "numpy" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scipy", marker = "extra == 'dev'" }, + { name = "scons" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "ty", marker = "extra == 'dev'" }, +] +provides-extras = ["dev"] + [[package]] name = "requests" version = "2.34.2" @@ -1335,27 +1433,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.16" +version = "0.15.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/5f7ec371001337d8fa61701c186ff8b613ecac1651848c5950f4c4d5f2e9/ruff-0.15.16.tar.gz", hash = "sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78", size = 4714267, upload-time = "2026-06-04T16:33:09.974Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/42/53ef1c3953f157956db9bf7861e3bc50b9b887ce93300aa48cdba8336fe6/ruff-0.15.16-py3-none-linux_armv6l.whl", hash = "sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2", size = 10709025, upload-time = "2026-06-04T16:32:51.935Z" }, - { url = "https://files.pythonhosted.org/packages/93/9a/a79159346f19134a956607754e57d8d128f7a4c00f4ad2f7514d224c172c/ruff-0.15.16-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a", size = 11063550, upload-time = "2026-06-04T16:32:42.24Z" }, - { url = "https://files.pythonhosted.org/packages/bc/72/3ce2ac000a5299ec238e01f51397b3b653c93b077d9b1bfe8715bb895f20/ruff-0.15.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071", size = 10421345, upload-time = "2026-06-04T16:32:37.251Z" }, - { url = "https://files.pythonhosted.org/packages/b0/c2/cc7fad3ec9169373f5b6a18f1917b91080feec40c3f9658334a1d28e2f03/ruff-0.15.16-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf", size = 10757217, upload-time = "2026-06-04T16:32:54.722Z" }, - { url = "https://files.pythonhosted.org/packages/69/d2/3474009eaa0a65b31fa7152a2fad5e2f050c640ceb1e6b02ee6922e94c82/ruff-0.15.16-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d", size = 10507035, upload-time = "2026-06-04T16:33:05.343Z" }, - { url = "https://files.pythonhosted.org/packages/ca/81/b7ae6ccbd11f0c8dc3d5d67fc4be9b57ff57ca86ba56152021378e1277f2/ruff-0.15.16-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628", size = 11255291, upload-time = "2026-06-04T16:32:49.49Z" }, - { url = "https://files.pythonhosted.org/packages/d9/e1/46e526f1a7cc90857ce6ddf25fbb77eb6568651ac38d71b033af07076dd5/ruff-0.15.16-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb", size = 12124922, upload-time = "2026-06-04T16:33:07.821Z" }, - { url = "https://files.pythonhosted.org/packages/1a/da/5c791b088b596b24d0deb967fa28ae02ad751a140c0b9ea81c5ab915d6c0/ruff-0.15.16-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4", size = 11332186, upload-time = "2026-06-04T16:33:02.971Z" }, - { url = "https://files.pythonhosted.org/packages/72/11/5da87abe20047c8962361473923ebb2f62b595250126aadfad8c20649c1e/ruff-0.15.16-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb", size = 11373541, upload-time = "2026-06-04T16:32:47.007Z" }, - { url = "https://files.pythonhosted.org/packages/fe/2a/8554754c23a854ae3fd6b507e36ad61ddb121e298c6d5d617dec94ed0f14/ruff-0.15.16-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951", size = 11353014, upload-time = "2026-06-04T16:32:34.795Z" }, - { url = "https://files.pythonhosted.org/packages/62/25/62ea41529ec89f742ea3fed9cb1059c72877ec7cf9b9e99ac9cf3294d1d9/ruff-0.15.16-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8", size = 10737467, upload-time = "2026-06-04T16:32:26.348Z" }, - { url = "https://files.pythonhosted.org/packages/90/17/334d3ad9de4d40f9dd58fdd09e35ce64553bb501e2f19a839e2fb6be14fc/ruff-0.15.16-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123", size = 10521910, upload-time = "2026-06-04T16:32:32.54Z" }, - { url = "https://files.pythonhosted.org/packages/4d/bd/3ac7c6ae77a885c1004b3dda2446ea401768d24f851c14b4ad4b24f6639c/ruff-0.15.16-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a", size = 10979190, upload-time = "2026-06-04T16:32:57.492Z" }, - { url = "https://files.pythonhosted.org/packages/33/d7/609546e6a413c3f216fbf2a50c928f97c80939154f6a0503114094a86191/ruff-0.15.16-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3", size = 11477014, upload-time = "2026-06-04T16:32:44.687Z" }, - { url = "https://files.pythonhosted.org/packages/74/0d/f2cd247ad32633a5c36e97141a2c21b11c6279f7957bc2ff360b1e08fddd/ruff-0.15.16-py3-none-win32.whl", hash = "sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e", size = 10735541, upload-time = "2026-06-04T16:32:30.145Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9e/02e845ef151b1dee585e55c4739f8e1734ae1d9f1221dff65761c162208b/ruff-0.15.16-py3-none-win_amd64.whl", hash = "sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec", size = 11843403, upload-time = "2026-06-04T16:32:39.76Z" }, - { url = "https://files.pythonhosted.org/packages/15/19/016553f86f207450aebebc2b2b5088d086b901cc8186c02ac4284db3bd88/ruff-0.15.16-py3-none-win_arm64.whl", hash = "sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121", size = 11134555, upload-time = "2026-06-04T16:33:00.136Z" }, + { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, + { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, + { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, + { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, + { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, ] [[package]] @@ -1369,15 +1467,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.62.0" +version = "2.64.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/5d/a343201726150e05f2036eeb6e493e2e2f8bf8a66f5aa70f2f4ac96f9ca3/sentry_sdk-2.62.0.tar.gz", hash = "sha256:3c870b9f50d9fd15b58c817dbde1c7cfaa9fe3f05df0a4c6edd5571cb82f5491", size = 463986, upload-time = "2026-06-08T13:23:49.223Z" } +sdist = { url = "https://files.pythonhosted.org/packages/60/31/b7341f156a5f6f36f0b4845d6f1c28a2ae4799171dba7007f3a1e9b234b4/sentry_sdk-2.64.0.tar.gz", hash = "sha256:68be2c29e14ae310f8a39e1a79916b6d85c6cb41dcce789d14ff05fe293e4c55", size = 921020, upload-time = "2026-06-30T08:13:47.682Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/07/05440381627877aae223fd68f330df9b9fc6641d08bf65328b55235617a2/sentry_sdk-2.62.0-py3-none-any.whl", hash = "sha256:27f61d13a86c3c1648dec666dd5a64f79772dd6a84b446f11866601ecab24f6f", size = 490586, upload-time = "2026-06-08T13:23:47.486Z" }, + { url = "https://files.pythonhosted.org/packages/36/a8/3fb9a4319efa3b26f5be0e90e6d8918df43fa7c7e977d26390f589501d82/sentry_sdk-2.64.0-py3-none-any.whl", hash = "sha256:715ea91ca860a819e8d8a50a7bde3a80d0df3b4ed7b6660a20fb9a2d084188f1", size = 498901, upload-time = "2026-06-30T08:13:45.566Z" }, ] [[package]] @@ -1441,12 +1539,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/39/a61d4b83a7746b70d23d9173be688c0c6bfc7173772344b7442c2c155497/sounddevice-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3861901ddd8230d2e0e8ae62ac320cdd4c688d81df89da036dcb812f757bb3e6", size = 317115, upload-time = "2026-01-23T18:36:42.235Z" }, ] -[[package]] -name = "spidev" -version = "3.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/67/87/039b6eeea781598015b538691bc174cc0bf77df9d4d2d3b8bf9245c0de8c/spidev-3.8.tar.gz", hash = "sha256:2bc02fb8c6312d519ebf1f4331067427c0921d3f77b8bcaf05189a2e8b8382c0", size = 13893, upload-time = "2025-09-15T18:56:20.672Z" } - [[package]] name = "sympy" version = "1.14.0" @@ -1459,6 +1551,89 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] +[[package]] +name = "teleoprtc" +version = "1.0.1" +source = { editable = "teleoprtc_repo" } +dependencies = [ + { name = "aiohttp" }, + { name = "aiortc" }, + { name = "av" }, + { name = "numpy" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", specifier = ">=3.7.0" }, + { name = "aiortc", specifier = ">=1.6.0" }, + { name = "av", specifier = ">=11.0.0,<13.0.0" }, + { name = "numpy", specifier = ">=1.19.0" }, + { name = "parameterized", marker = "extra == 'dev'", specifier = ">=0.8" }, + { name = "pre-commit", marker = "extra == 'dev'" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-asyncio", marker = "extra == 'dev'" }, + { name = "pytest-xdist", marker = "extra == 'dev'" }, +] +provides-extras = ["dev"] + +[[package]] +name = "tinygrad" +version = "0.12.0" +source = { editable = "tinygrad_repo" } + +[package.metadata] +requires-dist = [ + { name = "black", marker = "extra == 'docs'" }, + { name = "blobfile", marker = "extra == 'testing'" }, + { name = "boto3", marker = "extra == 'testing'" }, + { name = "bottle", marker = "extra == 'testing'" }, + { name = "capstone", marker = "extra == 'testing-unit'" }, + { name = "gguf", marker = "extra == 'testing-unit'", specifier = ">=0.18" }, + { name = "hypothesis", marker = "extra == 'testing-minimal'", specifier = ">=6.148.9" }, + { name = "influxdb3-python", marker = "extra == 'testing'" }, + { name = "librosa", marker = "extra == 'testing'" }, + { name = "markdown-callouts", marker = "extra == 'docs'" }, + { name = "markdown-exec", extras = ["ansi"], marker = "extra == 'docs'" }, + { name = "mkdocs", marker = "extra == 'docs'" }, + { name = "mkdocs-material", marker = "extra == 'docs'" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'" }, + { name = "mypy", marker = "extra == 'linting'", specifier = "==1.19.1" }, + { name = "networkx", marker = "extra == 'testing'" }, + { name = "nibabel", marker = "extra == 'testing'" }, + { name = "numba", marker = "extra == 'testing'", specifier = ">=0.55" }, + { name = "numpy", marker = "extra == 'docs'" }, + { name = "numpy", marker = "extra == 'linting'" }, + { name = "numpy", marker = "extra == 'testing-minimal'" }, + { name = "onnx", marker = "extra == 'testing'", specifier = "==1.19.0" }, + { name = "onnx2torch", marker = "extra == 'testing'" }, + { name = "onnxruntime", marker = "extra == 'testing'" }, + { name = "openai", marker = "extra == 'testing-unit'" }, + { name = "opencv-python", marker = "extra == 'testing'" }, + { name = "pandas", marker = "extra == 'testing'" }, + { name = "pillow", marker = "extra == 'testing'" }, + { name = "pre-commit", marker = "extra == 'linting'" }, + { name = "pycocotools", marker = "extra == 'testing'" }, + { name = "pylint", marker = "extra == 'linting'" }, + { name = "pytest", marker = "extra == 'testing-minimal'" }, + { name = "pytest-split", marker = "extra == 'testing-minimal'" }, + { name = "pytest-timeout", marker = "extra == 'testing-minimal'" }, + { name = "pytest-xdist", marker = "extra == 'testing-minimal'" }, + { name = "ruff", marker = "extra == 'linting'", specifier = "==0.14.10" }, + { name = "safetensors", marker = "extra == 'testing-unit'" }, + { name = "sentencepiece", marker = "extra == 'testing'" }, + { name = "tabulate", marker = "extra == 'testing-unit'" }, + { name = "tiktoken", marker = "extra == 'testing'" }, + { name = "tinygrad", extras = ["testing-minimal"], marker = "extra == 'testing-unit'" }, + { name = "tinygrad", extras = ["testing-unit"], marker = "extra == 'testing'" }, + { name = "torch", marker = "extra == 'testing-minimal'", specifier = "==2.9.1" }, + { name = "tqdm", marker = "extra == 'testing-unit'" }, + { name = "transformers", marker = "extra == 'testing'" }, + { name = "typeguard", marker = "extra == 'linting'" }, + { name = "typing-extensions", marker = "extra == 'linting'" }, + { name = "z3-solver", marker = "extra == 'testing-minimal'", specifier = "<4.15.4" }, +] +provides-extras = ["linting", "testing-minimal", "testing-unit", "testing", "docs"] + [[package]] name = "tomli" version = "2.4.1" @@ -1479,48 +1654,48 @@ wheels = [ [[package]] name = "tqdm" -version = "4.68.1" +version = "4.68.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/b3/36c8ecf72e8925200671613332db156d84b99b3aee742a41c1938ebb0808/tqdm-4.68.1.tar.gz", hash = "sha256:fc163d96b287bd031e1aa24421ce4411b25559bd0a1be4fe649bdaa4d2c02bf5", size = 171236, upload-time = "2026-06-05T17:23:15.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/d7/0535a28b1f5f24f6612fb3ff1e89fb1a8d160fee0f976e0aa6803862134b/tqdm-4.68.3.tar.gz", hash = "sha256:00dfa48452b6b6cfae3dd9885636c23d3422d1ec97c66d96818cbd5e0821d482", size = 170596, upload-time = "2026-06-17T07:36:52.105Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/aa/218a0eb34de1f753c83e4d0d1c8e7c4cef27f20dcb8342e024f63a80dc86/tqdm-4.68.1-py3-none-any.whl", hash = "sha256:fea4a90e4023f764914569f7802a297277c5ab1a66be5144143e142e1a4031d8", size = 78354, upload-time = "2026-06-05T17:23:13.654Z" }, + { url = "https://files.pythonhosted.org/packages/d8/8e/bb97bb0c71802080bfc8952937d174e49cfc50de5c951dd47b2496f0dcdb/tqdm-4.68.3-py3-none-any.whl", hash = "sha256:39832cc2def2789a6f29df83f172db7416cea70052c0907a57801c5f2fdccb03", size = 78337, upload-time = "2026-06-17T07:36:50.132Z" }, ] [[package]] name = "ty" -version = "0.0.46" +version = "0.0.56" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/7d/d95b5a9dea83472006be3ce5e480028c44b34138d84d0172e910f287fb69/ty-0.0.46.tar.gz", hash = "sha256:c6c2d7105b5633b49950b4c3a90d1ed2613eb9d794ad582bbbf6c4ffcb93accf", size = 5832380, upload-time = "2026-06-09T03:28:05.056Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/07/fb29aea5235b0aa8ecfc4d1cc6ddf9fba8b863d67d96c6d345694d644c43/ty-0.0.56.tar.gz", hash = "sha256:84d114dc3796361c0fc72945016eabd74d46b9ee64f198cb0e485719704681e5", size = 6050123, upload-time = "2026-07-01T16:44:56.036Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/24/f9f7533c391610521f4164e6b8e37ef72d0c1ee8651bc0d9ce9e658b953b/ty-0.0.46-py3-none-linux_armv6l.whl", hash = "sha256:5e716337994699cbc1a1a7b7a3e6622306f2574c710330f9d9691c2c3d8391b0", size = 11756264, upload-time = "2026-06-09T03:28:20.112Z" }, - { url = "https://files.pythonhosted.org/packages/66/49/ff3d13655b9b5cc8176f4c3446bf7ec2df43c8ad9e5272d4adc5d952fa45/ty-0.0.46-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:51d618dec5403635690d0e3e298cd0ad3d84ebc6a576652939ef30ce96fce4b2", size = 11492723, upload-time = "2026-06-09T03:28:13.23Z" }, - { url = "https://files.pythonhosted.org/packages/82/4a/e7e3209e353c5835c7756339bbcdfda10852407b80fbb9ed46c17241873a/ty-0.0.46-py3-none-macosx_11_0_arm64.whl", hash = "sha256:acbafd6a2351b07a6cf4c945b0b1d47f6d2826faac2526a351dfa74d3a3cc664", size = 10892822, upload-time = "2026-06-09T03:27:51.179Z" }, - { url = "https://files.pythonhosted.org/packages/6c/20/4390c90434a9ddefcecb65e8df00e4c2700e9739dc0baf58bed36d25f713/ty-0.0.46-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de5df602ffd760612ae36602bbad69b0123ff6cffd92e62aa92b7709317d69e3", size = 11408745, upload-time = "2026-06-09T03:27:58.049Z" }, - { url = "https://files.pythonhosted.org/packages/75/0c/f13a1bf9c6798530c773667095a6cf8f73ec9721db359423e7249bff7fbc/ty-0.0.46-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7abf5a10b30d8641faad90f6a19989daec941bb90261159e05cfeb04d2012046", size = 11544432, upload-time = "2026-06-09T03:27:53.519Z" }, - { url = "https://files.pythonhosted.org/packages/56/69/eb3710c13dff846a0362df04fadd8a39b64ccc244c0d02ce5285ede8eae5/ty-0.0.46-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8770404139c6ccee2ce2fc226478cfa4100915133c876c257e52197b8b92051d", size = 12031228, upload-time = "2026-06-09T03:28:29.816Z" }, - { url = "https://files.pythonhosted.org/packages/e9/68/5f5db9c84c1d44acdc67281089b372d9d818ee68123a60c59c66187095e2/ty-0.0.46-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f960d5a6e4860076924d2b86891d9872c4a3daa4663fb416e640b22cf3dbf68e", size = 12596073, upload-time = "2026-06-09T03:28:25.204Z" }, - { url = "https://files.pythonhosted.org/packages/14/be/cfd0bb272e6a1491f6de30c60da1f39c2b3c3524ec64a5c92b71365c9185/ty-0.0.46-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d9000a4a3ed08fc37e8a2ff0b801cde06e1c2af3bc053677744bb5a1b751030", size = 12284885, upload-time = "2026-06-09T03:28:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/a8/3a/2cd541f6320f5d6f70a45725c4e1016efedd5545348bb23b47ffb3e4c724/ty-0.0.46-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1160e6dc86536109ab755f7142f36f4dda5333c8330cf230d61819494d27125", size = 12079480, upload-time = "2026-06-09T03:27:55.847Z" }, - { url = "https://files.pythonhosted.org/packages/de/91/8e0075bc6568fb477e7ef4d805c67fa6902b692cb4419e0bf5ce3c04c5bc/ty-0.0.46-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b619c0efe007731f8221fa787701bfa4402da7a83eb26c61ae25e77b6ace6384", size = 12316547, upload-time = "2026-06-09T03:28:08.28Z" }, - { url = "https://files.pythonhosted.org/packages/00/28/b96cbfeda019a4044c6a8cd06ff84d08b631d4ba7d9a1e6dc0311df3563a/ty-0.0.46-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ad98fccb6a8a94c4121b993761a0deee602f5826c4162e0a91f4f8118ddadd42", size = 11392846, upload-time = "2026-06-09T03:28:00.418Z" }, - { url = "https://files.pythonhosted.org/packages/3b/d0/4d77f699a95ac7a13b94ca1a58682667cfe974f91557d9e2a9fc0b808a7f/ty-0.0.46-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:74536b13c3cc3f5944408669c202d4c57c3d19ff154732df8e6145718aef9191", size = 11559017, upload-time = "2026-06-09T03:28:17.619Z" }, - { url = "https://files.pythonhosted.org/packages/88/62/1d6f6b51c2b132da8011c6a41ead0c1fd2a0b17ea72304bcf6ce084d581a/ty-0.0.46-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5e50b1e96ced41b609e24ed27d9e4f508584ed7f4d0bb717ca8c8d75d2fd1b7c", size = 11666509, upload-time = "2026-06-09T03:28:22.454Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9a/6643894bc12cb30c281f4c8bf37f6d30c1fbd9484ef39a12b0ea6dae3c1c/ty-0.0.46-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0a7d9f58d26d938e5d2f607481b7a412d8c00d675a1ec72004fa9d6b3b9def99", size = 12180448, upload-time = "2026-06-09T03:28:32.329Z" }, - { url = "https://files.pythonhosted.org/packages/86/68/0f3b7bb03a7da676ef51b1c0af0bde1e500d69d5f0c807ed63b6f30b66dd/ty-0.0.46-py3-none-win32.whl", hash = "sha256:26db0ce89c573e60132d14e9688c9329a1633b1a8c26fe457025c7c406f7d5e6", size = 10960002, upload-time = "2026-06-09T03:28:02.832Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f4/91ff618b2dee39d0633d23e1adac0174aa1de80df17e270acac534034dbc/ty-0.0.46-py3-none-win_amd64.whl", hash = "sha256:90e8e6d446b9cb7cb4bede9fca7b3c99fd1e2355605ecf431c131a51db2a5e93", size = 12097413, upload-time = "2026-06-09T03:28:27.495Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2e/300174fca375a27a7c28dd80e990d857d7b3e3b25980c65063f980aa2f17/ty-0.0.46-py3-none-win_arm64.whl", hash = "sha256:ebd320d82605079b901a095dc4711037a0c488b4ace79a602fef4df0d3f4cf74", size = 11439595, upload-time = "2026-06-09T03:28:15.355Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/bce79e7ca5c1cc529d3e0d37ddd1121aea4b68a4f749974ad1cc77161871/ty-0.0.56-py3-none-linux_armv6l.whl", hash = "sha256:186d4a53e15747c947e1ec3d7eec8e345d8e40a1ca10e634c585db52497e87dd", size = 11643066, upload-time = "2026-07-01T16:44:18.374Z" }, + { url = "https://files.pythonhosted.org/packages/80/d1/22555d8a1d719661f10050f3865d877bbf497da908961c75fe22217dd18a/ty-0.0.56-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aae1a980fd9535da0469b7ba2b2e1b54a907743a5e0f442dd57eee9f5bfd034c", size = 11407487, upload-time = "2026-07-01T16:44:20.956Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2d/b3b7a74ce8bc59ef48843ad80179bb0d9598bbd6cfc0d11d519bdf6b1352/ty-0.0.56-py3-none-macosx_11_0_arm64.whl", hash = "sha256:afd3058c0a6c5f241e814734f133008c93ee805f61c9cf4ce7412b8822b5d9ad", size = 10962270, upload-time = "2026-07-01T16:44:22.959Z" }, + { url = "https://files.pythonhosted.org/packages/64/ac/6c2fd7de0304a8a7218a756af74f7e62a5e8540fdb175e0a869e51042345/ty-0.0.56-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:058b52f7a823ac13aae3cae30809dd6b5145794b64d8478f9ef38c75d79b4483", size = 11471406, upload-time = "2026-07-01T16:44:25.327Z" }, + { url = "https://files.pythonhosted.org/packages/50/b6/11d861156861c03c7726b74558f9a0e0092661aff83a4fda1279df28c425/ty-0.0.56-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c66e00c1522add1f2bbdd2e45828c953b35c306b7bef03ec9169c75a63699a0", size = 11445612, upload-time = "2026-07-01T16:44:27.531Z" }, + { url = "https://files.pythonhosted.org/packages/fb/ba/09df108582090f3c0770ec4bc8675affed60248f6793a78d909be16211d9/ty-0.0.56-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40903d71c669a30691b5a5d5728056c7877a1bd6be4f233a38883a8b28cf34d7", size = 12093889, upload-time = "2026-07-01T16:44:29.548Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f7/dbb4b4ccb69cd64c209ae55b1ab788ace8222c2bc1f6845be9e7cbedbf25/ty-0.0.56-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63fe3947fe0c46c69a7d950e6832ee70a9ec17321fefbff3d2e3c20baf9e5bd0", size = 12666337, upload-time = "2026-07-01T16:44:31.586Z" }, + { url = "https://files.pythonhosted.org/packages/86/e9/73f903fe4a3d9ea02f26f57c1eb07e3b1029ec92b0e8c2364718893440e3/ty-0.0.56-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71a0c1a72f9854532e710e119b6871ffe4542c8a65146f1f65dcd78fecd885b4", size = 12280247, upload-time = "2026-07-01T16:44:33.637Z" }, + { url = "https://files.pythonhosted.org/packages/d6/90/cebd222495832f1a00dcd321ba25f3cab804221a4991b992c2178bec68ee/ty-0.0.56-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70d1665596494e24d8ebd198438872b5a56ec3cae5f2bcf6c673be797acc4e3c", size = 11991107, upload-time = "2026-07-01T16:44:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/b7/07/8f7337a07250f42d975cdb6decf47fc5b421e6c7da5e3e7be1e85f63a7e5/ty-0.0.56-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:778f99e51558afc1dbbe48ee38ab6aae7b31390ed8c1a1ef1499b295e9f1e82f", size = 12298970, upload-time = "2026-07-01T16:44:38.243Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b9/a52cd59034a48f5f18c6b155cc2cc36861d874b6d0af204b12c898024c3d/ty-0.0.56-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:867bc5708e0066bb4ff6c7db524bd5deea2676c62bfe71d3303138b3be850af0", size = 11425683, upload-time = "2026-07-01T16:44:40.473Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2e/48e42d33357d52eefb695c0c3fcfc96879b73668a7447d1d1e0ad774fedc/ty-0.0.56-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6012f4189c928edb330a37deb9930f982380bd4aa7c4b8e0428eec9651c7551", size = 11469258, upload-time = "2026-07-01T16:44:42.513Z" }, + { url = "https://files.pythonhosted.org/packages/d5/01/ad1b4138be1e3fa97863af3925aa2134f17a593240c35dc38c3429fb5ad1/ty-0.0.56-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8ee83de1a7ff4cc32837ec06134ce391d441bc5b35ecd8d3cfe053f120f3e4c1", size = 11758736, upload-time = "2026-07-01T16:44:44.567Z" }, + { url = "https://files.pythonhosted.org/packages/09/34/9d81967ff240eaa57e9249728ef7b7790747cf6d3c9a98ec86b2cfdcc8ee/ty-0.0.56-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:62619b3b0e2c6248ef30d3f0e2f2217ae9893040585be07f32324242f197cd6f", size = 12100242, upload-time = "2026-07-01T16:44:46.584Z" }, + { url = "https://files.pythonhosted.org/packages/c3/36/f51d4666d2de6cf33c1f3a1fcc4bb6b70b197dd6ceaa491eef71d78fe8e8/ty-0.0.56-py3-none-win32.whl", hash = "sha256:b30687bb5cd9729d34c889a289edf32770388d9bb05243e534e723fb45e0381b", size = 11093759, upload-time = "2026-07-01T16:44:49.171Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b4/8fb5d4acfa4afb152245b20fa263069a7547bd1f8e4bfca4eda280c897d7/ty-0.0.56-py3-none-win_amd64.whl", hash = "sha256:ad4c8c47b6f4e3f9ed3fc0b1a5d650088d229e17dd8f63c1826d6bbe94cc3235", size = 12100327, upload-time = "2026-07-01T16:44:51.26Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fc/6a183e71edde90d0c35c2303f23f7a45b6891d1a2c45daf7b8f869831e19/ty-0.0.56-py3-none-win_arm64.whl", hash = "sha256:57538f273d444a5f1293fa7860e967178afe3917611fc5eff16b64e1204fe0d6", size = 11538780, upload-time = "2026-07-01T16:44:53.8Z" }, ] [[package]] name = "typing-extensions" -version = "4.15.0" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] @@ -1559,11 +1734,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/63/188f7cb41ab35d795558325d5cc8ab552171d5498cfb178fd14409651e18/xattr-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2aaa5d66af6523332189108f34e966ca120ff816dfa077ca34b31e6263f8a236", size = 37754, upload-time = "2025-10-13T22:16:15.306Z" }, ] -[[package]] -name = "xvfb" -version = "1.20.11.post1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#f0bb0b0d9154ea7858f3c0333b607ba7d356b571" } - [[package]] name = "yarl" version = "1.24.2" @@ -1597,7 +1767,7 @@ wheels = [ [[package]] name = "zensical" -version = "0.0.44" +version = "0.0.46" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -1609,27 +1779,22 @@ dependencies = [ { name = "pyyaml" }, { name = "tomli" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/44/e8c891e607708ed6e2b38620948f0715d13cb378f9525caab84aaf4dfb6c/zensical-0.0.44.tar.gz", hash = "sha256:7452eb2a88e2e42e9a9d7861c5ee6a3b4413766a5c737aa6dc840dab344d46aa", size = 3934771, upload-time = "2026-06-04T17:30:53.326Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/57/c7bbb71f943e1e0ba5ce460f4930ec836ead7286969e7fd742f7a6c049ab/zensical-0.0.46.tar.gz", hash = "sha256:3ec21f4fb1e78cd7c0d6b07ae336b04770e27ba020dabc457b2790e5d34f1978", size = 3973968, upload-time = "2026-06-21T18:52:40.368Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/0f/08c503dff4077c66a99f00556d02f16bd1c67790e43cdd256499d6cab251/zensical-0.0.44-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:f7d562b231129356c1ac0a05147d48da759111b671be5c2d4ff6765639550606", size = 12702807, upload-time = "2026-06-04T17:30:18.476Z" }, - { url = "https://files.pythonhosted.org/packages/f7/01/88806c9e8ca6caa246dd9c5c3e15a8d25015c0862820e32b5cfd5cf01d56/zensical-0.0.44-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:534c5303b7f3e4e842a2aa21cd6afe1a19b89a62cda22bff64a8932d988c1e2a", size = 12575802, upload-time = "2026-06-04T17:30:21.617Z" }, - { url = "https://files.pythonhosted.org/packages/5e/21/bc55faf26e5a5e6d8b9216b9efba8a5f2b8c1db09d123b077696e5286fd9/zensical-0.0.44-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3255e14e648571eba1fc51b5d638e5738b96579acc2fd346ae94bb00ca1a37b9", size = 12944141, upload-time = "2026-06-04T17:30:24.532Z" }, - { url = "https://files.pythonhosted.org/packages/2d/62/27f934e443894174cddd1cc1d99fb296e0657611a21fdceb4e071a1207ac/zensical-0.0.44-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:83b167831e181451d266aedad66bf4d199b8ee3147439261c4193bcea09fd8b2", size = 12916341, upload-time = "2026-06-04T17:30:28.134Z" }, - { url = "https://files.pythonhosted.org/packages/18/65/aaa4f0630cb5cd5083176e45af9221bcabfc304af961a5c180f64b5a4dde/zensical-0.0.44-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7556f3a824b45302e29ec2145b2f8c52ca9df3c6c7f2ac40bc7ce3d39f090f01", size = 13277072, upload-time = "2026-06-04T17:30:31.916Z" }, - { url = "https://files.pythonhosted.org/packages/04/03/542ee91da33ec16fefcb5bf5fee40e29bfb15193adade6e729a2d3089982/zensical-0.0.44-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d27ca2de859241fe13871f252c488b5aabcf757772973ba6e57db6be1cdee55", size = 12977180, upload-time = "2026-06-04T17:30:34.508Z" }, - { url = "https://files.pythonhosted.org/packages/4b/71/4a20eb41b312e458e111119a2902ab402bd60320ea1c029ef1f4839c35ad/zensical-0.0.44-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:062c8a4071f75b25bcbe66c95d8984b967ed43ea9eeb3fd79374b4409618f93d", size = 13122478, upload-time = "2026-06-04T17:30:37.44Z" }, - { url = "https://files.pythonhosted.org/packages/67/90/d01e1fbe39ca687cbd076d1eeee9a2ac70b255d18a0f178ec9c0465ae349/zensical-0.0.44-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:17252630f2e4294ae8852b1616b6d87bdafb4d7608d2eb75f6d5ded043bd05ff", size = 13188163, upload-time = "2026-06-04T17:30:40.218Z" }, - { url = "https://files.pythonhosted.org/packages/08/bf/34a2080dcc131dba174f4247e2309113d9fcdaad0f1bd5bd4e0891d87991/zensical-0.0.44-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:4d0dba5a44634bff9d0661ca212d602c126efdb1d7a122c6a389630d17a5c15c", size = 13330242, upload-time = "2026-06-04T17:30:42.684Z" }, - { url = "https://files.pythonhosted.org/packages/eb/81/d752314525b6309657f5bf52b5f4414884df7b1175dc4ad6aaac5e2f5f1d/zensical-0.0.44-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f7ef005280c62a7cfa258583ff68b443bd5e460da9f996f7c671251403dcdb4a", size = 13261108, upload-time = "2026-06-04T17:30:45.516Z" }, - { url = "https://files.pythonhosted.org/packages/d5/08/cd69f37e43619f5613612d2e6b1eeee2842101c29b2db9fdde501716086d/zensical-0.0.44-cp310-abi3-win32.whl", hash = "sha256:b844e28292e9ea93e5dcca229773c027fd3931419d581e1af4fd5ff310679237", size = 12261668, upload-time = "2026-06-04T17:30:48.217Z" }, - { url = "https://files.pythonhosted.org/packages/d4/4d/261244d82be63383482717651befa9971255a6c1399bae61d6c14a117dd9/zensical-0.0.44-cp310-abi3-win_amd64.whl", hash = "sha256:912219e11af23081a7b6bc13e81131bdeacd6bb3516b9508c6b52d8b23aa8208", size = 12502071, upload-time = "2026-06-04T17:30:51.02Z" }, + { url = "https://files.pythonhosted.org/packages/4c/bd/bbc499ee35ac9ec5459dbfec7bb7231556689e97eaa13a5eddbe1f0443b5/zensical-0.0.46-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d91af81ab058c8693dfd75f2f77b4c73bcba4125681d1d276f38624291820bd2", size = 12796482, upload-time = "2026-06-21T18:52:07.369Z" }, + { url = "https://files.pythonhosted.org/packages/88/1b/7acc273184d59b8e894d15ebe3cf1c5e81b3a822fde1792ea3e33be37a2e/zensical-0.0.46-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:d9221264a9a87409900a47e29985607b0c9245dacb89077e87c8e16e31edc167", size = 12660030, upload-time = "2026-06-21T18:52:10.186Z" }, + { url = "https://files.pythonhosted.org/packages/80/df/bd0a68de98a19fc6050c58be11f36d05ea72a213b6a7ff7395d33c793747/zensical-0.0.46-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec43018d5343ca2e1d71aa352eeddd560fef504effd03025840a5a783abefa4f", size = 13057130, upload-time = "2026-06-21T18:52:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/f4/db/e27635f5787a42245f900e658340698a6654e165d466f9a3b640efced2cd/zensical-0.0.46-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26e98fb8ab7ab50cdd20a73e2c7d4d9aae0b46cf2d8691e6bb22f9c261b8a60a", size = 13022345, upload-time = "2026-06-21T18:52:15.84Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9d/6ce2ba11c97154870b458a8dae4637ade93b7097912f0102f5ea7fe8cf5b/zensical-0.0.46-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46fe578f26963f8ee89567983e62737b6fadc9197d4742e1020b522e092d7baa", size = 13377445, upload-time = "2026-06-21T18:52:18.538Z" }, + { url = "https://files.pythonhosted.org/packages/68/06/9930d43cd9d2f899b648d63491007c1b4f9716cf118b0c98e867b933069c/zensical-0.0.46-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aef03fa186a5589148e10b62610500989c6b075a2c08e1554233adbf91b2a3dc", size = 13086749, upload-time = "2026-06-21T18:52:21.452Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ed/2342cf860fbb02314938b0d1f1b02344935801b04d185ff3151ef1812898/zensical-0.0.46-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:bc7446cdf97a8dea390f20ed2bd6b030cddc1bd36a8ce113ea3efef6fa61c573", size = 13231120, upload-time = "2026-06-21T18:52:24.171Z" }, + { url = "https://files.pythonhosted.org/packages/de/b0/d2ece02f63cd767fcf10fd7608dc8e0a995f87dc5261209b1dbc296fd57b/zensical-0.0.46-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:bbee37801f1ed500f158dc0992c569282950f780ae353c37fe6969f99983d701", size = 13295035, upload-time = "2026-06-21T18:52:26.942Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b2/cb0048a612e63e615399fc507472a557d1c5b7c2f74065c5bf11998fd597/zensical-0.0.46-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:9487c147c9cceb50c04d0ad70b024821a6eab1629dafd70ab6d1e86ec841e623", size = 13437191, upload-time = "2026-06-21T18:52:29.69Z" }, + { url = "https://files.pythonhosted.org/packages/91/16/515f81db8055b109a510063be481e60a657c4fad1a883680b2ee4aa9a424/zensical-0.0.46-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f42a4683c762f026878d19ede4bcf7bfbb84dbecb5ad923949abb77806ed88a5", size = 13369382, upload-time = "2026-06-21T18:52:32.521Z" }, + { url = "https://files.pythonhosted.org/packages/b9/5c/da54ee65b642eb7d88dd4a3db35845d0765915638e05d5d434a10b42f1c3/zensical-0.0.46-cp310-abi3-win32.whl", hash = "sha256:85f018f2a7ee76a83915c87ddb12b58cf343fd6154081d33ac95b6751b011dd7", size = 12354298, upload-time = "2026-06-21T18:52:34.976Z" }, + { url = "https://files.pythonhosted.org/packages/73/26/fc7ef081acbdada8436825221cb728ee84a81d4d78a7bb79aa58bd150d31/zensical-0.0.46-cp310-abi3-win_amd64.whl", hash = "sha256:1543a693a160de60e86ca589592401b584670e7e12c5ae30e3c2ba76786f7ec3", size = 12599687, upload-time = "2026-06-21T18:52:37.913Z" }, ] -[[package]] -name = "zeromq" -version = "4.3.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#40b29e8e88a69802e8afc4f71f5c955bc2d5c74c" } - [[package]] name = "zstandard" version = "0.25.0" @@ -1654,8 +1819,3 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, ] - -[[package]] -name = "zstd" -version = "1.5.6" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#13015596466eb68825f109ad0d5aefa6330cc495" }