mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-08 06:25:42 +08:00
Merge remote-tracking branch 'commaai/openpilot/master' into hkg-can-long-tuning
This commit is contained in:
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: Build docs
|
||||
run: |
|
||||
# TODO: can we install just the "docs" dependency group without the normal deps?
|
||||
pip install mkdocs mkdocs-terminal
|
||||
pip install mkdocs==1.4.3 mkdocs-terminal mkdocs-plugin-commonmark
|
||||
cd docs
|
||||
mkdocs build
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
name: jenkins scan
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
jobs:
|
||||
# TODO: gc old branches in a separate job in this workflow
|
||||
scan-comments:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
steps:
|
||||
- name: Check for trigger phrase
|
||||
id: check_comment
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const triggerPhrase = "trigger-jenkins";
|
||||
const comment = context.payload.comment.body;
|
||||
const commenter = context.payload.comment.user.login;
|
||||
|
||||
const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
username: commenter
|
||||
});
|
||||
|
||||
const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin';
|
||||
|
||||
return (hasWriteAccess && comment.includes(triggerPhrase));
|
||||
result-encoding: json
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.issue.number }}/head
|
||||
|
||||
- name: Push to tmp-jenkins branch
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b tmp-jenkins-${{ github.event.issue.number }}
|
||||
GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }}
|
||||
@@ -74,8 +74,11 @@ jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
arch: ${{ fromJson('["x86_64"]') }} # TODO: Re-add build test for aarch64 once we switched to ubuntu-2404
|
||||
runs-on: ubuntu-latest
|
||||
arch: ${{ fromJson(
|
||||
((github.repository == 'commaai/openpilot') &&
|
||||
((github.event_name != 'pull_request') ||
|
||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && '["x86_64", "aarch64"]' || '["x86_64"]' ) }}
|
||||
runs-on: ${{ (matrix.arch == 'aarch64') && 'namespace-profile-arm64-2x8' || 'ubuntu-latest' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -84,7 +87,7 @@ jobs:
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
|
||||
run: |
|
||||
echo "PUSH_IMAGE=true" >> "$GITHUB_ENV"
|
||||
: # (TODO: Re-add this once we test other archs) echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV"
|
||||
echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV"
|
||||
$DOCKER_LOGIN
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
with:
|
||||
@@ -93,7 +96,7 @@ jobs:
|
||||
timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 15 || 30) }} # allow more time when we missed the scons cache
|
||||
|
||||
build_mac:
|
||||
name: build macos
|
||||
name: build macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -103,7 +106,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: ./tools/mac_setup.sh
|
||||
env:
|
||||
SKIP_PROMPT: 1
|
||||
# package install has DeprecationWarnings
|
||||
PYTHONWARNINGS: default
|
||||
- run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV
|
||||
@@ -118,6 +120,23 @@ jobs:
|
||||
- name: Building openpilot
|
||||
run: . .venv/bin/activate && scons -j$(nproc)
|
||||
|
||||
docker_push_multiarch:
|
||||
name: docker push multiarch tag
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
- name: Setup docker
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
- name: Merge x64 and arm64 tags
|
||||
run: |
|
||||
export PUSH_IMAGE=true
|
||||
scripts/retry.sh selfdrive/test/docker_tag_multiarch.sh base x86_64 aarch64
|
||||
|
||||
static_analysis:
|
||||
name: static analysis
|
||||
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
|
||||
@@ -318,6 +337,7 @@ jobs:
|
||||
})
|
||||
|
||||
create_ui_report:
|
||||
# This job name needs to be the same as UI_JOB_NAME in ui_preview.yaml
|
||||
name: Create UI Report
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -335,55 +355,5 @@ jobs:
|
||||
- name: Upload Test Report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: report-${{ inputs.run_number || '1' }}
|
||||
path: selfdrive/ui/tests/test_ui/report_${{ inputs.run_number || '1' }}
|
||||
- name: Get changes to selfdrive/ui
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v44
|
||||
with:
|
||||
files: |
|
||||
selfdrive/ui/**
|
||||
- name: Checkout ci-artifacts
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
ref: master
|
||||
- name: Push Screenshots
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||
run: |
|
||||
git checkout -b openpilot/pr-${{ github.event.pull_request.number }}
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
sudo mv ${{ github.workspace }}/selfdrive/ui/tests/test_ui/report_1/screenshots/* .
|
||||
git add .
|
||||
git commit -m "screenshots for PR #${{ github.event.pull_request.number }}"
|
||||
git push origin openpilot/pr-${{ github.event.pull_request.number }} --force
|
||||
- name: Comment Screenshots on PR
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
<!-- _(run_id_screenshots **${{ github.run_id }}**)_ -->
|
||||
## UI Screenshots
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/homescreen.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad_map.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad_sidebar.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/settings_network.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/settings_device.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
comment_tag: run_id_screenshots
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: report-${{ github.event.number }}
|
||||
path: selfdrive/ui/tests/test_ui/report_1/screenshots
|
||||
|
||||
@@ -73,12 +73,6 @@ jobs:
|
||||
scons-${{ runner.arch }}-ubuntu2004
|
||||
- name: Building openpilot
|
||||
run: uv run scons -u -j$(nproc)
|
||||
- name: Saving scons cache
|
||||
uses: actions/cache/save@v4
|
||||
if: github.ref == 'refs/heads/master'
|
||||
with:
|
||||
path: /tmp/scons_cache
|
||||
key: scons-${{ runner.arch }}-ubuntu2004-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
||||
|
||||
devcontainer:
|
||||
name: devcontainer
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
name: "ui preview"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [assigned, opened, synchronize, reopened, edited]
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'selfdrive/ui/**'
|
||||
|
||||
env:
|
||||
UI_JOB_NAME: "Create UI Report"
|
||||
|
||||
jobs:
|
||||
preview:
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
name: preview
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Waiting for ui test to start
|
||||
run: sleep 30
|
||||
|
||||
- name: Wait for ui report
|
||||
uses: lewagon/wait-on-check-action@v1.3.4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
check-name: ${{ env.UI_JOB_NAME }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
allowed-conclusions: success
|
||||
wait-interval: 20
|
||||
|
||||
- name: Get workflow run ID
|
||||
id: get_run_id
|
||||
run: |
|
||||
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ github.event.pull_request.head.sha }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout ci-artifacts
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
ref: master
|
||||
|
||||
- name: Download artifact
|
||||
id: download-artifact
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
||||
search_artifacts: true
|
||||
name: report-${{ github.event.number }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
|
||||
- name: Push Screenshots
|
||||
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||
run: |
|
||||
git checkout -b openpilot/pr-${{ github.event.number }}
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
git add ${{ github.workspace }}/ci-artifacts/*
|
||||
git commit -m "screenshots for PR #${{ github.event.number }}"
|
||||
git push origin openpilot/pr-${{ github.event.number }} --force
|
||||
|
||||
- name: Comment Screenshots on PR
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
<!-- _(run_id_screenshots **${{ github.run_id }}**)_ -->
|
||||
## UI Screenshots
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/homescreen.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_map.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_sidebar.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/settings_network.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/settings_device.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
comment_tag: run_id_screenshots
|
||||
pr_number: ${{ github.event.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -33,7 +33,7 @@ repos:
|
||||
- -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn
|
||||
- --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.5.2
|
||||
rev: v0.5.4
|
||||
hooks:
|
||||
- id: ruff
|
||||
exclude: '^(third_party/)|(msgq/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)'
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
[](https://comma.ai/shop/comma-3x)
|
||||
<div align="center" style="text-align: center;">
|
||||
|
||||
What is openpilot?
|
||||
------
|
||||
<h1>openpilot</h1>
|
||||
|
||||
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW), and Lane Departure Warning (LDW) for a growing variety of [supported car makes, models, and model years](docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md).
|
||||
<p>
|
||||
<b>openpilot is an operating system for robotics.</b>
|
||||
<br>
|
||||
Currently, it upgrades the driver assistance system in 275+ supported cars.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="https://docs.comma.ai">Read the docs</a>
|
||||
<span> · </span>
|
||||
<a href="https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md">Contribute</a>
|
||||
<span> · </span>
|
||||
<a href="https://discord.comma.ai">Community</a>
|
||||
<span> · </span>
|
||||
<a href="https://comma.ai/shop">Try it on a comma 3X</a>
|
||||
</h3>
|
||||
|
||||
Quick start: `curl -fsSL openpilot.comma.ai | bash`
|
||||
|
||||

|
||||
[](https://codecov.io/gh/commaai/openpilot)
|
||||
[](LICENSE)
|
||||
[](https://x.com/comma_ai)
|
||||
[](https://discord.comma.ai)
|
||||
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -19,7 +42,7 @@ To start using openpilot in a car
|
||||
To use openpilot in a car, you need four things:
|
||||
1. **Supported Device:** a comma 3/3X, available at [comma.ai/shop](https://comma.ai/shop/comma-3x).
|
||||
2. **Software:** The setup procedure for the comma 3/3X allows users to enter a URL for custom software. Use the URL `openpilot.comma.ai` to install the release version.
|
||||
3. **Supported Car:** Ensure that you have one of [the 250+ supported cars](docs/CARS.md).
|
||||
3. **Supported Car:** Ensure that you have one of [the 275+ supported cars](docs/CARS.md).
|
||||
4. **Car Harness:** You will also need a [car harness](https://comma.ai/shop/car-harness) to connect your comma 3/3X to your car.
|
||||
|
||||
We have detailed instructions for [how to install the harness and device in a car](https://comma.ai/setup). Note that it's possible to run openpilot on [other hardware](https://blog.comma.ai/self-driving-car-for-free/), although it's not plug-and-play.
|
||||
@@ -49,18 +72,6 @@ Safety and Testing
|
||||
* panda has additional hardware-in-the-loop [tests](https://github.com/commaai/panda/blob/master/Jenkinsfile).
|
||||
* We run the latest openpilot in a testing closet containing 10 comma devices continuously replaying routes.
|
||||
|
||||
User Data and comma Account
|
||||
------
|
||||
|
||||
By default, openpilot uploads the driving data to our servers. You can also access your data through [comma connect](https://connect.comma.ai/). We use your data to train better models and improve openpilot for everyone.
|
||||
|
||||
openpilot is open source software: the user is free to disable data collection if they wish to do so.
|
||||
|
||||
openpilot logs the road-facing cameras, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
|
||||
The driver-facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded.
|
||||
|
||||
By using openpilot, you agree to [our Privacy Policy](https://comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma for the use of this data.
|
||||
|
||||
Licensing
|
||||
------
|
||||
|
||||
@@ -72,9 +83,14 @@ Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and i
|
||||
YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS.
|
||||
NO WARRANTY EXPRESSED OR IMPLIED.**
|
||||
|
||||
---
|
||||
User Data and comma Account
|
||||
------
|
||||
|
||||
<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/1061157-bc7e9bf3b246ece7322e6ffe653f6af8-medium_jpg.jpg?buster=1458363130" width="75"></img> <img src="https://cdn-images-1.medium.com/max/1600/1*C87EjxGeMPrkTuVRVWVg4w.png" width="225"></img>
|
||||
By default, openpilot uploads the driving data to our servers. You can also access your data through [comma connect](https://connect.comma.ai/). We use your data to train better models and improve openpilot for everyone.
|
||||
|
||||

|
||||
[](https://codecov.io/gh/commaai/openpilot)
|
||||
openpilot is open source software: the user is free to disable data collection if they wish to do so.
|
||||
|
||||
openpilot logs the road-facing cameras, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
|
||||
The driver-facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded.
|
||||
|
||||
By using openpilot, you agree to [our Privacy Policy](https://comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma for the use of this data.
|
||||
|
||||
+1
-4
@@ -102,7 +102,6 @@ if arch == "larch64":
|
||||
|
||||
libpath = [
|
||||
"/usr/local/lib",
|
||||
"/usr/lib",
|
||||
"/system/vendor/lib64",
|
||||
f"#third_party/acados/{arch}/lib",
|
||||
]
|
||||
@@ -170,7 +169,6 @@ if arch != "Darwin":
|
||||
ldflags += ["-Wl,--as-needed", "-Wl,--no-undefined"]
|
||||
|
||||
# Enable swaglog include in submodules
|
||||
cflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
|
||||
cxxflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
|
||||
|
||||
ccflags_option = GetOption('ccflags')
|
||||
@@ -206,7 +204,6 @@ env = Environment(
|
||||
"#third_party/json11",
|
||||
"#third_party/linux/include",
|
||||
"#third_party/snpe/include",
|
||||
"#third_party/qrcode",
|
||||
"#third_party",
|
||||
"#cereal",
|
||||
"#msgq",
|
||||
@@ -315,7 +312,7 @@ try:
|
||||
except SCons.Errors.UserError:
|
||||
qt_env.Tool('qt')
|
||||
|
||||
qt_env['CPPPATH'] += qt_dirs# + ["#selfdrive/ui/qt/"]
|
||||
qt_env['CPPPATH'] += qt_dirs + ["#third_party/qrcode"]
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
|
||||
@@ -5,6 +5,9 @@ site_url: https://docs.comma.ai
|
||||
|
||||
strict: true
|
||||
|
||||
plugins:
|
||||
- commonmark
|
||||
|
||||
theme:
|
||||
name: terminal
|
||||
features:
|
||||
|
||||
+1
-1
Submodule opendbc updated: 5ba787024f...cff2af8ff8
+1
-1
Submodule panda updated: b4e3d5cdd2...f6375848ca
+12
-12
@@ -52,22 +52,25 @@ dependencies = [
|
||||
"websocket_client",
|
||||
|
||||
# acados deps
|
||||
"casadi",
|
||||
"casadi @ https://github.com/commaai/casadi/releases/download/nightly-release-3.6.6/casadi-3.6.6-cp312-none-manylinux2014_aarch64.whl ; (python_version == '3.12' and platform_machine == 'aarch64')", # TODO: Go back to pypi casadi when they fix aarch64 for python312
|
||||
"casadi; platform_machine != 'aarch64' or python_version != '3.12'",
|
||||
"future-fstrings",
|
||||
|
||||
# these should be removed
|
||||
"psutil",
|
||||
"pycryptodome", # used in updated/casync, panda, body, and a test
|
||||
|
||||
#logreader
|
||||
# logreader
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
docs = [
|
||||
"Jinja2",
|
||||
"mkdocs",
|
||||
"natsort",
|
||||
"mkdocs==1.4.3", # needed for mkdocs-plugin-commonmark
|
||||
"mkdocs-terminal",
|
||||
"mkdocs-plugin-commonmark",
|
||||
]
|
||||
|
||||
testing = [
|
||||
@@ -93,7 +96,6 @@ dev = [
|
||||
"av",
|
||||
"azure-identity",
|
||||
"azure-storage-blob",
|
||||
"breathe",
|
||||
"control",
|
||||
"dictdiffer",
|
||||
"flaky",
|
||||
@@ -101,14 +103,11 @@ dev = [
|
||||
"lru-dict",
|
||||
"matplotlib",
|
||||
"metadrive-simulator@git+https://github.com/commaai/metadrive@opencv_headless ; platform_machine != 'aarch64'",
|
||||
"mpld3",
|
||||
"myst-parser",
|
||||
"natsort",
|
||||
"opencv-python-headless",
|
||||
"parameterized >=0.8, <0.9",
|
||||
#pprofile = "*"
|
||||
#"pprofile",
|
||||
"pyautogui",
|
||||
"pyopencl; platform_machine != 'aarch64'", # broken on arm64
|
||||
"pytools < 2024.1.11; platform_machine != 'aarch64'", # pyopencl use a broken version
|
||||
"pywinctl",
|
||||
"pyprof2calltree",
|
||||
"rerun-sdk",
|
||||
@@ -119,7 +118,6 @@ dev = [
|
||||
|
||||
# this is only pinned since 5.15.11 is broken
|
||||
"pyqt5 ==5.15.2; platform_machine == 'x86_64'", # no aarch64 wheels for macOS/linux
|
||||
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
@@ -226,7 +224,7 @@ lint.ignore = [
|
||||
"UP038", # (x, y) -> x|y for isinstance
|
||||
]
|
||||
line-length = 160
|
||||
target-version="py311"
|
||||
target-version ="py311"
|
||||
exclude = [
|
||||
"body",
|
||||
"cereal",
|
||||
@@ -238,7 +236,8 @@ exclude = [
|
||||
"teleoprtc_repo",
|
||||
"third_party",
|
||||
]
|
||||
lint.flake8-implicit-str-concat.allow-multiline=false
|
||||
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"
|
||||
@@ -250,5 +249,6 @@ lint.flake8-implicit-str-concat.allow-multiline=false
|
||||
|
||||
[tool.coverage.run]
|
||||
concurrency = ["multiprocessing", "thread"]
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
|
||||
@@ -26,6 +26,7 @@ FW_VERSIONS = {
|
||||
],
|
||||
(Ecu.fwdRadar, 0x753, None): [
|
||||
b'04672758AA',
|
||||
b'04672758AB',
|
||||
b'68226356AF',
|
||||
b'68226356AH',
|
||||
b'68226356AI',
|
||||
@@ -47,6 +48,7 @@ FW_VERSIONS = {
|
||||
b'68352654AE ',
|
||||
b'68366851AH ',
|
||||
b'68366853AE ',
|
||||
b'68366853AG ',
|
||||
b'68372861AF ',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
@@ -60,6 +62,7 @@ FW_VERSIONS = {
|
||||
b'68277374AD',
|
||||
b'68277374AN',
|
||||
b'68367471AC',
|
||||
b'68367471AD',
|
||||
b'68380571AB',
|
||||
],
|
||||
},
|
||||
@@ -387,6 +390,7 @@ FW_VERSIONS = {
|
||||
b'68294051AI',
|
||||
b'68294052AG',
|
||||
b'68294052AH',
|
||||
b'68294059AI',
|
||||
b'68294063AG',
|
||||
b'68294063AH',
|
||||
b'68294063AI',
|
||||
@@ -397,6 +401,7 @@ FW_VERSIONS = {
|
||||
b'68434858AC',
|
||||
b'68434859AC',
|
||||
b'68434860AC',
|
||||
b'68453471AD',
|
||||
b'68453483AC',
|
||||
b'68453483AD',
|
||||
b'68453487AD',
|
||||
@@ -421,11 +426,13 @@ FW_VERSIONS = {
|
||||
b'68527346AE',
|
||||
b'68527361AD',
|
||||
b'68527375AD',
|
||||
b'68527381AD',
|
||||
b'68527381AE',
|
||||
b'68527382AE',
|
||||
b'68527383AD',
|
||||
b'68527383AE',
|
||||
b'68527387AE',
|
||||
b'68527397AD',
|
||||
b'68527403AC',
|
||||
b'68527403AD',
|
||||
b'68546047AF',
|
||||
@@ -516,6 +523,7 @@ FW_VERSIONS = {
|
||||
b'05036066AE ',
|
||||
b'05036193AA ',
|
||||
b'05149368AA ',
|
||||
b'05149374AA ',
|
||||
b'05149591AD ',
|
||||
b'05149591AE ',
|
||||
b'05149592AE ',
|
||||
@@ -546,6 +554,7 @@ FW_VERSIONS = {
|
||||
b'68455145AC ',
|
||||
b'68455145AE ',
|
||||
b'68455146AC ',
|
||||
b'68460927AA ',
|
||||
b'68467915AC ',
|
||||
b'68467916AC ',
|
||||
b'68467936AC ',
|
||||
@@ -564,6 +573,7 @@ FW_VERSIONS = {
|
||||
b'68539650AF',
|
||||
b'68539651AD',
|
||||
b'68586101AA ',
|
||||
b'68586102AA ',
|
||||
b'68586105AB ',
|
||||
b'68629919AC ',
|
||||
b'68629922AC ',
|
||||
@@ -602,6 +612,8 @@ FW_VERSIONS = {
|
||||
b'68520867AE',
|
||||
b'68520867AF',
|
||||
b'68520870AC',
|
||||
b'68520871AC',
|
||||
b'68528325AE',
|
||||
b'68540431AB',
|
||||
b'68540433AB',
|
||||
b'68551676AA',
|
||||
|
||||
@@ -292,6 +292,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLAC0 4TSHC102',
|
||||
b'\xf1\x00TM MDPS C 1.00 1.02 56310-CLEC0 4TSHC102',
|
||||
b'\xf1\x00TM MDPS C 1.00 1.02 56310-GA000 4TSHA100',
|
||||
b'\xf1\x00TM MDPS C 1.00 1.02 56310GA000\x00 4TSHA100',
|
||||
b'\xf1\x00TM MDPS R 1.00 1.05 57700-CL000 4TSHP105',
|
||||
b'\xf1\x00TM MDPS R 1.00 1.06 57700-CL000 4TSHP106',
|
||||
],
|
||||
@@ -408,6 +409,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00ON ESC \x0b 100\x18\x12\x18 58910-S9360',
|
||||
b'\xf1\x00ON ESC \x0b 101\x19\t\x05 58910-S9320',
|
||||
b'\xf1\x00ON ESC \x0b 101\x19\t\x08 58910-S9360',
|
||||
b'\xf1\x00ON ESC \x0b 103$\x04\x08 58910-S9360',
|
||||
],
|
||||
(Ecu.eps, 0x7d4, None): [
|
||||
b'\xf1\x00LX2 MDPS C 1,00 1,03 56310-S8020 4LXDC103',
|
||||
@@ -481,11 +483,13 @@ FW_VERSIONS = {
|
||||
},
|
||||
CAR.GENESIS_G80: {
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00DH__ SCC F-CU- 1.00 1.01 96400-B1110 ',
|
||||
b'\xf1\x00DH__ SCC F-CUP 1.00 1.01 96400-B1120 ',
|
||||
b'\xf1\x00DH__ SCC F-CUP 1.00 1.02 96400-B1120 ',
|
||||
b'\xf1\x00DH__ SCC FHCUP 1.00 1.01 96400-B1110 ',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00DH LKAS AT EUR LHD 1.01 1.01 95895-B1500 161014',
|
||||
b'\xf1\x00DH LKAS AT KOR LHD 1.01 1.01 95895-B1500 161014',
|
||||
b'\xf1\x00DH LKAS AT KOR LHD 1.01 1.02 95895-B1500 170810',
|
||||
b'\xf1\x00DH LKAS AT USA LHD 1.01 1.01 95895-B1500 161014',
|
||||
@@ -761,9 +765,11 @@ FW_VERSIONS = {
|
||||
],
|
||||
(Ecu.abs, 0x7d1, None): [
|
||||
b'\xf1\x00JF ESC \x0f 16 \x16\x06\x17 58920-D5080',
|
||||
b'\xf1\x00JF ESC \t 17 \x16\x06# 58920-D4180',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00JFWGN LDWS AT USA LHD 1.00 1.02 95895-D4100 G21',
|
||||
b'\xf1\x00JFWGN LKAS AT EUR LHD 1.00 1.01 95895-D4100 G20',
|
||||
],
|
||||
},
|
||||
CAR.KIA_OPTIMA_G4_FL: {
|
||||
|
||||
@@ -1152,6 +1152,7 @@ FW_VERSIONS = {
|
||||
},
|
||||
CAR.TOYOTA_RAV4_TSS2_2023: {
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'\x01F15260R440\x00\x00\x00\x00\x00\x00',
|
||||
b'\x01F15260R450\x00\x00\x00\x00\x00\x00',
|
||||
b'\x01F15260R50000\x00\x00\x00\x00',
|
||||
b'\x01F15260R51000\x00\x00\x00\x00',
|
||||
@@ -1173,6 +1174,7 @@ FW_VERSIONS = {
|
||||
b'\x01896634AE1001\x00\x00\x00\x00',
|
||||
b'\x01896634AF0000\x00\x00\x00\x00',
|
||||
b'\x01896634AJ2000\x00\x00\x00\x00',
|
||||
b'\x01896634AJ3000\x00\x00\x00\x00',
|
||||
b'\x01896634AL5000\x00\x00\x00\x00',
|
||||
b'\x01896634AL6000\x00\x00\x00\x00',
|
||||
b'\x01896634AL8000\x00\x00\x00\x00',
|
||||
|
||||
@@ -832,7 +832,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
|
||||
},
|
||||
|
||||
EventName.espActive: {
|
||||
ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("Electronic Stability Control Active"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Active"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Active"),
|
||||
},
|
||||
|
||||
|
||||
@@ -22,22 +22,26 @@ def long_control_state_trans(CP, active, long_control_state, v_ego,
|
||||
long_control_state = LongCtrlState.off
|
||||
|
||||
else:
|
||||
if long_control_state in (LongCtrlState.off, LongCtrlState.pid):
|
||||
long_control_state = LongCtrlState.pid
|
||||
if stopping_condition:
|
||||
if long_control_state == LongCtrlState.off:
|
||||
if not starting_condition:
|
||||
long_control_state = LongCtrlState.stopping
|
||||
else:
|
||||
if starting_condition and CP.startingState:
|
||||
long_control_state = LongCtrlState.starting
|
||||
else:
|
||||
long_control_state = LongCtrlState.pid
|
||||
|
||||
elif long_control_state == LongCtrlState.stopping:
|
||||
if starting_condition and CP.startingState:
|
||||
long_control_state = LongCtrlState.starting
|
||||
elif starting_condition:
|
||||
long_control_state = LongCtrlState.pid
|
||||
|
||||
elif long_control_state == LongCtrlState.starting:
|
||||
elif long_control_state in [LongCtrlState.starting, LongCtrlState.pid]:
|
||||
if stopping_condition:
|
||||
long_control_state = LongCtrlState.stopping
|
||||
elif started_condition:
|
||||
long_control_state = LongCtrlState.pid
|
||||
|
||||
return long_control_state
|
||||
|
||||
class LongControl:
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
from cereal import car
|
||||
from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState, long_control_state_trans
|
||||
|
||||
|
||||
|
||||
|
||||
class TestLongControlStateTransition:
|
||||
|
||||
def test_stay_stopped(self):
|
||||
CP = car.CarParams.new_message()
|
||||
active = True
|
||||
current_state = LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=True, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=True, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=True)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.pid
|
||||
active = False
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.off
|
||||
|
||||
def test_engage():
|
||||
CP = car.CarParams.new_message()
|
||||
active = True
|
||||
current_state = LongCtrlState.off
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=True, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=True, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=True)
|
||||
assert next_state == LongCtrlState.stopping
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.pid
|
||||
|
||||
def test_starting():
|
||||
CP = car.CarParams.new_message(startingState=True, vEgoStarting=0.5)
|
||||
active = True
|
||||
current_state = LongCtrlState.starting
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.starting
|
||||
next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0,
|
||||
should_stop=False, brake_pressed=False, cruise_standstill=False)
|
||||
assert next_state == LongCtrlState.pid
|
||||
@@ -3,8 +3,7 @@
|
||||
import argparse
|
||||
|
||||
from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, replay_process
|
||||
from openpilot.tools.lib.helpers import save_log
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from openpilot.tools.lib.logreader import LogReader, save_log
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Run process on route and create new logs",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
import numpy as np
|
||||
cimport numpy as cnp
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
from libcpp.string cimport string
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
import os
|
||||
from libcpp cimport bool
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# distutils: language = c++
|
||||
# cython: c_string_encoding=ascii
|
||||
# cython: c_string_encoding=ascii, language_level=3
|
||||
|
||||
from libcpp cimport bool
|
||||
from libcpp.string cimport string
|
||||
|
||||
@@ -10,8 +10,7 @@ from openpilot.tools.lib.openpilotci import BASE_URL, get_url
|
||||
from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff
|
||||
from openpilot.selfdrive.test.process_replay.process_replay import get_process_config, replay_process
|
||||
from openpilot.tools.lib.framereader import FrameReader
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from openpilot.tools.lib.helpers import save_log
|
||||
from openpilot.tools.lib.logreader import LogReader, save_log
|
||||
|
||||
TEST_ROUTE = "2f4452b03ccb98f0|2022-12-03--13-45-30"
|
||||
SEGMENT = 6
|
||||
|
||||
@@ -14,8 +14,7 @@ from openpilot.selfdrive.test.process_replay.vision_meta import DRIVER_CAMERA_FR
|
||||
from openpilot.selfdrive.test.update_ci_routes import upload_route
|
||||
from openpilot.tools.lib.route import Route
|
||||
from openpilot.tools.lib.framereader import FrameReader, BaseFrameReader, FrameType
|
||||
from openpilot.tools.lib.logreader import LogReader, LogIterable
|
||||
from openpilot.tools.lib.helpers import save_log
|
||||
from openpilot.tools.lib.logreader import LogReader, LogIterable, save_log
|
||||
|
||||
|
||||
class DummyFrameReader(BaseFrameReader):
|
||||
|
||||
@@ -14,8 +14,7 @@ from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, f
|
||||
from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, replay_process, \
|
||||
check_openpilot_enabled, check_most_messages_valid
|
||||
from openpilot.tools.lib.filereader import FileReader
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from openpilot.tools.lib.helpers import save_log
|
||||
from openpilot.tools.lib.logreader import LogReader, save_log
|
||||
|
||||
source_segments = [
|
||||
("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.COMMA_BODY
|
||||
|
||||
@@ -56,7 +56,7 @@ PROCS = {
|
||||
"system.logmessaged": 0.2,
|
||||
"system.tombstoned": 0,
|
||||
"logcatd": 0,
|
||||
"system.micd": 6.0,
|
||||
"system.micd": 5.0,
|
||||
"system.timed": 0,
|
||||
"selfdrive.pandad.pandad": 0,
|
||||
"system.statsd": 0.4,
|
||||
|
||||
@@ -109,7 +109,7 @@ if GetOption('extras') and arch != "Darwin":
|
||||
obj = senv.Object(f"installer/installers/installer_{name}.o", ["installer/installer.cc"], CPPDEFINES=d)
|
||||
f = senv.Program(f"installer/installers/installer_{name}", [obj, cont], LIBS=qt_libs)
|
||||
# keep installers small
|
||||
assert f[0].get_size() < 350*1e3
|
||||
assert f[0].get_size() < 370*1e3
|
||||
|
||||
# build watch3
|
||||
if arch in ['x86_64', 'aarch64', 'Darwin'] or GetOption('extras'):
|
||||
|
||||
@@ -18,7 +18,9 @@ void setMainWindow(QWidget *w) {
|
||||
wl_surface *s = reinterpret_cast<wl_surface*>(native->nativeResourceForWindow("surface", w->windowHandle()));
|
||||
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
|
||||
wl_surface_commit(s);
|
||||
w->showFullScreen();
|
||||
|
||||
w->setWindowState(Qt::WindowFullScreen);
|
||||
w->setVisible(true);
|
||||
|
||||
// ensure we have a valid eglDisplay, otherwise the ui will silently fail
|
||||
void *egl = native->nativeResourceForWindow("egldisplay", w->windowHandle());
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Prevent large data uploads when on a metered connection</source>
|
||||
<translation>Evitar grandes descargas de datos cuando tiene una conexión limitada</translation>
|
||||
<translation>Evitar grandes descargas de datos cuando tenga una conexión limitada</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Hidden Network</source>
|
||||
@@ -72,7 +72,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>CONNECT</source>
|
||||
<translation>CONNECTAR</translation>
|
||||
<translation>CONECTAR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter SSID</source>
|
||||
@@ -117,7 +117,7 @@
|
||||
<name>DeclinePage</name>
|
||||
<message>
|
||||
<source>You must accept the Terms and Conditions in order to use openpilot.</source>
|
||||
<translation>Debe aceptar los terminos y condiciones para poder utilizar openpilot.</translation>
|
||||
<translation>Debe aceptar los términos y condiciones para poder utilizar openpilot.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
@@ -164,11 +164,11 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Preview the driver facing camera to ensure that driver monitoring has good visibility. (vehicle must be off)</source>
|
||||
<translation>Previsualizar la cámara del conductor para garantizar que la monitorización del sistema tenga buena visibilidad (El vehículo tiene que estar apagado)</translation>
|
||||
<translation>Previsualizar la cámara del conductor para garantizar que la monitorización del sistema tenga buena visibilidad (el vehículo tiene que estar apagado)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset Calibration</source>
|
||||
<translation>Reiniciar Calibración</translation>
|
||||
<translation>Formatear Calibración</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>RESET</source>
|
||||
@@ -176,11 +176,11 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Are you sure you want to reset calibration?</source>
|
||||
<translation>¿Seguro qué quiere reiniciar la calibración?</translation>
|
||||
<translation>¿Seguro que quiere formatear la calibración?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset</source>
|
||||
<translation>Reiniciar</translation>
|
||||
<translation>Formatear</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Review Training Guide</source>
|
||||
@@ -196,7 +196,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Are you sure you want to review the training guide?</source>
|
||||
<translation>¿Seguro qué quiere revisar la guía de entrenamiento?</translation>
|
||||
<translation>¿Seguro que quiere revisar la guía de entrenamiento?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Review</source>
|
||||
@@ -232,11 +232,11 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot requires the device to be mounted within 4° left or right and within 5° up or 9° down. openpilot is continuously calibrating, resetting is rarely required.</source>
|
||||
<translation>openpilot requiere que el dispositivo sea montado entre 4° izquierda o derecha y entre 5° arriba o 9° abajo. openpilot está constantemente en calibración, reiniciar es rara vez necesario.</translation>
|
||||
<translation>openpilot requiere que el dispositivo sea montado entre 4° grados a la izquierda o derecha y entre 5° grados hacia arriba o 9° grados hacia abajo. openpilot está constantemente en calibración, formatear rara vez es necesario.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source> Your device is pointed %1° %2 and %3° %4.</source>
|
||||
<translation> Su dispositivo está apuntando %1° %2 e %3° %4.</translation>
|
||||
<translation> Su dispositivo está apuntando %1° %2 y %3° %4.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>down</source>
|
||||
@@ -286,7 +286,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>CHILL MODE ON</source>
|
||||
<translation>MODO TRANQUILO</translation>
|
||||
<translation>MODO CHILL</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -298,7 +298,7 @@
|
||||
<message numerus="yes">
|
||||
<source>Need at least %n character(s)!</source>
|
||||
<translation>
|
||||
<numerusform>¡Necesita mínimo %n caractere!</numerusform>
|
||||
<numerusform>¡Necesita mínimo %n caracter!</numerusform>
|
||||
<numerusform>¡Necesita mínimo %n caracteres!</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
@@ -314,7 +314,7 @@
|
||||
<name>MultiOptionDialog</name>
|
||||
<message>
|
||||
<source>Select</source>
|
||||
<translation>Seleccione</translation>
|
||||
<translation>Seleccionar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
@@ -337,22 +337,22 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Wrong password</source>
|
||||
<translation>Contraseña equivocada</translation>
|
||||
<translation>Contraseña incorrecta</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OffroadAlert</name>
|
||||
<message>
|
||||
<source>Device temperature too high. System cooling down before starting. Current internal component temperature: %1</source>
|
||||
<translation>Temperatura de dispositivo muy alta. Systema enfriando antes de iniciar. Temperatura actual del componente interno: %1</translation>
|
||||
<translation>La temperatura del dispositivo es muy alta. El sistema se está enfriando antes de iniciar. Temperatura actual del componente interno: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Immediately connect to the internet to check for updates. If you do not connect to the internet, openpilot won't engage in %1</source>
|
||||
<translation>Inmediatamente conectar al internet para buscar actualizaciones. Si no se conecta al internet, openpilot no iniciara en %1</translation>
|
||||
<translation>Conéctese inmediatamente al internet para buscar actualizaciones. Si no se conecta al internet, openpilot no iniciará en %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to internet to check for updates. openpilot won't automatically start until it connects to internet to check for updates.</source>
|
||||
<translation>Conectar al internet para buscar actualizaciones. openpilot no iniciara automáticamente hasta conectarse al internet para buscar actualizaciones.</translation>
|
||||
<translation>Conectese al internet para buscar actualizaciones. openpilot no iniciará automáticamente hasta conectarse al internet para buscar actualizaciones.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to download updates
|
||||
@@ -362,7 +362,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Taking camera snapshots. System won't start until finished.</source>
|
||||
<translation>Tomando instantáneas de la cámara. El sistema no se iniciará hasta que finalice.</translation>
|
||||
<translation>Tomando capturas de las cámaras. El sistema no se iniciará hasta que finalice.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>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.</source>
|
||||
@@ -370,7 +370,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Device failed to register. It will not connect to or upload to comma.ai servers, and receives no support from comma.ai. If this is an official device, visit https://comma.ai/support.</source>
|
||||
<translation>El dispositivo no pudo registrarse. No se conectará ni cargará en los servidores de comma.ai y no recibe soporte de comma.ai. Si este es un dispositivo oficial, visite https://comma.ai/support.</translation>
|
||||
<translation>El dispositivo no pudo registrarse. No se conectará ni subirá datos a los servidores de comma.ai y no recibe soporte de comma.ai. Si este es un dispositivo oficial, visite https://comma.ai/support.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NVMe drive not mounted.</source>
|
||||
@@ -378,15 +378,15 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Unsupported NVMe drive detected. Device may draw significantly more power and overheat due to the unsupported NVMe.</source>
|
||||
<translation>Se detectó una unidad NVMe no compatible. El dispositivo puede consumir mucha más energía y sobrecalentarse debido a que NVMe no es compatible.</translation>
|
||||
<translation>Se detectó una unidad NVMe incompatible. El dispositivo puede consumir mucha más energía y sobrecalentarse debido a esto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai.</source>
|
||||
<translation>openpilot no pudo identificar su automóvil. Su automóvil no es compatible o no se reconocen sus ECU. Envíe una solicitud de extracción para agregar las versiones de firmware al vehículo adecuado. ¿Necesitas ayuda? Únase a discord.comma.ai.</translation>
|
||||
<translation>openpilot no pudo identificar su automóvil. Su automóvil no es compatible o no se reconocen sus ECU. Por favor haga un pull request para agregar las versiones de firmware del vehículo adecuado. ¿Necesita ayuda? Únase a discord.comma.ai.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot was unable to identify your car. Check integrity of cables and ensure all connections are secure, particularly that the comma power is fully inserted in the OBD-II port of the vehicle. Need help? Join discord.comma.ai.</source>
|
||||
<translation>openpilot no pudo identificar su automóvil. Verifique la integridad de los cables y asegúrese de que todas las conexiones estén seguras, en particular que comma power esté completamente insertada en el puerto OBD-II del vehículo. ¿Necesitas ayuda? Únase a discord.comma.ai.</translation>
|
||||
<translation>openpilot no pudo identificar su automóvil. Verifique la integridad de los cables y asegúrese de que todas las conexiones estén seguras, en particular que el comma power esté completamente insertado en el puerto OBD-II del vehículo. ¿Necesita ayuda? Únase discord.comma.ai.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot detected a change in the device's mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.</source>
|
||||
@@ -439,15 +439,15 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Go to https://connect.comma.ai on your phone</source>
|
||||
<translation>Ve a https://connect.comma.ai en su telefono</translation>
|
||||
<translation>Vaya a https://connect.comma.ai en su teléfono</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Click "add new device" and scan the QR code on the right</source>
|
||||
<translation>Clic en "agregar nuevo dispositivo" y escanee el código QR a la derecha</translation>
|
||||
<translation>Seleccione "agregar nuevo dispositivo" y escanee el código QR a la derecha</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Bookmark connect.comma.ai to your home screen to use it like an app</source>
|
||||
<translation>Marcar connect.comma.ai como su pantalla de inicio para usarlo como una aplicación</translation>
|
||||
<translation>Añada connect.comma.ai a su pantalla de inicio para usarlo como una aplicación</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -469,7 +469,7 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>Become a comma prime member at connect.comma.ai</source>
|
||||
<translation>Hazte miembro prime de comma en connect.comma.ai</translation>
|
||||
<translation>Hazte miembro de comma prime en connect.comma.ai</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>PRIME FEATURES:</source>
|
||||
@@ -485,11 +485,11 @@
|
||||
</message>
|
||||
<message>
|
||||
<source>1 year of drive storage</source>
|
||||
<translation>1 año de almacenamiento en disco</translation>
|
||||
<translation>1 año de almacenamiento</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Remote snapshots</source>
|
||||
<translation>Istantánea remota</translation>
|
||||
<translation>Capturas remotas</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -547,25 +547,25 @@
|
||||
<name>Reset</name>
|
||||
<message>
|
||||
<source>Reset failed. Reboot to try again.</source>
|
||||
<translation>Reset fallido. Reinicie de nuevo.</translation>
|
||||
<translation>Formateo fallido. Reinicie para reintentar.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Resetting device...
|
||||
This may take up to a minute.</source>
|
||||
<translation>Reiniciando dispositivo...
|
||||
Esto puede tardar hasta un minuto.</translation>
|
||||
<translation>formateando dispositivo...
|
||||
Esto puede tardar un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Are you sure you want to reset your device?</source>
|
||||
<translation>¿Seguro que quiere reiniciar su dispositivo?</translation>
|
||||
<translation>¿Seguro que quiere formatear su dispositivo?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>System Reset</source>
|
||||
<translation>Reiniciar Sistema</translation>
|
||||
<translation>Formatear Sistema</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot.</source>
|
||||
<translation>Reinicio del sistema activado. Presione confirmar para borrar todo el contenido y la configuración. Presione cancelar para reanudar el inicio.</translation>
|
||||
<translation>Formateo del sistema activado. Presione confirmar para borrar todo el contenido y la configuración. Presione cancelar para reanudar el inicio.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cancel</source>
|
||||
@@ -581,7 +581,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device.</source>
|
||||
<translation>No es posible montar una partición de datos. Partición corrompida. Confirme para borrar y reiniciar su dispositivo.</translation>
|
||||
<translation>No es posible montar una partición de datos. La partición podría estar corrompida. Confirme para borrar y formatear su dispositivo.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -615,19 +615,19 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Ensure the entered URL is valid, and the device’s internet connection is good.</source>
|
||||
<translation>Asegurese de que la URL insertada es válida, y que el dispositivo tiene buena conexión.</translation>
|
||||
<translation>Asegúrese de que la URL insertada es válida y que el dispositivo tiene buena conexión.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No custom software found at this URL.</source>
|
||||
<translation>No hay software personalizado en esta URL.</translation>
|
||||
<translation>No encontramos software personalizado en esta URL.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>WARNING: Low Voltage</source>
|
||||
<translation>ALERTA: Volage bajo</translation>
|
||||
<translation>ALERTA: Voltaje bajo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Power your device in a car with a harness or proceed at your own risk.</source>
|
||||
<translation>Encender su dispositivo en el auto con el arnés o proceda bajo su propio riesgo.</translation>
|
||||
<translation>Encienda su dispositivo en un auto con el arnés o proceda bajo su propio riesgo.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Power off</source>
|
||||
@@ -643,11 +643,11 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Before we get on the road, let’s finish installation and cover some details.</source>
|
||||
<translation>Antes de comenzar, terminemos la instalación y cubramos algunos detalles.</translation>
|
||||
<translation>Antes de ponernos en marcha, terminemos la instalación y cubramos algunos detalles.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to Wi-Fi</source>
|
||||
<translation>Conectar a la Wi-Fi</translation>
|
||||
<translation>Conectarse al Wi-Fi</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Back</source>
|
||||
@@ -663,7 +663,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose Software to Install</source>
|
||||
<translation>Elija el software para instalar</translation>
|
||||
<translation>Elija el software a instalar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot</source>
|
||||
@@ -699,7 +699,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Select a language</source>
|
||||
<translation>Seleccione el idioma</translation>
|
||||
<translation>Seleccione un idioma</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -710,7 +710,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pair your device with comma connect (connect.comma.ai) and claim your comma prime offer.</source>
|
||||
<translation>Empareja tu dispositivo con comma connect (connect.comma.ai) y reclama tu oferta de comma prime.</translation>
|
||||
<translation>Empareje su dispositivo con comma connect (connect.comma.ai) y reclame su oferta de comma prime.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pair device</source>
|
||||
@@ -725,11 +725,11 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OFFLINE</source>
|
||||
<translation>SIN LINEA</translation>
|
||||
<translation>OFFLINE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ONLINE</source>
|
||||
<translation>EN LINEA</translation>
|
||||
<translation>EN LÍNEA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ERROR</source>
|
||||
@@ -745,7 +745,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GOOD</source>
|
||||
<translation>BUENO</translation>
|
||||
<translation>BUENA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>OK</source>
|
||||
@@ -769,7 +769,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SEARCH</source>
|
||||
<translation>BUSQUEDA</translation>
|
||||
<translation>BÚSQUEDA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>--</source>
|
||||
@@ -804,7 +804,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
<name>SoftwarePanel</name>
|
||||
<message>
|
||||
<source>Updates are only downloaded while the car is off.</source>
|
||||
<translation>Apague el auto para descargar actualizaciones.</translation>
|
||||
<translation>Actualizaciones solo se descargan con el auto apagado.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Current Version</source>
|
||||
@@ -856,7 +856,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>failed to check for update</source>
|
||||
<translation>no se pudo buscar actualización</translation>
|
||||
<translation>no se pudo buscar actualizaciones</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>DOWNLOAD</source>
|
||||
@@ -883,7 +883,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.</source>
|
||||
<translation>Aviso: Esto otorga acceso SSH a todas las claves públicas en su Github. Nunca inserte un nombre de usuario de Github que no sea suyo. Un empleado de comma nunca le pedirá que añada su nombre de Github.</translation>
|
||||
<translation>Aviso: Esto otorga acceso SSH a todas las claves públicas en su Github. Nunca ingrese un nombre de usuario de Github que no sea suyo. Un empleado de comma NUNCA le pedirá que añada un usuario de Github que no sea el suyo.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ADD</source>
|
||||
@@ -891,7 +891,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enter your GitHub username</source>
|
||||
<translation>Ingresa tu usuario de GitHub</translation>
|
||||
<translation>Ingrese su usuario de GitHub</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>LOADING</source>
|
||||
@@ -903,7 +903,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Username '%1' has no keys on GitHub</source>
|
||||
<translation>Nombre de usuario "%1” no tiene claves en GitHub</translation>
|
||||
<translation>El usuario "%1” no tiene claves en GitHub</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Request timed out</source>
|
||||
@@ -911,7 +911,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Username '%1' doesn't exist on GitHub</source>
|
||||
<translation>Nombre de usuario '%1' no existe en Github</translation>
|
||||
<translation>El usuario '%1' no existe en Github</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -925,7 +925,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
<name>TermsPage</name>
|
||||
<message>
|
||||
<source>Terms & Conditions</source>
|
||||
<translation>Terminos & Condiciones</translation>
|
||||
<translation>Términos & Condiciones</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Decline</source>
|
||||
@@ -948,19 +948,19 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.</source>
|
||||
<translation>Utilice el sistema openpilot para control de crucero adaptativo y asistencia al conductor para mantenerse en el carril. Se requiere su atención en todo momento para utilizar esta función. Cambiar esta configuración solo tendrá efecto con el auto apagado.</translation>
|
||||
<translation>Utilice el sistema openpilot para acceder a un autocrucero adaptativo y asistencia al conductor para mantenerse en el carril. Se requiere su atención en todo momento para utilizar esta función. Cambiar esta configuración solo tendrá efecto con el auto apagado.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot Longitudinal Control (Alpha)</source>
|
||||
<translation>Control longitudinal de openpilot (Alfa)</translation>
|
||||
<translation>Control longitudinal de openpilot (fase experimental)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).</source>
|
||||
<translation>Aviso: el control longitudinal de openpilot está en fase alfa para este automóvil y desactivará el Frenado Automático de Emergencia (AEB).</translation>
|
||||
<translation>AVISO: el control longitudinal de openpilot está en fase experimental para este automóvil y desactivará el Frenado Automático de Emergencia (AEB).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>On this car, openpilot defaults to the car's built-in ACC instead of openpilot's longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.</source>
|
||||
<translation>En este vehículo, openpilot se configura de manera predeterminada con el Control de Crucero Adaptativo (ACC) incorporado en el automóvil en lugar del control longitudinal de openpilot. Habilita esta opción para cambiar al control longitudinal de openpilot. Se recomienda activar el modo experimental al habilitar el control longitudinal alfa de openpilot.</translation>
|
||||
<translation>En este automóvil, openpilot se configura de manera predeterminada con el Autocrucero Adaptativo (ACC) incorporado en el automóvil en lugar del control longitudinal de openpilot. Habilita esta opción para cambiar al control longitudinal de openpilot. Se recomienda activar el modo experimental al habilitar el control longitudinal de openpilot (aún en fase experimental).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Experimental Mode</source>
|
||||
@@ -972,23 +972,23 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When enabled, pressing the accelerator pedal will disengage openpilot.</source>
|
||||
<translation>Cuando esté activado, presionar el acelerador deshabilitará el openpilot.</translation>
|
||||
<translation>Cuando esté activado, presionar el acelerador deshabilitará openpilot.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable Lane Departure Warnings</source>
|
||||
<translation>Activar Aviso de Salida de Carril</translation>
|
||||
<translation>Activar Avisos de Salida de Carril</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h).</source>
|
||||
<translation>Recibir alertas para volver dentro del carril cuando su vehículo se sale fuera del carril sin que esté activado la señal de giro mientras esté conduciendo por encima de 50 km/h (31 mph).</translation>
|
||||
<translation>Recibir alertas para volver al carril cuando su vehículo se salga fuera del carril sin que esté activada la señal de giro y esté conduciendo por encima de 50 km/h (31 mph).</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Always-On Driver Monitoring</source>
|
||||
<translation>Monitoreo del Conductor Siempre Activo</translation>
|
||||
<translation>Monitoreo Permanente del Conductor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable driver monitoring even when openpilot is not engaged.</source>
|
||||
<translation>Habilite el monitoreo del conductor incluso cuando Openpilot no esté activado.</translation>
|
||||
<translation>Habilitar el monitoreo del conductor incluso cuando Openpilot no esté activado.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Record and Upload Driver Camera</source>
|
||||
@@ -996,7 +996,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Upload data from the driver facing camera and help improve the driver monitoring algorithm.</source>
|
||||
<translation>Subir datos de la cámara del conductor para ayudar a mejorar el algoritmo de monitorización del conductor.</translation>
|
||||
<translation>Subir datos de la cámara del conductor para ayudar a mejorar el algoritmo de monitoreo del conductor.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Metric System</source>
|
||||
@@ -1024,19 +1024,19 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. On supported cars, you can cycle through these personalities with your steering wheel distance button.</source>
|
||||
<translation>Se recomienda estándar. En el modo agresivo, openpilot seguirá a los autos líderes más cerca y será más agresivo con el acelerador y el freno. En modo relajado, openpilot se mantendrá más alejado de los coches líderes. En automóviles compatibles, puede recorrer estas personalidades con el botón de distancia del volante.</translation>
|
||||
<translation>Se recomienda el modo estándar. En el modo agresivo, openpilot seguirá más cerca a los autos delante suyo y será más agresivo con el acelerador y el freno. En modo relajado, openpilot se mantendrá más alejado de los autos delante suyo. En automóviles compatibles, puede recorrer estas personalidades con el botón de distancia del volante.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below:</source>
|
||||
<translation>openpilot por defecto conduce en <b>modo chill</b>. El modo Experimental activa <b>recursos de nível-alfa</b> que no están listos para el modo chill. Los recursos del modo expeimental están listados abajo:</translation>
|
||||
<translation>openpilot por defecto conduce en <b>modo chill</b>. El modo Experimental activa <b>funcionalidades en fase experimental</b>, que no están listas para el modo chill. Las funcionalidades del modo expeimental están listados abajo:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>End-to-End Longitudinal Control</source>
|
||||
<translation>🌮 Control Longitudinal de Punta a Punta 🌮</translation>
|
||||
<translation>Control Longitudinal de Punta a Punta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; mistakes should be expected.</source>
|
||||
<translation>Dajar que el modelo de conducción controle la aceleración y el frenado. openpilot va a conducir como lo haría una persona, incluiyendo parar en los semaforos en rojo y las señales de stop. Dado que el modelo decide la velocidad de conducción, la velocidad de crucero establecida actuará como limitador. Este recurso es de una calidad alfa; errores pueden ocurrir.</translation>
|
||||
<translation>Dajar que el modelo de conducción controle la aceleración y el frenado. openpilot conducirá como piensa que lo haría una persona, incluiyendo parar en los semáforos en rojo y las señales de alto. Dado que el modelo decide la velocidad de conducción, la velocidad de crucero establecida solo actuará como el límite superior. Este recurso aún está en fase experimental; deberían esperarse errores.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>New Driving Visualization</source>
|
||||
@@ -1044,11 +1044,11 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner.</source>
|
||||
<translation>La visualización de la conducción cambiará a la cámara que enfoca la carretera a velocidades bajas para mostrar mejor los giros. El logo del modo experimental se mostrará en la esquina superior derecha.</translation>
|
||||
<translation>La visualización de la conducción cambiará a la cámara que enfoca la carretera a velocidades bajas para mostrar mejor los giros. El logo del modo experimental también se mostrará en la esquina superior derecha.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Experimental mode is currently unavailable on this car since the car's stock ACC is used for longitudinal control.</source>
|
||||
<translation>El modo Experimental no está disponible actualmente para este auto, ya que el ACC del auto está siendo usado para el control longitudinal.</translation>
|
||||
<translation>El modo Experimental no está disponible actualmente para este auto, ya que el ACC default del auto está siendo usado para el control longitudinal.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>openpilot longitudinal control may come in a future update.</source>
|
||||
@@ -1056,11 +1056,11 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches.</source>
|
||||
<translation>Se puede probar una versión experimental del control longitudinal openpilot, junto con el modo Experimental, en ramas sin liberación.</translation>
|
||||
<translation>Se puede probar una versión experimental del control longitudinal openpilot, junto con el modo Experimental, en ramas no liberadas.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
|
||||
<translation>Activar el control longitudinal experimental para permitir el modo Experimental.</translation>
|
||||
<translation>Activar el control longitudinal (fase experimental) para permitir el modo Experimental.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -1071,7 +1071,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>An operating system update is required. Connect your device to Wi-Fi for the fastest update experience. The download size is approximately 1GB.</source>
|
||||
<translation>Es necesario la actualización del sistema operativo. Conecte su dispositivo a Wi-Fi para una actualización rápida. El tamaño de descarga es de aproximadamente 1GB.</translation>
|
||||
<translation>Es necesario la actualización del sistema operativo. Conecte su dispositivo al Wi-Fi para una actualización rápida. El tamaño de descarga es de aproximadamente 1GB.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to Wi-Fi</source>
|
||||
@@ -1106,7 +1106,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Connect to Wi-Fi to upload driving data and help improve openpilot</source>
|
||||
<translation>Conectar a Wi-Fi para subir los datos de conducir para mejorar openpilot</translation>
|
||||
<translation>Conectarse al Wi-Fi para subir los datos de conducción y mejorar openpilot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open Settings</source>
|
||||
@@ -1137,7 +1137,7 @@ Esto puede tardar hasta un minuto.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Forget Wi-Fi Network "%1"?</source>
|
||||
<translation>Olvidar Red Wi-Fi "%1"?</translation>
|
||||
<translation>¿Olvidar la Red de Wi-Fi "%1"?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Forget</source>
|
||||
|
||||
@@ -401,6 +401,7 @@ def uploadFilesToUrls(files_data: list[UploadFileDict]) -> UploadFilesToUrlRespo
|
||||
|
||||
resp: UploadFilesToUrlResponse = {"enqueued": len(items), "items": items}
|
||||
if failed:
|
||||
cloudlog.event("athena.uploadFilesToUrls.failed", failed=failed, error=True)
|
||||
resp["failed"] = failed
|
||||
|
||||
return resp
|
||||
|
||||
@@ -244,7 +244,7 @@ static kj::Array<capnp::byte> yuv420_to_jpeg(const CameraBuf *b, int thumbnail_w
|
||||
return dat;
|
||||
}
|
||||
|
||||
static void publish_thumbnail(PubMaster *pm, const CameraBuf *b) {
|
||||
void publish_thumbnail(PubMaster *pm, const CameraBuf *b) {
|
||||
auto thumbnail = yuv420_to_jpeg(b, b->rgb_width / 4, b->rgb_height / 4);
|
||||
if (thumbnail.size() == 0) return;
|
||||
|
||||
@@ -284,36 +284,6 @@ float set_exposure_target(const CameraBuf *b, Rect ae_xywh, int x_skip, int y_sk
|
||||
return lum_med / 256.0;
|
||||
}
|
||||
|
||||
void *processing_thread(MultiCameraState *cameras, CameraState *cs, process_thread_cb callback) {
|
||||
const char *thread_name = nullptr;
|
||||
if (cs == &cameras->road_cam) {
|
||||
thread_name = "RoadCamera";
|
||||
} else if (cs == &cameras->driver_cam) {
|
||||
thread_name = "DriverCamera";
|
||||
} else {
|
||||
thread_name = "WideRoadCamera";
|
||||
}
|
||||
util::set_thread_name(thread_name);
|
||||
|
||||
uint32_t cnt = 0;
|
||||
while (!do_exit) {
|
||||
if (!cs->buf.acquire()) continue;
|
||||
|
||||
callback(cameras, cs, cnt);
|
||||
|
||||
if (cs == &(cameras->road_cam) && cameras->pm && cnt % 100 == 3) {
|
||||
// this takes 10ms???
|
||||
publish_thumbnail(cameras->pm, &(cs->buf));
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::thread start_process_thread(MultiCameraState *cameras, CameraState *cs, process_thread_cb callback) {
|
||||
return std::thread(processing_thread, cameras, cs, callback);
|
||||
}
|
||||
|
||||
void camerad_thread() {
|
||||
cl_device_id device_id = cl_get_device_id(CL_DEVICE_TYPE_DEFAULT);
|
||||
#ifdef QCOM2
|
||||
@@ -324,7 +294,7 @@ void camerad_thread() {
|
||||
#endif
|
||||
|
||||
{
|
||||
MultiCameraState cameras = {};
|
||||
MultiCameraState cameras;
|
||||
VisionIpcServer vipc_server("camerad", device_id, context);
|
||||
|
||||
cameras_open(&cameras);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "cereal/messaging/messaging.h"
|
||||
#include "msgq/visionipc/visionipc_server.h"
|
||||
@@ -18,9 +17,6 @@ enum CameraType {
|
||||
};
|
||||
|
||||
// for debugging
|
||||
const bool env_disable_road = getenv("DISABLE_ROAD") != NULL;
|
||||
const bool env_disable_wide_road = getenv("DISABLE_WIDE_ROAD") != NULL;
|
||||
const bool env_disable_driver = getenv("DISABLE_DRIVER") != NULL;
|
||||
const bool env_debug_frames = getenv("DEBUG_FRAMES") != NULL;
|
||||
const bool env_log_raw_frames = getenv("LOG_RAW_FRAMES") != NULL;
|
||||
const bool env_ctrl_exp_from_params = getenv("CTRL_EXP_FROM_PARAMS") != NULL;
|
||||
@@ -72,13 +68,10 @@ public:
|
||||
void queue(size_t buf_idx);
|
||||
};
|
||||
|
||||
typedef void (*process_thread_cb)(MultiCameraState *s, CameraState *c, int cnt);
|
||||
|
||||
void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &frame_data, CameraState *c);
|
||||
kj::Array<uint8_t> get_raw_frame_image(const CameraBuf *b);
|
||||
float set_exposure_target(const CameraBuf *b, Rect ae_xywh, int x_skip, int y_skip);
|
||||
std::thread start_process_thread(MultiCameraState *cameras, CameraState *cs, process_thread_cb callback);
|
||||
|
||||
void publish_thumbnail(PubMaster *pm, const CameraBuf *b);
|
||||
void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx);
|
||||
void cameras_open(MultiCameraState *s);
|
||||
void cameras_run(MultiCameraState *s);
|
||||
|
||||
@@ -26,6 +26,16 @@ const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py
|
||||
|
||||
extern ExitHandler do_exit;
|
||||
|
||||
CameraState::CameraState(MultiCameraState *multi_camera_state, const CameraConfig &config)
|
||||
: multi_cam_state(multi_camera_state),
|
||||
camera_num(config.camera_num),
|
||||
stream_type(config.stream_type),
|
||||
focal_len(config.focal_len),
|
||||
publish_name(config.publish_name),
|
||||
init_camera_state(config.init_camera_state),
|
||||
enabled(config.enabled) {
|
||||
}
|
||||
|
||||
int CameraState::clear_req_queue() {
|
||||
struct cam_req_mgr_flush_info req_mgr_flush_request = {0};
|
||||
req_mgr_flush_request.session_hdl = session_handle;
|
||||
@@ -425,50 +435,50 @@ void CameraState::set_exposure_rect() {
|
||||
}
|
||||
|
||||
void CameraState::sensor_set_parameters() {
|
||||
target_grey_fraction = 0.3;
|
||||
|
||||
dc_gain_enabled = false;
|
||||
dc_gain_weight = ci->dc_gain_min_weight;
|
||||
gain_idx = ci->analog_gain_rec_idx;
|
||||
exposure_time = 5;
|
||||
cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (ci->dc_gain_factor-1) / ci->dc_gain_max_weight) * ci->sensor_analog_gains[gain_idx] * exposure_time;
|
||||
}
|
||||
|
||||
void CameraState::camera_map_bufs(MultiCameraState *s) {
|
||||
void CameraState::camera_map_bufs() {
|
||||
for (int i = 0; i < FRAME_BUF_COUNT; i++) {
|
||||
// configure ISP to put the image in place
|
||||
struct cam_mem_mgr_map_cmd mem_mgr_map_cmd = {0};
|
||||
mem_mgr_map_cmd.mmu_hdls[0] = s->device_iommu;
|
||||
mem_mgr_map_cmd.mmu_hdls[0] = multi_cam_state->device_iommu;
|
||||
mem_mgr_map_cmd.num_hdl = 1;
|
||||
mem_mgr_map_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
|
||||
mem_mgr_map_cmd.fd = buf.camera_bufs[i].fd;
|
||||
int ret = do_cam_control(s->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
|
||||
int ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
|
||||
LOGD("map buf req: (fd: %d) 0x%x %d", buf.camera_bufs[i].fd, mem_mgr_map_cmd.out.buf_handle, ret);
|
||||
buf_handle[i] = mem_mgr_map_cmd.out.buf_handle;
|
||||
}
|
||||
enqueue_req_multi(1, FRAME_BUF_COUNT, 0);
|
||||
}
|
||||
|
||||
void CameraState::camera_init(MultiCameraState *s, VisionIpcServer * v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type, float focal_len) {
|
||||
void CameraState::camera_init(VisionIpcServer * v, cl_device_id device_id, cl_context ctx) {
|
||||
if (!enabled) return;
|
||||
|
||||
LOGD("camera init %d", camera_num);
|
||||
request_id_last = 0;
|
||||
skipped = true;
|
||||
|
||||
buf.init(device_id, ctx, this, v, FRAME_BUF_COUNT, yuv_type);
|
||||
camera_map_bufs(s);
|
||||
buf.init(device_id, ctx, this, v, FRAME_BUF_COUNT, stream_type);
|
||||
camera_map_bufs();
|
||||
|
||||
fl_pix = focal_len / ci->pixel_size_mm;
|
||||
set_exposure_rect();
|
||||
}
|
||||
|
||||
void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num_, bool enabled_) {
|
||||
multi_cam_state = multi_cam_state_;
|
||||
camera_num = camera_num_;
|
||||
enabled = enabled_;
|
||||
void CameraState::camera_open() {
|
||||
if (!enabled) return;
|
||||
|
||||
if (!openSensor()) {
|
||||
return;
|
||||
}
|
||||
|
||||
configISP();
|
||||
configCSIPHY();
|
||||
linkDevices();
|
||||
}
|
||||
|
||||
bool CameraState::openSensor() {
|
||||
sensor_fd = open_v4l_by_name_and_index("cam-sensor-driver", camera_num);
|
||||
assert(sensor_fd >= 0);
|
||||
LOGD("opened sensor for %d", camera_num);
|
||||
@@ -493,7 +503,7 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
!init_sensor_lambda(new OS04C10)) {
|
||||
LOGE("** sensor %d FAILED bringup, disabling", camera_num);
|
||||
enabled = false;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
LOGD("-- Probing sensor %d success", camera_num);
|
||||
|
||||
@@ -512,7 +522,10 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
|
||||
LOG("-- Configuring sensor");
|
||||
sensors_i2c(ci->init_reg_array.data(), ci->init_reg_array.size(), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, ci->data_word);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraState::configISP() {
|
||||
// NOTE: to be able to disable road and wide road, we still have to configure the sensor over i2c
|
||||
// If you don't do this, the strobe GPIO is an output (even in reset it seems!)
|
||||
if (!enabled) return;
|
||||
@@ -570,6 +583,13 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
isp_dev_handle = *isp_dev_handle_;
|
||||
LOGD("acquire isp dev");
|
||||
|
||||
// config ISP
|
||||
alloc_w_mmu_hdl(multi_cam_state->video0_fd, 984480, (uint32_t*)&buf0_handle, 0x20, CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS |
|
||||
CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE, multi_cam_state->device_iommu, multi_cam_state->cdm_iommu);
|
||||
config_isp(0, 0, 1, buf0_handle, 0);
|
||||
}
|
||||
|
||||
void CameraState::configCSIPHY() {
|
||||
csiphy_fd = open_v4l_by_name_and_index("cam-csiphy-driver", camera_num);
|
||||
assert(csiphy_fd >= 0);
|
||||
LOGD("opened csiphy for %d", camera_num);
|
||||
@@ -580,11 +600,6 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
csiphy_dev_handle = *csiphy_dev_handle_;
|
||||
LOGD("acquire csiphy dev");
|
||||
|
||||
// config ISP
|
||||
alloc_w_mmu_hdl(multi_cam_state->video0_fd, 984480, (uint32_t*)&buf0_handle, 0x20, CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS |
|
||||
CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE, multi_cam_state->device_iommu, multi_cam_state->cdm_iommu);
|
||||
config_isp(0, 0, 1, buf0_handle, 0);
|
||||
|
||||
// config csiphy
|
||||
LOG("-- Config CSI PHY");
|
||||
{
|
||||
@@ -612,15 +627,16 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
int ret_ = device_config(csiphy_fd, session_handle, csiphy_dev_handle, cam_packet_handle);
|
||||
assert(ret_ == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// link devices
|
||||
void CameraState::linkDevices() {
|
||||
LOG("-- Link devices");
|
||||
struct cam_req_mgr_link_info req_mgr_link_info = {0};
|
||||
req_mgr_link_info.session_hdl = session_handle;
|
||||
req_mgr_link_info.num_devices = 2;
|
||||
req_mgr_link_info.dev_hdls[0] = isp_dev_handle;
|
||||
req_mgr_link_info.dev_hdls[1] = sensor_dev_handle;
|
||||
ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_LINK, &req_mgr_link_info, sizeof(req_mgr_link_info));
|
||||
int ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_LINK, &req_mgr_link_info, sizeof(req_mgr_link_info));
|
||||
link_handle = req_mgr_link_info.link_hdl;
|
||||
LOGD("link: %d session: 0x%X isp: 0x%X sensors: 0x%X link: 0x%X", ret, session_handle, isp_dev_handle, sensor_dev_handle, link_handle);
|
||||
|
||||
@@ -644,9 +660,9 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num
|
||||
}
|
||||
|
||||
void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
|
||||
s->driver_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_DRIVER, DRIVER_FL_MM);
|
||||
s->road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_ROAD, ROAD_FL_MM);
|
||||
s->wide_road_cam.camera_init(s, v, device_id, ctx, VISION_STREAM_WIDE_ROAD, WIDE_FL_MM);
|
||||
s->driver_cam.camera_init(v, device_id, ctx);
|
||||
s->road_cam.camera_init(v, device_id, ctx);
|
||||
s->wide_road_cam.camera_init(v, device_id, ctx);
|
||||
|
||||
s->pm = new PubMaster({"roadCameraState", "driverCameraState", "wideRoadCameraState", "thumbnail"});
|
||||
}
|
||||
@@ -690,11 +706,11 @@ void cameras_open(MultiCameraState *s) {
|
||||
ret = HANDLE_EINTR(ioctl(s->video0_fd, VIDIOC_SUBSCRIBE_EVENT, &sub));
|
||||
LOGD("req mgr subscribe: %d", ret);
|
||||
|
||||
s->driver_cam.camera_open(s, 2, !env_disable_driver);
|
||||
s->driver_cam.camera_open();
|
||||
LOGD("driver camera opened");
|
||||
s->road_cam.camera_open(s, 1, !env_disable_road);
|
||||
s->road_cam.camera_open();
|
||||
LOGD("road camera opened");
|
||||
s->wide_road_cam.camera_open(s, 0, !env_disable_wide_road);
|
||||
s->wide_road_cam.camera_open();
|
||||
LOGD("wide road camera opened");
|
||||
}
|
||||
|
||||
@@ -927,41 +943,50 @@ void CameraState::set_camera_exposure(float grey_frac) {
|
||||
sensors_i2c(exp_reg_array.data(), exp_reg_array.size(), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, ci->data_word);
|
||||
}
|
||||
|
||||
static void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) {
|
||||
c->set_camera_exposure(set_exposure_target(&c->buf, c->ae_xywh, 2, 4));
|
||||
void CameraState::run() {
|
||||
util::set_thread_name(publish_name);
|
||||
|
||||
MessageBuilder msg;
|
||||
auto framed = msg.initEvent().initDriverCameraState();
|
||||
fill_frame_data(framed, c->buf.cur_frame_data, c);
|
||||
for (uint32_t cnt = 0; !do_exit; ++cnt) {
|
||||
// Acquire the buffer; continue if acquisition fails
|
||||
if (!buf.acquire()) continue;
|
||||
|
||||
c->ci->processRegisters(c, framed);
|
||||
s->pm->send("driverCameraState", msg);
|
||||
MessageBuilder msg;
|
||||
auto framed = (msg.initEvent().*init_camera_state)();
|
||||
fill_frame_data(framed, buf.cur_frame_data, this);
|
||||
|
||||
// Log raw frames for road camera
|
||||
if (env_log_raw_frames && stream_type == VISION_STREAM_ROAD && cnt % 100 == 5) { // no overlap with qlog decimation
|
||||
framed.setImage(get_raw_frame_image(&buf));
|
||||
}
|
||||
// Log frame id for road and wide road cameras
|
||||
if (stream_type != VISION_STREAM_DRIVER) {
|
||||
LOGT(buf.cur_frame_data.frame_id, "%s: Image set", publish_name);
|
||||
}
|
||||
|
||||
// Process camera registers and set camera exposure
|
||||
ci->processRegisters(this, framed);
|
||||
set_camera_exposure(set_exposure_target(&buf, ae_xywh, 2, stream_type != VISION_STREAM_DRIVER ? 2 : 4));
|
||||
|
||||
// Send the message
|
||||
multi_cam_state->pm->send(publish_name, msg);
|
||||
if (stream_type == VISION_STREAM_ROAD && cnt % 100 == 3) {
|
||||
publish_thumbnail(multi_cam_state->pm, &buf); // this takes 10ms???
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) {
|
||||
const CameraBuf *b = &c->buf;
|
||||
|
||||
MessageBuilder msg;
|
||||
auto framed = c == &s->road_cam ? msg.initEvent().initRoadCameraState() : msg.initEvent().initWideRoadCameraState();
|
||||
fill_frame_data(framed, b->cur_frame_data, c);
|
||||
if (env_log_raw_frames && c == &s->road_cam && cnt % 100 == 5) { // no overlap with qlog decimation
|
||||
framed.setImage(get_raw_frame_image(b));
|
||||
}
|
||||
LOGT(c->buf.cur_frame_data.frame_id, "%s: Image set", c == &s->road_cam ? "RoadCamera" : "WideRoadCamera");
|
||||
|
||||
c->ci->processRegisters(c, framed);
|
||||
s->pm->send(c == &s->road_cam ? "roadCameraState" : "wideRoadCameraState", msg);
|
||||
|
||||
const int skip = 2;
|
||||
c->set_camera_exposure(set_exposure_target(b, c->ae_xywh, skip, skip));
|
||||
MultiCameraState::MultiCameraState()
|
||||
: driver_cam(this, DRIVER_CAMERA_CONFIG),
|
||||
road_cam(this, ROAD_CAMERA_CONFIG),
|
||||
wide_road_cam(this, WIDE_ROAD_CAMERA_CONFIG) {
|
||||
}
|
||||
|
||||
void cameras_run(MultiCameraState *s) {
|
||||
LOG("-- Starting threads");
|
||||
std::vector<std::thread> threads;
|
||||
if (s->driver_cam.enabled) threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera));
|
||||
if (s->road_cam.enabled) threads.push_back(start_process_thread(s, &s->road_cam, process_road_camera));
|
||||
if (s->wide_road_cam.enabled) threads.push_back(start_process_thread(s, &s->wide_road_cam, process_road_camera));
|
||||
if (s->driver_cam.enabled) threads.emplace_back(&CameraState::run, &s->driver_cam);
|
||||
if (s->road_cam.enabled) threads.emplace_back(&CameraState::run, &s->road_cam);
|
||||
if (s->wide_road_cam.enabled) threads.emplace_back(&CameraState::run, &s->wide_road_cam);
|
||||
|
||||
// start devices
|
||||
LOG("-- Starting devices");
|
||||
|
||||
@@ -11,67 +11,105 @@
|
||||
|
||||
#define FRAME_BUF_COUNT 4
|
||||
|
||||
#define ROAD_FL_MM 8.0f
|
||||
#define WIDE_FL_MM 1.71f
|
||||
#define DRIVER_FL_MM 1.71f
|
||||
struct CameraConfig {
|
||||
int camera_num;
|
||||
VisionStreamType stream_type;
|
||||
float focal_len; // millimeters
|
||||
const char *publish_name;
|
||||
cereal::FrameData::Builder (cereal::Event::Builder::*init_camera_state)();
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
const CameraConfig WIDE_ROAD_CAMERA_CONFIG = {
|
||||
.camera_num = 0,
|
||||
.stream_type = VISION_STREAM_WIDE_ROAD,
|
||||
.focal_len = 1.71,
|
||||
.publish_name = "wideRoadCameraState",
|
||||
.init_camera_state = &cereal::Event::Builder::initWideRoadCameraState,
|
||||
.enabled = !getenv("DISABLE_WIDE_ROAD"),
|
||||
};
|
||||
|
||||
const CameraConfig ROAD_CAMERA_CONFIG = {
|
||||
.camera_num = 1,
|
||||
.stream_type = VISION_STREAM_ROAD,
|
||||
.focal_len = 8.0,
|
||||
.publish_name = "roadCameraState",
|
||||
.init_camera_state = &cereal::Event::Builder::initRoadCameraState,
|
||||
.enabled = !getenv("DISABLE_ROAD"),
|
||||
};
|
||||
|
||||
const CameraConfig DRIVER_CAMERA_CONFIG = {
|
||||
.camera_num = 2,
|
||||
.stream_type = VISION_STREAM_DRIVER,
|
||||
.focal_len = 1.71,
|
||||
.publish_name = "driverCameraState",
|
||||
.init_camera_state = &cereal::Event::Builder::initDriverCameraState,
|
||||
.enabled = !getenv("DISABLE_DRIVER"),
|
||||
};
|
||||
|
||||
class CameraState {
|
||||
public:
|
||||
MultiCameraState *multi_cam_state;
|
||||
MultiCameraState *multi_cam_state = nullptr;
|
||||
std::unique_ptr<const SensorInfo> ci;
|
||||
bool enabled;
|
||||
bool enabled = true;
|
||||
VisionStreamType stream_type;
|
||||
const char *publish_name = nullptr;
|
||||
cereal::FrameData::Builder (cereal::Event::Builder::*init_camera_state)() = nullptr;
|
||||
float focal_len = 0;
|
||||
|
||||
std::mutex exp_lock;
|
||||
|
||||
int exposure_time;
|
||||
bool dc_gain_enabled;
|
||||
int dc_gain_weight;
|
||||
int gain_idx;
|
||||
float analog_gain_frac;
|
||||
int exposure_time = 5;
|
||||
bool dc_gain_enabled = false;
|
||||
int dc_gain_weight = 0;
|
||||
int gain_idx = 0;
|
||||
float analog_gain_frac = 0;
|
||||
|
||||
float cur_ev[3];
|
||||
float best_ev_score;
|
||||
int new_exp_g;
|
||||
int new_exp_t;
|
||||
float cur_ev[3] = {};
|
||||
float best_ev_score = 0;
|
||||
int new_exp_g = 0;
|
||||
int new_exp_t = 0;
|
||||
|
||||
Rect ae_xywh;
|
||||
float measured_grey_fraction;
|
||||
float target_grey_fraction;
|
||||
Rect ae_xywh = {};
|
||||
float measured_grey_fraction = 0;
|
||||
float target_grey_fraction = 0.3;
|
||||
|
||||
unique_fd sensor_fd;
|
||||
unique_fd csiphy_fd;
|
||||
|
||||
int camera_num;
|
||||
float fl_pix;
|
||||
int camera_num = 0;
|
||||
float fl_pix = 0;
|
||||
|
||||
CameraState(MultiCameraState *multi_camera_state, const CameraConfig &config);
|
||||
void handle_camera_event(void *evdat);
|
||||
void update_exposure_score(float desired_ev, int exp_t, int exp_g_idx, float exp_gain);
|
||||
void set_camera_exposure(float grey_frac);
|
||||
|
||||
void sensors_start();
|
||||
|
||||
void camera_open(MultiCameraState *multi_cam_state, int camera_num, bool enabled);
|
||||
void camera_open();
|
||||
void set_exposure_rect();
|
||||
void sensor_set_parameters();
|
||||
void camera_map_bufs(MultiCameraState *s);
|
||||
void camera_init(MultiCameraState *s, VisionIpcServer *v, cl_device_id device_id, cl_context ctx, VisionStreamType yuv_type, float focal_len);
|
||||
void camera_map_bufs();
|
||||
void camera_init(VisionIpcServer *v, cl_device_id device_id, cl_context ctx);
|
||||
void camera_close();
|
||||
void run();
|
||||
|
||||
int32_t session_handle;
|
||||
int32_t sensor_dev_handle;
|
||||
int32_t isp_dev_handle;
|
||||
int32_t csiphy_dev_handle;
|
||||
int32_t session_handle = -1;
|
||||
int32_t sensor_dev_handle = -1;
|
||||
int32_t isp_dev_handle = -1;
|
||||
int32_t csiphy_dev_handle = -1;
|
||||
|
||||
int32_t link_handle;
|
||||
int32_t link_handle = -1;
|
||||
|
||||
int buf0_handle;
|
||||
int buf_handle[FRAME_BUF_COUNT];
|
||||
int sync_objs[FRAME_BUF_COUNT];
|
||||
int request_ids[FRAME_BUF_COUNT];
|
||||
int request_id_last;
|
||||
int frame_id_last;
|
||||
int idx_offset;
|
||||
bool skipped;
|
||||
int buf0_handle = 0;
|
||||
int buf_handle[FRAME_BUF_COUNT] = {};
|
||||
int sync_objs[FRAME_BUF_COUNT] = {};
|
||||
int request_ids[FRAME_BUF_COUNT] = {};
|
||||
int request_id_last = 0;
|
||||
int frame_id_last = 0;
|
||||
int idx_offset = 0;
|
||||
bool skipped = true;
|
||||
|
||||
CameraBuf buf;
|
||||
MemoryManager mm;
|
||||
@@ -86,20 +124,28 @@ public:
|
||||
void sensors_i2c(const struct i2c_random_wr_payload* dat, int len, int op_code, bool data_word);
|
||||
|
||||
private:
|
||||
bool openSensor();
|
||||
void configISP();
|
||||
void configCSIPHY();
|
||||
void linkDevices();
|
||||
|
||||
// for debugging
|
||||
Params params;
|
||||
};
|
||||
|
||||
typedef struct MultiCameraState {
|
||||
class MultiCameraState {
|
||||
public:
|
||||
MultiCameraState();
|
||||
|
||||
unique_fd video0_fd;
|
||||
unique_fd cam_sync_fd;
|
||||
unique_fd isp_fd;
|
||||
int device_iommu;
|
||||
int cdm_iommu;
|
||||
int device_iommu = -1;
|
||||
int cdm_iommu = -1;
|
||||
|
||||
CameraState road_cam;
|
||||
CameraState wide_road_cam;
|
||||
CameraState driver_cam;
|
||||
|
||||
PubMaster *pm;
|
||||
} MultiCameraState;
|
||||
};
|
||||
|
||||
+12
-10
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
from functools import cache
|
||||
|
||||
from cereal import messaging
|
||||
from openpilot.common.realtime import Ratekeeper
|
||||
@@ -10,7 +11,16 @@ RATE = 10
|
||||
FFT_SAMPLES = 4096
|
||||
REFERENCE_SPL = 2e-5 # newtons/m^2
|
||||
SAMPLE_RATE = 44100
|
||||
SAMPLE_BUFFER = 4096 # (approx 100ms)
|
||||
SAMPLE_BUFFER = 4096 # approx 100ms
|
||||
|
||||
|
||||
@cache
|
||||
def get_a_weighting_filter():
|
||||
# Calculate the A-weighting filter
|
||||
# https://en.wikipedia.org/wiki/A-weighting
|
||||
freqs = np.fft.fftfreq(FFT_SAMPLES, d=1 / SAMPLE_RATE)
|
||||
A = 12194 ** 2 * freqs ** 4 / ((freqs ** 2 + 20.6 ** 2) * (freqs ** 2 + 12194 ** 2) * np.sqrt((freqs ** 2 + 107.7 ** 2) * (freqs ** 2 + 737.9 ** 2)))
|
||||
return A / np.max(A)
|
||||
|
||||
|
||||
def calculate_spl(measurements):
|
||||
@@ -27,16 +37,8 @@ def apply_a_weighting(measurements: np.ndarray) -> np.ndarray:
|
||||
# Generate a Hanning window of the same length as the audio measurements
|
||||
measurements_windowed = measurements * np.hanning(len(measurements))
|
||||
|
||||
# Calculate the frequency axis for the signal
|
||||
freqs = np.fft.fftfreq(measurements_windowed.size, d=1 / SAMPLE_RATE)
|
||||
|
||||
# Calculate the A-weighting filter
|
||||
# https://en.wikipedia.org/wiki/A-weighting
|
||||
A = 12194 ** 2 * freqs ** 4 / ((freqs ** 2 + 20.6 ** 2) * (freqs ** 2 + 12194 ** 2) * np.sqrt((freqs ** 2 + 107.7 ** 2) * (freqs ** 2 + 737.9 ** 2)))
|
||||
A /= np.max(A) # Normalize the filter
|
||||
|
||||
# Apply the A-weighting filter to the signal
|
||||
return np.abs(np.fft.ifft(np.fft.fft(measurements_windowed) * A))
|
||||
return np.abs(np.fft.ifft(np.fft.fft(measurements_windowed) * get_a_weighting_filter()))
|
||||
|
||||
|
||||
class Mic:
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:85e765be665eab8ce8b64d6a884148e0ff3905fadcef6c0daa75e4efd84bb5cb
|
||||
size 499734
|
||||
oid sha256:320bef5a75a62dd2731a496040921d5000f1ed237ae70fd7aeb6c010a1534363
|
||||
size 462482
|
||||
|
||||
@@ -34,7 +34,7 @@ update_uv
|
||||
|
||||
# TODO: remove --no-cache once this is fixed: https://github.com/astral-sh/uv/issues/4378
|
||||
echo "installing python packages..."
|
||||
uv --no-cache sync --all-extras
|
||||
uv --no-cache sync --frozen --all-extras
|
||||
source .venv/bin/activate
|
||||
|
||||
echo "PYTHONPATH=${PWD}" > $ROOT/.env
|
||||
|
||||
@@ -3,7 +3,6 @@ import argparse
|
||||
import json
|
||||
import matplotlib.patches as mpatches
|
||||
import matplotlib.pyplot as plt
|
||||
import mpld3
|
||||
import sys
|
||||
from bisect import bisect_left, bisect_right
|
||||
from collections import defaultdict
|
||||
@@ -174,7 +173,6 @@ def print_timestamps(timestamps, durations, start_times, relative):
|
||||
print(" "+'%-53s%-53s' %(event, str(time*1000)))
|
||||
|
||||
def graph_timestamps(timestamps, start_times, end_times, relative, offset_services=False, title=""):
|
||||
# mpld3 doesn't convert properly to D3 font sizes
|
||||
plt.rcParams.update({'font.size': 18})
|
||||
|
||||
t0 = find_t0(start_times)
|
||||
@@ -203,15 +201,14 @@ def graph_timestamps(timestamps, start_times, end_times, relative, offset_servic
|
||||
points['labels'].append(event[0])
|
||||
ax.broken_barh(service_bars, (i-height/2, height), facecolors=(colors), alpha=0.5, offsets=offsets)
|
||||
|
||||
scatter = ax.scatter(points['x'], points['y'], marker='d', edgecolor='black')
|
||||
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=points['labels'])
|
||||
mpld3.plugins.connect(fig, tooltip)
|
||||
ax.scatter(points['x'], points['y'], marker='d', edgecolor='black')
|
||||
for i, label in enumerate(points['labels']):
|
||||
ax.annotate(label, (points['x'][i], points['y'][i]), textcoords="offset points", xytext=(0,10), ha='center')
|
||||
|
||||
plt.title(title)
|
||||
# Set size relative window size is not trivial: https://github.com/mpld3/mpld3/issues/65
|
||||
fig.set_size_inches(18, 9)
|
||||
plt.legend(handles=[mpatches.Patch(color=colors[i], label=SERVICES[i]) for i in range(len(SERVICES))])
|
||||
return fig
|
||||
plt.show()
|
||||
|
||||
def get_timestamps(lr):
|
||||
lr = list(lr)
|
||||
@@ -239,4 +236,4 @@ if __name__ == "__main__":
|
||||
data, _ = get_timestamps(lr)
|
||||
print_timestamps(data['timestamp'], data['duration'], data['start'], args.relative)
|
||||
if args.plot:
|
||||
mpld3.show(graph_timestamps(data['timestamp'], data['start'], data['end'], args.relative, offset_services=args.offset, title=r))
|
||||
graph_timestamps(data['timestamp'], data['start'], data['end'], args.relative, offset_services=args.offset, title=r)
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import bz2
|
||||
|
||||
|
||||
# regex patterns
|
||||
class RE:
|
||||
DONGLE_ID = r'(?P<dongle_id>[a-f0-9]{16})'
|
||||
@@ -18,13 +15,3 @@ class RE:
|
||||
|
||||
EXPLORER_FILE = fr'^(?P<segment_name>{SEGMENT_NAME})--(?P<file_name>[a-z]+\.[a-z0-9]+)$'
|
||||
OP_SEGMENT_DIR = fr'^(?P<segment_name>{SEGMENT_NAME})$'
|
||||
|
||||
|
||||
def save_log(dest, log_msgs, compress=True):
|
||||
dat = b"".join(msg.as_builder().to_bytes() for msg in log_msgs)
|
||||
|
||||
if compress:
|
||||
dat = bz2.compress(dat)
|
||||
|
||||
with open(dest, "wb") as f:
|
||||
f.write(dat)
|
||||
|
||||
@@ -27,6 +27,16 @@ LogIterable = Iterable[LogMessage]
|
||||
RawLogIterable = Iterable[bytes]
|
||||
|
||||
|
||||
def save_log(dest, log_msgs, compress=True):
|
||||
dat = b"".join(msg.as_builder().to_bytes() for msg in log_msgs)
|
||||
|
||||
if compress:
|
||||
dat = bz2.compress(dat)
|
||||
|
||||
with open(dest, "wb") as f:
|
||||
f.write(dat)
|
||||
|
||||
|
||||
class _LogFileReader:
|
||||
def __init__(self, fn, canonicalize=True, only_union_types=False, sort_by_time=False, dat=None):
|
||||
self.data_version = None
|
||||
@@ -140,6 +150,7 @@ def internal_source(sr: SegmentRange, mode: ReadMode, file_ext: str = "bz2") ->
|
||||
def get_internal_url(sr: SegmentRange, seg, file):
|
||||
return f"cd:/{sr.dongle_id}/{sr.log_id}/{seg}/{file}.{file_ext}"
|
||||
|
||||
# TODO: list instead of using static URLs to support routes with multiple file extensions
|
||||
rlog_paths = [get_internal_url(sr, seg, "rlog") for seg in sr.seg_idxs]
|
||||
qlog_paths = [get_internal_url(sr, seg, "qlog") for seg in sr.seg_idxs]
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ from openpilot.tools.lib.helpers import RE
|
||||
|
||||
QLOG_FILENAMES = ['qlog', 'qlog.bz2', 'qlog.zst']
|
||||
QCAMERA_FILENAMES = ['qcamera.ts']
|
||||
LOG_FILENAMES = ['rlog', 'rlog.bz2', 'raw_log.bz2']
|
||||
LOG_FILENAMES = ['rlog', 'rlog.bz2', 'raw_log.bz2', 'rlog.zst']
|
||||
CAMERA_FILENAMES = ['fcamera.hevc', 'video.hevc']
|
||||
DCAMERA_FILENAMES = ['dcamera.hevc']
|
||||
ECAMERA_FILENAMES = ['ecamera.hevc']
|
||||
|
||||
+6
-13
@@ -2,19 +2,12 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$SKIP_PROMPT" ]; then
|
||||
echo "--------------- macOS support ---------------"
|
||||
echo "Running openpilot natively on macOS is not officially supported."
|
||||
echo "It might build, some parts of it might work, but it's not fully tested, so there might be some issues."
|
||||
echo
|
||||
echo "Check out devcontainers for a seamless experience (see tools/README.md)."
|
||||
echo "-------------------------------------------------"
|
||||
echo -n "Are you sure you want to continue? [y/N] "
|
||||
read -r response
|
||||
if [[ ! "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo "--------------- macOS support ---------------"
|
||||
echo "Running openpilot natively on macOS is still a work-in-progress."
|
||||
echo "It might build, some parts of it might work, but it's not fully tested, so there might be some issues."
|
||||
echo
|
||||
echo "Check out devcontainers for a seamless experience (see tools/README.md)."
|
||||
echo "-------------------------------------------------"
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
ROOT="$(cd $DIR/../ && pwd)"
|
||||
|
||||
Executable
+395
@@ -0,0 +1,395 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
UNDERLINE='\033[4m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
function op_install() {
|
||||
(set -e
|
||||
|
||||
echo "Installing op system-wide..."
|
||||
RC_FILE="${HOME}/.$(basename ${SHELL})rc"
|
||||
if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then
|
||||
RC_FILE="$HOME/.bash_profile"
|
||||
fi
|
||||
printf "\nalias op='source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/op.sh" \"\$@\"'\n" >> $RC_FILE
|
||||
echo -e " ↳ [${GREEN}✔${NC}] op installed successfully. Open a new shell to use it.\n"
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_run_command() {
|
||||
CMD="$@"
|
||||
echo -e "${BOLD}Running:${NC} $CMD"
|
||||
if [[ -z "$DRY" ]]; then
|
||||
eval "$CMD"
|
||||
fi
|
||||
}
|
||||
|
||||
# be default, assume openpilot dir is in current directory
|
||||
OPENPILOT_ROOT=$(pwd)
|
||||
function op_get_openpilot_dir() {
|
||||
while [[ "$OPENPILOT_ROOT" != '/' ]];
|
||||
do
|
||||
if find "$OPENPILOT_ROOT/launch_openpilot.sh" -maxdepth 1 -mindepth 1 &> /dev/null; then
|
||||
return 0
|
||||
fi
|
||||
OPENPILOT_ROOT="$(readlink -f "$OPENPILOT_ROOT/"..)"
|
||||
done
|
||||
}
|
||||
|
||||
function op_check_openpilot_dir() {
|
||||
echo "Checking for openpilot directory..."
|
||||
if [[ -f "$OPENPILOT_ROOT/launch_openpilot.sh" ]]; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] openpilot found.\n"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e " ↳ [${RED}✗${NC}] openpilot directory not found! Make sure that you are"
|
||||
echo " inside the openpilot directory or specify one with the"
|
||||
echo " --dir option!"
|
||||
return 1
|
||||
}
|
||||
|
||||
function op_check_git() {
|
||||
(set -e
|
||||
|
||||
echo "Checking for git..."
|
||||
if ! command -v "git" > /dev/null 2>&1; then
|
||||
echo -e " ↳ [${RED}✗${NC}] git not found on your system!"
|
||||
return 1
|
||||
else
|
||||
echo -e " ↳ [${GREEN}✔${NC}] git found."
|
||||
fi
|
||||
|
||||
echo "Checking for git lfs files..."
|
||||
if [[ $(file -b $OPENPILOT_ROOT/selfdrive/modeld/models/supercombo.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'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Checking for git submodules..."
|
||||
for name in body msgq_repo opendbc panda rednose_repo tinygrad_repo; do
|
||||
if [[ -z $(ls $OPENPILOT_ROOT/$name) ]]; then
|
||||
echo -e " ↳ [${RED}✗${NC}] git submodule $name not found! Run 'git submodule update --init --recursive'"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
echo -e " ↳ [${GREEN}✔${NC}] git submodules found."
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_check_os() {
|
||||
(set -e
|
||||
|
||||
echo "Checking for compatible os version..."
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
|
||||
if [ -f "/etc/os-release" ]; then
|
||||
source /etc/os-release
|
||||
case "$VERSION_CODENAME" in
|
||||
"jammy" | "kinetic" | "noble" | "focal")
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Ubuntu $VERSION_CODENAME detected."
|
||||
;;
|
||||
* )
|
||||
echo -e " ↳ [${RED}✗${NC}] Incompatible Ubuntu version $VERSION_CODENAME detected!"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo -e " ↳ [${RED}✗${NC}] No /etc/os-release on your system. Make sure you're running on Ubuntu, or similar!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] macos detected.\n"
|
||||
else
|
||||
echo -e " ↳ [${RED}✗${NC}] OS type $OSTYPE not supported!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_check_python() {
|
||||
(set -e
|
||||
|
||||
echo "Checking for compatible python version..."
|
||||
REQUIRED_PYTHON_VERSION=$(grep "requires-python" $OPENPILOT_ROOT/pyproject.toml)
|
||||
INSTALLED_PYTHON_VERSION=$(python3 --version 2> /dev/null || true)
|
||||
|
||||
if [[ -z $INSTALLED_PYTHON_VERSION ]]; then
|
||||
echo -e " ↳ [${RED}✗${NC}] python3 not found on your system. You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!"
|
||||
return 1
|
||||
elif [[ $(echo $INSTALLED_PYTHON_VERSION | tr -d -c '[0-9]') -ge $(($(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9]') * 10)) ]]; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] $INSTALLED_PYTHON_VERSION detected."
|
||||
else
|
||||
echo -e " ↳ [${RED}✗${NC}] You need python version at least $(echo $REQUIRED_PYTHON_VERSION | tr -d -c '[0-9.]') to continue!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_check_venv() {
|
||||
echo "Checking for venv..."
|
||||
if source $OPENPILOT_ROOT/.venv/bin/activate; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] venv detected."
|
||||
else
|
||||
echo -e " ↳ [${RED}✗${NC}] Can't activate venv in $OPENPILOT_ROOT. Assuming global env!"
|
||||
fi
|
||||
}
|
||||
|
||||
function op_before_cmd() {
|
||||
if [[ ! -z "$NO_VERIFY" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
op_get_openpilot_dir
|
||||
cd $OPENPILOT_ROOT
|
||||
|
||||
result="$((op_check_openpilot_dir ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
result="${result}\n$(( op_check_git ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
result="${result}\n$(( op_check_os ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
result="${result}\n$(( op_check_venv ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
|
||||
op_activate_venv
|
||||
|
||||
result="${result}\n$(( op_check_python ) 2>&1)" || (echo -e "$result" && return 1)
|
||||
|
||||
if [[ -z $VERBOSE ]]; then
|
||||
echo -e "Checking system → [${GREEN}✔${NC}] system is good."
|
||||
else
|
||||
echo -e "$result"
|
||||
fi
|
||||
}
|
||||
|
||||
function op_setup() {
|
||||
(set -e
|
||||
|
||||
op_get_openpilot_dir
|
||||
cd $OPENPILOT_ROOT
|
||||
|
||||
op_check_openpilot_dir
|
||||
op_check_os
|
||||
op_check_python
|
||||
|
||||
echo "Installing dependencies..."
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
op_run_command $OPENPILOT_ROOT/tools/ubuntu_setup.sh
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
op_run_command $OPENPILOT_ROOT/tools/mac_setup.sh
|
||||
fi
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Dependencies installed successfully.\n"
|
||||
|
||||
echo "Getting git submodules..."
|
||||
op_run_command git submodule update --init --recursive
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully.\n"
|
||||
|
||||
echo "Pulling git lfs files..."
|
||||
op_run_command git lfs pull
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Files pulled successfully.\n"
|
||||
|
||||
op_check
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_activate_venv() {
|
||||
source $OPENPILOT_ROOT/.venv/bin/activate &> /dev/null || true
|
||||
}
|
||||
|
||||
function op_venv() {
|
||||
( set -e
|
||||
|
||||
op_before_cmd
|
||||
|
||||
)
|
||||
|
||||
if [[ "$?" -eq 0 ]]; then
|
||||
# this must be run in the same shell as the user calling "op"
|
||||
op_get_openpilot_dir
|
||||
op_run_command source $OPENPILOT_ROOT/.venv/bin/activate
|
||||
fi
|
||||
}
|
||||
|
||||
function op_check() {
|
||||
(set -e
|
||||
|
||||
VERBOSE=1
|
||||
op_before_cmd
|
||||
unset VERBOSE
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_build() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command scons $@
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_juggle() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command tools/plotjuggler/juggle.py $@
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_lint() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command pre-commit run --all $@
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_replay() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command tools/replay/replay $@
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_cabana() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command tools/cabana/cabana $@
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_sim() {
|
||||
(set -e
|
||||
|
||||
op_before_cmd
|
||||
op_run_command exec tools/sim/run_bridge.py &
|
||||
op_run_command exec tools/sim/launch_openpilot.sh
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
function op_default() {
|
||||
echo "An openpilot helper"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Description:${NC}"
|
||||
echo " op is your entry point for all things related to openpilot development."
|
||||
echo " op is only a wrapper for existing scripts, tools, and commands."
|
||||
echo " op will always show you what it will run on your system."
|
||||
echo ""
|
||||
echo " op will try to find your openpilot directory in the following order:"
|
||||
echo " 1: use the directory specified with the --dir option"
|
||||
echo " 2: use the current working directory"
|
||||
echo " 3: go up the file tree non-recursively"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Usage:${NC} op [OPTIONS] <COMMAND>"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Commands:${NC}"
|
||||
echo -e " ${BOLD}venv${NC} Activate the Python virtual environment"
|
||||
echo -e " ${BOLD}check${NC} Check the development environment (git, os, python) to start using openpilot"
|
||||
echo -e " ${BOLD}setup${NC} Install openpilot dependencies"
|
||||
echo -e " ${BOLD}build${NC} Build openpilot"
|
||||
echo -e " ${BOLD}sim${NC} Run openpilot in a simulator"
|
||||
echo -e " ${BOLD}juggle${NC} Run Plotjuggler"
|
||||
echo -e " ${BOLD}replay${NC} Run replay"
|
||||
echo -e " ${BOLD}cabana${NC} Run cabana"
|
||||
echo -e " ${BOLD}lint${NC} Run all the pre-commit checks"
|
||||
echo -e " ${BOLD}help${NC} Show this message"
|
||||
echo -e " ${BOLD}install${NC} Install the 'op' tool system wide"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Options:${NC}"
|
||||
echo -e " ${BOLD}-d, --dir${NC}"
|
||||
echo " Specify the openpilot directory you want to use"
|
||||
echo -e " ${BOLD}--dry${NC}"
|
||||
echo " Don't actually run anything, just print what would be run"
|
||||
echo -e " ${BOLD}-n, --no-verify${NC}"
|
||||
echo " Skip environment check before running commands"
|
||||
echo -e " ${BOLD}-v, --verbose${NC}"
|
||||
echo " Show the result of all checks before running a command"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Examples:${NC}"
|
||||
echo " op --dir /tmp/openpilot check"
|
||||
echo " Run the check command on openpilot located in /tmp/openpilot"
|
||||
echo ""
|
||||
echo " op juggle --install"
|
||||
echo " Install plotjuggler in the openpilot located in your current"
|
||||
echo " working directory"
|
||||
echo ""
|
||||
echo " op --dir /tmp/openpilot build -j4"
|
||||
echo " Run the build command on openpilot located in /tmp/openpilot"
|
||||
echo " on 4 cores"
|
||||
}
|
||||
|
||||
|
||||
function _op() {
|
||||
# parse Options
|
||||
case $1 in
|
||||
-d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;;
|
||||
--dry ) shift 1; DRY="1" ;;
|
||||
-n | --no-verify ) shift 1; NO_VERIFY="1" ;;
|
||||
-v | --verbose ) shift 1; VERBOSE="1" ;;
|
||||
esac
|
||||
|
||||
# parse Commands
|
||||
case $1 in
|
||||
venv ) shift 1; op_venv "$@" ;;
|
||||
check ) shift 1; op_check "$@" ;;
|
||||
setup ) shift 1; op_setup "$@" ;;
|
||||
build ) shift 1; op_build "$@" ;;
|
||||
juggle ) shift 1; op_juggle "$@" ;;
|
||||
cabana ) shift 1; op_cabana "$@" ;;
|
||||
lint ) shift 1; op_lint "$@" ;;
|
||||
replay ) shift 1; op_replay "$@" ;;
|
||||
sim ) shift 1; op_sim "$@" ;;
|
||||
install ) shift 1; op_install "$@" ;;
|
||||
* ) op_default "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
_op $@
|
||||
|
||||
# remove from env
|
||||
unset -f _op
|
||||
unset -f op_check
|
||||
unset -f op_setup
|
||||
unset -f op_build
|
||||
unset -f op_juggle
|
||||
unset -f op_venv
|
||||
unset -f op_check_openpilot_dir
|
||||
unset -f op_check_git
|
||||
unset -f op_check_python
|
||||
unset -f op_check_os
|
||||
unset -f op_install
|
||||
unset -f op_default
|
||||
unset -f op_run_command
|
||||
unset -f op_lint
|
||||
unset -f op_replay
|
||||
unset -f op_cabana
|
||||
unset -f op_check_venv
|
||||
unset -f op_before_cmd
|
||||
unset -f op_sim
|
||||
unset -f op_activate_venv
|
||||
unset -f op_get_openpilot_dir
|
||||
unset DRY
|
||||
unset NC
|
||||
unset RED
|
||||
unset GREEN
|
||||
unset UNDERLINE
|
||||
unset BOLD
|
||||
unset OPENPILOT_ROOT
|
||||
unset NO_VERIFY
|
||||
unset VERBOSE
|
||||
@@ -12,8 +12,7 @@ from functools import partial
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.car.fingerprints import MIGRATION
|
||||
from openpilot.tools.lib.helpers import save_log
|
||||
from openpilot.tools.lib.logreader import LogReader, ReadMode
|
||||
from openpilot.tools.lib.logreader import LogReader, ReadMode, save_log
|
||||
|
||||
juggle_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Rerun
|
||||
Rerun is a tool to quickly visualize time series data. It supports all openpilot logs , both the `logMessages` and video logs.
|
||||
|
||||
[Instructions](https://rerun.io/docs/reference/viewer/overview) for navigation within the Rerun Viewer.
|
||||
|
||||
## Usage
|
||||
```
|
||||
usage: run.py [-h] [--demo] [--qcam] [--fcam] [--ecam] [--dcam] [--print_services] [--services [SERVICES ...]] [route_or_segment_name]
|
||||
|
||||
A helper to run rerun on openpilot routes
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--demo Use the demo route instead of providing one (default: False)
|
||||
--qcam Log decimated driving camera (default: False)
|
||||
--fcam Log driving camera (default: False)
|
||||
--ecam Log wide camera (default: False)
|
||||
--dcam Log driver monitoring camera (default: False)
|
||||
--print_services List out openpilot services (default: False)
|
||||
--services [SERVICES ...] Specify openpilot services that will be logged. No service will be logged if not specified.
|
||||
To log all services include 'all' as one of your services (default: [])
|
||||
--route [ROUTE] The route or segment name to plot (default: None)
|
||||
```
|
||||
|
||||
Examples using route name to observe accelerometer and qcamera:
|
||||
|
||||
`./run.py --services accelerometer --qcam --route "a2a0ccea32023010/2023-07-27--13-01-19"`
|
||||
|
||||
Examples using segment range (more on [SegmentRange](https://github.com/commaai/openpilot/tree/master/tools/lib)):
|
||||
|
||||
`./run.py --qcam --route "a2a0ccea32023010/2023-07-27--13-01-19/2:4"`
|
||||
|
||||
## Cautions:
|
||||
- You can specify `--services all` to visualize all `logMessage`, but it will draw a lot of memory usage and take a long time to log all messages. Rerun isn't ready for logging big number of data.
|
||||
|
||||
- Logging hevc videos (`--fcam`, `--ecam`, and `--dcam`) are expensive, and it's recommended to use `--qcam` for optimized performance. If possible, limiting your route to a few segments using `SegmentRange` will speed up logging and reduce memory usage
|
||||
|
||||
This example draws 13GB of memory:
|
||||
|
||||
`./run.py --services accelerometer --qcam --route "a2a0ccea32023010/2023-07-27--13-01-19"`
|
||||
|
||||
|
||||
## Openpilot services
|
||||
To list all openpilot services:
|
||||
|
||||
`./run.py --print_services`
|
||||
|
||||
Examples including openpilot services:
|
||||
|
||||
`./run.py --services accelerometer cameraodometry --route "a2a0ccea32023010/2023-07-27--13-01-19/0/q"`
|
||||
|
||||
Examples including all services:
|
||||
|
||||
`./run.py --services all --route "a2a0ccea32023010/2023-07-27--13-01-19/0/q"`
|
||||
|
||||
## Demo
|
||||
`./run.py --services accelerometer carcontrol caroutput --qcam --demo`
|
||||
@@ -0,0 +1,92 @@
|
||||
import tqdm
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
from enum import StrEnum
|
||||
from functools import partial
|
||||
from collections import namedtuple
|
||||
|
||||
from openpilot.tools.lib.framereader import ffprobe
|
||||
|
||||
CameraConfig = namedtuple("CameraConfig", ["qcam", "fcam", "ecam", "dcam"])
|
||||
|
||||
class CameraType(StrEnum):
|
||||
qcam = "qcamera"
|
||||
fcam = "fcamera"
|
||||
ecam = "ecamera"
|
||||
dcam = "dcamera"
|
||||
|
||||
|
||||
def probe_packet_info(camera_path):
|
||||
args = ["ffprobe", "-v", "quiet", "-show_packets", "-probesize", "10M", camera_path]
|
||||
dat = subprocess.check_output(args)
|
||||
dat = dat.decode().split()
|
||||
return dat
|
||||
|
||||
|
||||
class _FrameReader:
|
||||
def __init__(self, camera_path, segment, h, w, start_time):
|
||||
self.camera_path = camera_path
|
||||
self.segment = segment
|
||||
self.h = h
|
||||
self.w = w
|
||||
self.start_time = start_time
|
||||
|
||||
self.ts = self._get_ts()
|
||||
|
||||
def _read_stream_nv12(self):
|
||||
frame_sz = self.w * self.h * 3 // 2
|
||||
proc = subprocess.Popen(
|
||||
["ffmpeg", "-v", "quiet", "-i", self.camera_path, "-f", "rawvideo", "-pix_fmt", "nv12", "-"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
try:
|
||||
while True:
|
||||
dat = proc.stdout.read(frame_sz)
|
||||
if len(dat) == 0:
|
||||
break
|
||||
yield dat
|
||||
finally:
|
||||
proc.kill()
|
||||
|
||||
def _get_ts(self):
|
||||
dat = probe_packet_info(self.camera_path)
|
||||
try:
|
||||
ret = [float(d.split('=')[1]) for d in dat if d.startswith("pts_time=")]
|
||||
except ValueError:
|
||||
# pts_times aren't available. Infer timestamps from duration_times
|
||||
ret = [d for d in dat if d.startswith("duration_time")]
|
||||
ret = [float(d.split('=')[1])*(i+1)+(self.segment*60)+self.start_time for i, d in enumerate(ret)]
|
||||
return ret
|
||||
|
||||
def __iter__(self):
|
||||
for i, frame in enumerate(self._read_stream_nv12()):
|
||||
yield self.ts[i], frame
|
||||
|
||||
|
||||
class CameraReader:
|
||||
def __init__(self, camera_paths, start_time, seg_idxs):
|
||||
self.seg_idxs = seg_idxs
|
||||
self.camera_paths = camera_paths
|
||||
self.start_time = start_time
|
||||
|
||||
probe = ffprobe(camera_paths[0])["streams"][0]
|
||||
self.h = probe["height"]
|
||||
self.w = probe["width"]
|
||||
|
||||
self.__frs = {}
|
||||
|
||||
def _get_fr(self, i):
|
||||
if i not in self.__frs:
|
||||
self.__frs[i] = _FrameReader(self.camera_paths[i], segment=i, h=self.h, w=self.w, start_time=self.start_time)
|
||||
return self.__frs[i]
|
||||
|
||||
def _run_on_segment(self, func, i):
|
||||
return func(self._get_fr(i))
|
||||
|
||||
def run_across_segments(self, num_processes, func):
|
||||
with multiprocessing.Pool(num_processes) as pool:
|
||||
num_segs = len(self.seg_idxs)
|
||||
for _ in tqdm.tqdm(pool.imap_unordered(partial(self._run_on_segment, func), self.seg_idxs), total=num_segs):
|
||||
continue
|
||||
|
||||
+152
-60
@@ -6,84 +6,176 @@ import rerun as rr
|
||||
import rerun.blueprint as rrb
|
||||
from functools import partial
|
||||
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.tools.rerun.camera_reader import probe_packet_info, CameraReader, CameraConfig, CameraType
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from openpilot.tools.lib.route import Route, SegmentRange
|
||||
|
||||
|
||||
NUM_CPUS = multiprocessing.cpu_count()
|
||||
DEMO_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19"
|
||||
RR_TIMELINE_NAME = "Timeline"
|
||||
RR_WIN = "rerun_test"
|
||||
|
||||
def log_msg(msg, parent_key=''):
|
||||
stack = [(msg, parent_key)]
|
||||
while stack:
|
||||
current_msg, current_parent_key = stack.pop()
|
||||
if isinstance(current_msg, list):
|
||||
for index, item in enumerate(current_msg):
|
||||
new_key = f"{current_parent_key}/{index}"
|
||||
if isinstance(item, (int, float)):
|
||||
rr.log(str(new_key), rr.Scalar(item))
|
||||
elif isinstance(item, dict):
|
||||
stack.append((item, new_key))
|
||||
elif isinstance(current_msg, dict):
|
||||
for key, value in current_msg.items():
|
||||
new_key = f"{current_parent_key}/{key}"
|
||||
if isinstance(value, (int, float)):
|
||||
rr.log(str(new_key), rr.Scalar(value))
|
||||
elif isinstance(value, dict):
|
||||
stack.append((value, new_key))
|
||||
elif isinstance(value, list):
|
||||
for index, item in enumerate(value):
|
||||
if isinstance(item, (int, float)):
|
||||
rr.log(f"{new_key}/{index}", rr.Scalar(item))
|
||||
else:
|
||||
pass # Not a plottable value
|
||||
|
||||
def createBlueprint():
|
||||
blueprint = None
|
||||
timeSeriesViews = []
|
||||
for topic in sorted(SERVICE_LIST.keys()):
|
||||
timeSeriesViews.append(rrb.TimeSeriesView(name=topic, origin=f"/{topic}/", visible=False))
|
||||
rr.log(topic, rr.SeriesLine(name=topic), timeless=True)
|
||||
blueprint = rrb.Blueprint(rrb.Grid(rrb.Vertical(*timeSeriesViews,rrb.SelectionPanel(expanded=False),rrb.TimePanel(expanded=False)),
|
||||
rrb.Spatial2DView(name="thumbnail", origin="/thumbnail")))
|
||||
return blueprint
|
||||
"""
|
||||
Relevant upstream Rerun issues:
|
||||
- large time series: https://github.com/rerun-io/rerun/issues/5967
|
||||
- loading videos directly: https://github.com/rerun-io/rerun/issues/6532
|
||||
"""
|
||||
|
||||
def log_thumbnail(thumbnailMsg):
|
||||
bytesImgData = thumbnailMsg.get('thumbnail')
|
||||
rr.log("/thumbnail", rr.ImageEncoded(contents=bytesImgData))
|
||||
class Rerunner:
|
||||
def __init__(self, route, segment_range, camera_config, enabled_services):
|
||||
self.enabled_services = [s.lower() for s in enabled_services]
|
||||
self.log_all = "all" in self.enabled_services
|
||||
self.lr = LogReader(route_or_segment_name)
|
||||
|
||||
@rr.shutdown_at_exit
|
||||
def process(blueprint, lr):
|
||||
rr.init("rerun_test")
|
||||
rr.connect(default_blueprint=blueprint)
|
||||
# hevc files don't have start_time. We get it from qcamera.ts
|
||||
start_time = 0
|
||||
dat = probe_packet_info(r.qcamera_paths()[0])
|
||||
for d in dat:
|
||||
if d.startswith("pts_time="):
|
||||
start_time = float(d.split('=')[1])
|
||||
break
|
||||
|
||||
qcam, fcam, ecam, dcam = camera_config
|
||||
self.camera_readers = {}
|
||||
if qcam:
|
||||
self.camera_readers[CameraType.qcam] = CameraReader(route.qcamera_paths(), start_time, segment_range.seg_idxs)
|
||||
if fcam:
|
||||
self.camera_readers[CameraType.fcam] = CameraReader(route.camera_paths(), start_time, segment_range.seg_idxs)
|
||||
if ecam:
|
||||
self.camera_readers[CameraType.ecam] = CameraReader(route.ecamera_paths(), start_time, segment_range.seg_idxs)
|
||||
if dcam:
|
||||
self.camera_readers[CameraType.dcam] = CameraReader(route.dcamera_paths(), start_time, segment_range.seg_idxs)
|
||||
|
||||
def _start_rerun(self):
|
||||
self.blueprint = self._create_blueprint()
|
||||
rr.init(RR_WIN, spawn=True)
|
||||
|
||||
def _create_blueprint(self):
|
||||
blueprint = None
|
||||
service_views = []
|
||||
|
||||
log_msg_visible = len(self.enabled_services) <= 3 and not self.log_all
|
||||
for topic in sorted(SERVICE_LIST.keys()):
|
||||
if not self.log_all and topic.lower() not in self.enabled_services:
|
||||
continue
|
||||
View = rrb.TimeSeriesView if topic != "thumbnail" else rrb.Spatial2DView
|
||||
service_views.append(View(name=topic, origin=f"/{topic}/", visible=log_msg_visible))
|
||||
rr.log(topic, rr.SeriesLine(name=topic), timeless=True)
|
||||
|
||||
blueprint = rrb.Blueprint(
|
||||
rrb.Horizontal(
|
||||
rrb.Vertical(*service_views),
|
||||
rrb.Vertical(*[rrb.Spatial2DView(name=cam_type, origin=cam_type) for cam_type in self.camera_readers.keys()]),
|
||||
),
|
||||
rrb.SelectionPanel(expanded=False),
|
||||
rrb.TimePanel(expanded=False)
|
||||
)
|
||||
return blueprint
|
||||
|
||||
@staticmethod
|
||||
def _log_msg(msg, parent_key=''):
|
||||
stack = [(msg, parent_key)]
|
||||
while stack:
|
||||
current_msg, current_parent_key = stack.pop()
|
||||
if isinstance(current_msg, list):
|
||||
for index, item in enumerate(current_msg):
|
||||
new_key = f"{current_parent_key}/{index}"
|
||||
if isinstance(item, (int, float)):
|
||||
rr.log(new_key, rr.Scalar(item))
|
||||
elif isinstance(item, dict):
|
||||
stack.append((item, new_key))
|
||||
elif isinstance(current_msg, dict):
|
||||
for key, value in current_msg.items():
|
||||
new_key = f"{current_parent_key}/{key}"
|
||||
if isinstance(value, (int, float)):
|
||||
rr.log(new_key, rr.Scalar(value))
|
||||
elif isinstance(value, dict):
|
||||
stack.append((value, new_key))
|
||||
elif isinstance(value, list):
|
||||
for index, item in enumerate(value):
|
||||
if isinstance(item, (int, float)):
|
||||
rr.log(f"{new_key}/{index}", rr.Scalar(item))
|
||||
else:
|
||||
pass # Not a plottable value
|
||||
|
||||
@staticmethod
|
||||
@rr.shutdown_at_exit
|
||||
def _process_log_msgs(blueprint, enabled_services, log_all, lr):
|
||||
rr.init(RR_WIN)
|
||||
rr.connect(default_blueprint=blueprint)
|
||||
|
||||
for msg in lr:
|
||||
rr.set_time_nanos(RR_TIMELINE_NAME, msg.logMonoTime)
|
||||
msg_type = msg.which()
|
||||
|
||||
if not log_all and msg_type.lower() not in enabled_services:
|
||||
continue
|
||||
|
||||
if msg_type != "thumbnail":
|
||||
Rerunner._log_msg(msg.to_dict()[msg.which()], msg.which())
|
||||
else:
|
||||
rr.log("/thumbnail", rr.ImageEncoded(contents=msg.to_dict()[msg.which()].get("thumbnail")))
|
||||
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
@rr.shutdown_at_exit
|
||||
def _process_cam_readers(blueprint, cam_type, h, w, fr):
|
||||
rr.init(RR_WIN)
|
||||
rr.connect(default_blueprint=blueprint)
|
||||
|
||||
size_hint = (h, w)
|
||||
for ts, frame in fr:
|
||||
rr.set_time_nanos(RR_TIMELINE_NAME, int(ts * 1e9))
|
||||
rr.log(cam_type, rr.ImageEncoded(contents=frame,format=rr.ImageFormat.NV12(size_hint)))
|
||||
|
||||
def load_data(self):
|
||||
self._start_rerun()
|
||||
if len(self.enabled_services) > 0:
|
||||
self.lr.run_across_segments(NUM_CPUS, partial(self._process_log_msgs, self.blueprint, self.enabled_services, self.log_all))
|
||||
for cam_type, cr in self.camera_readers.items():
|
||||
cr.run_across_segments(NUM_CPUS, partial(self._process_cam_readers, self.blueprint, cam_type, cr.h, cr.w))
|
||||
|
||||
ret = []
|
||||
for msg in lr:
|
||||
ret.append(msg)
|
||||
rr.set_time_nanos("TIMELINE", msg.logMonoTime)
|
||||
if msg.which() != "thumbnail":
|
||||
log_msg(msg.to_dict()[msg.which()], msg.which())
|
||||
else:
|
||||
log_thumbnail(msg.to_dict()[msg.which()])
|
||||
return ret
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description="A helper to run rerun on openpilot routes",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument("--demo", action="store_true", help="Use the demo route instead of providing one")
|
||||
parser.add_argument("route_or_segment_name", nargs='?', help="The route or segment name to plot")
|
||||
parser.add_argument("--qcam", action="store_true", help="Log decimated driving camera")
|
||||
parser.add_argument("--fcam", action="store_true", help="Log driving camera")
|
||||
parser.add_argument("--ecam", action="store_true", help="Log wide camera")
|
||||
parser.add_argument("--dcam", action="store_true", help="Log driver monitoring camera")
|
||||
parser.add_argument("--print_services", action="store_true", help="List out openpilot services")
|
||||
parser.add_argument("--services", default=[], nargs='*', help="Specify openpilot services that will be logged.\
|
||||
No service will be logged if not specified.\
|
||||
To log all services include 'all' as one of your services")
|
||||
parser.add_argument("--route", nargs='?', help="The route or segment name to plot")
|
||||
args = parser.parse_args()
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
if not args.demo and not args.route:
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.print_services:
|
||||
print("\n".join(SERVICE_LIST.keys()))
|
||||
sys.exit()
|
||||
|
||||
blueprint = createBlueprint()
|
||||
rr.init("rerun_test")
|
||||
rr.spawn(connect=False) # child processes stream data to Viewer
|
||||
camera_config = CameraConfig(args.qcam, args.fcam, args.ecam, args.dcam)
|
||||
|
||||
route_or_segment_name = DEMO_ROUTE if args.demo else args.route.strip()
|
||||
sr = SegmentRange(route_or_segment_name)
|
||||
r = Route(sr.route_name)
|
||||
|
||||
if len(sr.seg_idxs) > 10:
|
||||
print("You're requesting more than 10 segments of the route, " + \
|
||||
"please be aware that might take a lot of memory")
|
||||
response = input("Do you wish to continue? (Y/n): ")
|
||||
if response.strip() != "Y":
|
||||
sys.exit()
|
||||
|
||||
rerunner = Rerunner(r, sr, camera_config, args.services)
|
||||
rerunner.load_data()
|
||||
|
||||
route_or_segment_name = DEMO_ROUTE if args.demo else args.route_or_segment_name.strip()
|
||||
print("Getting route log paths")
|
||||
lr = LogReader(route_or_segment_name)
|
||||
lr.run_across_segments(NUM_CPUS, partial(process, blueprint))
|
||||
|
||||
+50
-23
@@ -1,32 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ ! -f launch_openpilot.sh ]; then
|
||||
if [ ! -d openpilot ]; then
|
||||
git clone --single-branch --recurse-submodules https://github.com/commaai/openpilot.git
|
||||
if [ -z "$OPENPILOT_ROOT" ]; then
|
||||
# default to current directory for installation
|
||||
OPENPILOT_ROOT="$(pwd)/openpilot"
|
||||
fi
|
||||
|
||||
function check_dir() {
|
||||
echo "Checking for installation directory..."
|
||||
if [ -d "$OPENPILOT_ROOT" ]; then
|
||||
echo -e " ↳ [${RED}✗${NC}] can't install openpilot in $OPENPILOT_ROOT !"
|
||||
return 1
|
||||
fi
|
||||
cd openpilot
|
||||
fi
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
tools/mac_setup.sh
|
||||
else
|
||||
tools/ubuntu_setup.sh
|
||||
fi
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Successfully chosen $OPENPILOT_ROOT as installation directory\n"
|
||||
}
|
||||
|
||||
git lfs pull
|
||||
function check_git() {
|
||||
echo "Checking for git..."
|
||||
if ! command -v "git" > /dev/null 2>&1; then
|
||||
echo -e " ↳ [${RED}✗${NC}] git not found on your system, can't continue!"
|
||||
return 1
|
||||
else
|
||||
echo -e " ↳ [${GREEN}✔${NC}] git found.\n"
|
||||
fi
|
||||
}
|
||||
|
||||
source .venv/bin/activate
|
||||
function git_clone() {
|
||||
echo "Cloning openpilot..."
|
||||
if $(git clone --filter=blob:none https://github.com/commaai/openpilot.git "$OPENPILOT_ROOT"); then
|
||||
if [[ -f $OPENPILOT_ROOT/launch_openpilot.sh ]]; then
|
||||
echo -e " ↳ [${GREEN}✔${NC}] Successfully cloned openpilot.\n"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Building openpilot"
|
||||
scons -u -j$(nproc)
|
||||
echo -e " ↳ [${RED}✗${NC}] failed to clone openpilot!"
|
||||
return 1
|
||||
}
|
||||
|
||||
echo
|
||||
echo "---- OPENPILOT BUILDING DONE ----"
|
||||
echo "To push changes to your fork, run the following commands:"
|
||||
echo "git remote remove origin"
|
||||
echo "git remote add origin git@github.com:<YOUR_USERNAME>/openpilot.git"
|
||||
echo "git fetch"
|
||||
echo "git commit -m \"first commit\""
|
||||
echo "git push"
|
||||
function install_with_op() {
|
||||
cd $OPENPILOT_ROOT
|
||||
$OPENPILOT_ROOT/tools/op.sh install
|
||||
$OPENPILOT_ROOT/tools/op.sh setup
|
||||
|
||||
# make op usable right now
|
||||
alias op="source $OPENPILOT_ROOT/tools/op.sh \"\$@\""
|
||||
}
|
||||
|
||||
check_dir && check_git && git_clone && install_with_op
|
||||
|
||||
unset OPENPILOT_ROOT
|
||||
unset RED
|
||||
unset GREEN
|
||||
unset NC
|
||||
|
||||
@@ -8,8 +8,3 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
|
||||
$DIR/install_ubuntu_dependencies.sh
|
||||
$DIR/install_python_dependencies.sh
|
||||
|
||||
echo
|
||||
echo "---- OPENPILOT SETUP DONE ----"
|
||||
echo "Open a new shell or configure your active shell env by running:"
|
||||
echo "source ~/.bashrc"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# TODO: remove the cv2 dependency, it's only used here
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
|
||||
@@ -96,15 +96,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "alabaster"
|
||||
version = "0.7.16"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "attrs"
|
||||
version = "23.2.0"
|
||||
@@ -116,22 +107,22 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "av"
|
||||
version = "12.2.0"
|
||||
version = "12.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9e/e2/1c5708feb7ceb46c8ab9d2e3fbd451a725f0741d7c5336020d13be527490/av-12.2.0.tar.gz", hash = "sha256:460670325bbd64b7a6774b6bda05985cbe4582d111f81993bfbb08058f8c0484", size = 3828627 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/f8/5adeeae0c42a7130933d168b8d84a21c98a32cb9fcf9222e2541ed0d9c7b/av-12.3.0.tar.gz", hash = "sha256:04b1892562aff3277efc79f32bd8f1d0cbb64ed011241cb3e96f9ad471816c22", size = 3833953 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/73/08/41200974e40a803da6d008cab7a801d187f950d92efa71182680b419a99a/av-12.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f74c9987798d45302b86e94b3bdb6009e9a509c57971b5599aae4353f5b8c5c0", size = 26057398 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/94/d4383c50b1a819e0edb43637d6cb03086b1fcc563e9c07fc0eb2840c4e2d/av-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d17e4110efe449842d12bc11166141b5ca08ce821b7529f02ed9dc3b73c9291", size = 20871004 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/eb/82b86e8f763dd104a75478a02228465715984e0fe91ae6c7567093bf75a2/av-12.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a7cc709c0c231f282f1b26a76b42d63100a8bc088522cfd06c500ed4b6c660c", size = 33310123 },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/b9/bc306aaae0743004ea0f45a779c35ce0896d284e36e715f383eaf04d3a9c/av-12.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:433589001c309d4ab655f0085b47bcab89e5ddeb6472993d9ef92e05eabbbe8e", size = 32783301 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/50/0014d42a7165dc386bef02cae9de3fd5512daafcf0bae56d3cfc1e880df5/av-12.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:505955d5c2c9b7e0034fad7d0b57df6944adda9e42a606c9964ca5693c9b090d", size = 35224812 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/fd/a1e1f10666e3aa37caed52804e656f525b978591ab69d20fccc6bb35d115/av-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:a9ca519ae6525a88637b73a1adae87235ac9a141a8d0b0c26a75cd4182c12a9f", size = 26827978 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/7e/92107c359b802555f33feef5f60650a433ac084ec5e257134bf26f1ae559/av-12.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f0026b52b9981b15d71f7f09ecd32587d9b99dd350588f8e17ce726662b466c5", size = 26070643 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/9f/7a94c61856e243ecb3aa58ceebbeae5f165862ffb4e8548b497d1d906418/av-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e60a6da4eb5200900b37716dd971676a1dfb8731b53e8f49a3e630b772f5c97", size = 20877075 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/2a/9b02466d6b53581b64c3fb9f6e063e2d83b549bffa7141ba10b0523ad23c/av-12.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d143d10ce726ced812eb0d4834841349027efd082c13d45a42f6914aae402ca6", size = 33536552 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/fe/8b7ec1008f42942f0cb0db1f700bc4d1e862018677c32f4d47331202302e/av-12.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbe1ace6ebaae1de41f3b0412367eec42188a381fae83669d4b18e1340648839", size = 33060022 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/aa/2e74958ebb9dde8b33940fedd7ead406bd52760589cd7bcd9c19dbac3163/av-12.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8280def29f209ce294b0aa5045a66c1027b8ba2ba5b82e1f66e8a910ff1c1120", size = 35549894 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/cc/437ca48e268120abab9634775d0befecee7ed54327c4df2573f2cf9f9d51/av-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:6740ae90ffd7fe6e7439beab6494c966cd46739943d3046ea01021d4bc2b36e6", size = 26829453 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/20/256fa4fc4ef9bb46fdc4be4662e13a30b0334487c955961f3816d94db04b/av-12.3.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:cc06a806419fddc7102150ffe353c7d96b99b95fd12864280c91c851603fd4cb", size = 24658122 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/45/a9d0475539b4f49deb34f3da558de31cefc6be867d5c0603d575a8485069/av-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e2130ff622a574d3d5d6e88ac335efcdd98c375bb341f87d9fe540830a746f5", size = 19923068 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/27/1f2b3e46059c6618fd76ba12a96b49dc8515a426cd477032cd33f80505e8/av-12.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e8b9bd99f916ff4d1278654e94658e6ace7ca60f6321f254d09c8cd81d9095b", size = 32555100 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/34/759741d397a8bdbb8a359b8b5d49832a444b26c9a7f79c0f88be76a6b979/av-12.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e375d1d89a5c6edfd9f66701fdb6cc9161cc1ff99d15ff0bda21ee1ad38e9e0", size = 31936355 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/6e/77426cb92117c941b0f759908bc83f34f259b11b353acb5de95972b452f7/av-12.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9066fd8d86548e12d587cbfe7b852159e48ff3c732271c3032668d4bd7c599", size = 34416598 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/d3/4b0fddcd54d0a88ee7e035f239ebb56ce139fac8e02ee0942c43746a66ff/av-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bfaa9864560e43d45d254ed95f70ab1aab24a2fa0cc35ac99eef362f1453bec0", size = 25975217 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/c1/0636bccf5a1a2c935952614b9d34d8d8aae078c9773a60efb5376702f499/av-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5174e995772ebe33561980dca625f830aea8d39a4338728dedb41ae7dc2605af", size = 24669628 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/7d/9126abdafe20fa73d2c19fd108450363253cfea283c350618cc1434f473c/av-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:028d8b40308536f740dace3efd0178eb96825b414897c9594fb74136532901cb", size = 19928928 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/75/c1b9e0aa4bd0d8b8311f366b6b38f6c6600d66baddfe2888accc7f76b1f5/av-12.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b030791ecc6185776d832d19ce196f61daf3e17e591a9bb6fd181280e1754138", size = 32793461 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/06/1364c445f8a8ab4870f0f5c4530b496257ae09de7fa01b6108525abea8b9/av-12.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3703a35481fda5798a27bf6208c1ec3b61c18931625771fb3c9fd870539c7d7", size = 32217647 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/08/220d5a1ae7e7830d66d041c71e607c1f5df2e3598b12fb406b0d7c2defa7/av-12.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32f3eef56b2df289db6105f9fe2ebc9a8134a8adbd62190daeb8e22c4ff47794", size = 34746451 },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/67/9f1c444864d4f3e3773100b9ed20e670f80d5575b7a8fd53cca20de9d681/av-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:62d036ee8321d67190887012c3dbcd1ad83248603cc29ea75fbb75835b8d6e6e", size = 25977611 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -166,7 +157,7 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "azure-storage-blob"
|
||||
version = "12.20.0"
|
||||
version = "12.21.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "azure-core" },
|
||||
@@ -174,31 +165,9 @@ dependencies = [
|
||||
{ name = "isodate" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1b/0f/86cdaec4be486d12fd5bd2c56e835492a58d3bcd4915d24473e889b70f2c/azure-storage-blob-12.20.0.tar.gz", hash = "sha256:eeb91256e41d4b5b9bad6a87fd0a8ade07dd58aa52344e2c8d2746e27a017d3b", size = 551196 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/97/c9/0e1e864eef8071102de2d6b11dfcf8d35410735145b2fbc2e0a5f58d1490/azure-storage-blob-12.21.0.tar.gz", hash = "sha256:b9722725072f5b7373c0f4dd6d78fbae2bb37bffc5c3e01731ab8c750ee8dd7e", size = 557430 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/15/19/2be26569e708cb618feecd7316ee0c5475273f7cdb4f9030a862870c74c8/azure_storage_blob-12.20.0-py3-none-any.whl", hash = "sha256:de6b3bf3a90e9341a6bcb96a2ebe981dffff993e9045818f6549afea827a52a9", size = 392162 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "babel"
|
||||
version = "2.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/15/d2/9671b93d623300f0aef82cde40e25357f11330bdde91743891b22a555bed/babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413", size = 9390000 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/27/45/377f7e32a5c93d94cd56542349b34efab5ca3f9e2fd5a68c5e93169aa32d/Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb", size = 9634913 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "breathe"
|
||||
version = "4.35.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "docutils" },
|
||||
{ name = "sphinx" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/9f/0c6f4ae0608d5edbb1df357c2487edfcbda13e75f4e48a898972592e2e48/breathe-4.35.0.tar.gz", hash = "sha256:5165541c3c67b6c7adde8b3ecfe895c6f7844783c4076b6d8d287e4f33d62386", size = 83358 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/61/faddc25913de74e60e175bcfd962ec83532653c5895c0a06a83a6b5bbf3d/breathe-4.35.0-py3-none-any.whl", hash = "sha256:52c581f42ca4310737f9e435e3851c3d1f15446205a85fbc272f1f97ed74f5be", size = 92955 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/da/4033cee3855395e84ff73da4b50d3528f9338205299cde89676639387fcc/azure_storage_blob-12.21.0-py3-none-any.whl", hash = "sha256:f9ede187dd5a0ef296b583a7c1861c6938ddd6708d6e70f4203a163c2ab42d43", size = 396449 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -227,6 +196,17 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/88/08/c55e2172f033a44b831ee771bb32fa89c369311c0598a52c03755f29a75e/casadi-3.6.5-cp312-none-win_amd64.whl", hash = "sha256:fe2b64d777e36cc3f101220dd1e219a0e11c3e4ee2b5e708b30fea9a27107e41", size = 43057681 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "casadi"
|
||||
version = "3.6.6"
|
||||
source = { url = "https://github.com/commaai/casadi/releases/download/nightly-release-3.6.6/casadi-3.6.6-cp312-none-manylinux2014_aarch64.whl" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
wheels = [
|
||||
{ url = "https://github.com/commaai/casadi/releases/download/nightly-release-3.6.6/casadi-3.6.6-cp312-none-manylinux2014_aarch64.whl", hash = "sha256:06a15e0099657b960620a2491e565c7f126030018da80c39f6bd33439160c669" },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "certifi"
|
||||
version = "2024.7.4"
|
||||
@@ -439,36 +419,31 @@ sdist = { url = "https://files.pythonhosted.org/packages/6b/b0/e595ce2a2527e169c
|
||||
|
||||
[[distribution]]
|
||||
name = "cryptography"
|
||||
version = "42.0.8"
|
||||
version = "43.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/93/a7/1498799a2ea06148463a9a2c10ab2f6a921a74fb19e231b27dc412a748e2/cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2", size = 671250 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/ec/9fb9dcf4f91f0e5e76de597256c43eedefd8423aa59be95c70c4c3db426a/cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e", size = 686873 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/8b/1b929ba8139430e09e140e6939c2b29c18df1f2fc2149e41bdbdcdaf5d1f/cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e", size = 5899961 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/5d/31d833daa800e4fab33209843095df7adb4a78ea536929145534cbc15026/cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d", size = 3114353 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/32/f6326c70a9f0f258a201d3b2632bca586ea24d214cec3cf36e374040e273/cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902", size = 3647773 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/66/2d87e9ca95c82c7ee5f2c09716fc4c4242c1ae6647b9bd27e55e920e9f10/cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801", size = 3839763 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/de/8083fa2e68d403553a01a9323f4f8b9d7ffed09928ba25635c29fb28c1e7/cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949", size = 3632661 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/40/d6f6819c62e808ea74639c3c640f7edd636b86cce62cb14943996a15df92/cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9", size = 3851536 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/46/de71d48abf2b6d3c808f4fbb0f4dc44a4e72786be23df0541aa2a3f6fd7e/cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583", size = 3754209 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/c9/86f04e150c5d5d5e4a731a2c1e0e43da84d901f388e3fea3d5de98d689a7/cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7", size = 3923551 },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/c2/903014dafb7271fb148887d4355b2e90319cad6e810663be622b0c933fc9/cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b", size = 3739265 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/26/82d704d988a193cbdc69ac3b41c687c36eaed1642cce52530ad810c35645/cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7", size = 3937371 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/71/4e0d05c9acd638a225f57fb6162aa3d03613c11b76893c23ea4675bb28c5/cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2", size = 2438849 },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/0f/78da3cad74f2ba6c45321dc90394d70420ea846730dc042ef527f5a224b5/cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba", size = 2889090 },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/12/f064af29190cdb1d38fe07f3db6126091639e1dece7ec77c4ff037d49193/cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28", size = 5901232 },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/c2/4a3eef67e009a522711ebd8ac89424c3a7fe591ece7035d964419ad52a1d/cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e", size = 3648711 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/1c/9f6d13cc8041c05eebff1154e4e71bedd1db8e174fff999054435994187a/cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70", size = 3841968 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/f9/c3d4f19b82bdb25a3d857fe96e7e571c981810e47e3f299cc13ac429066a/cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c", size = 3633032 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/e2/b7e6e8c261536c489d9cf908769880d94bd5d9a187e166b0dc838d2e6a56/cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7", size = 3852478 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/68/e16751f6b859bc120f53fddbf3ebada5c34f0e9689d8af32884d8b2e4b4c/cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e", size = 3754102 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/38/85c74d0ac4c540780e072b1e6f148ecb718418c1062edcb20d22f3ec5bbb/cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961", size = 3925042 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/f4/a8b982e88eb5350407ebdbf4717b55043271d878705329e107f4783555f2/cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1", size = 3738833 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/2b/be327b580645927bb1a1f32d5a175b897a9b956bc085b095e15c40bac9ed/cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14", size = 3938751 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/d5/c6a78ffccdbe4516711ebaa9ed2c7eb6ac5dfa3dc920f2c7e920af2418b0/cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c", size = 2439281 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/7b/b0d330852dd5953daee6b15f742f15d9f18e9c0154eb4cfcc8718f0436da/cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a", size = 2886038 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/46/dcd2eb6840b9452e7fbc52720f3dc54a85eb41e68414733379e8f98e3275/cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74", size = 6239718 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/23/b0713319edff1d8633775b354f8b34a476e4dd5f4cd4b91e488baec3361a/cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895", size = 3808466 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/9d/0b98c73cebfd41e4fb0439fe9ce08022e8d059f51caa7afc8934fc1edcd9/cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22", size = 3998060 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/71/e073795d0d1624847f323481f7d84855f699172a632aa37646464b0e1712/cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47", size = 3792596 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/25/439a8ddd8058e7f898b7d27c36f94b66c8c8a2d60e1855d725845f4be0bc/cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf", size = 4008355 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/a2/1607f1295eb2c30fcf2c07d7fd0c3772d21dcdb827de2b2730b02df0af51/cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55", size = 3899133 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/64/f41f42ddc9c583737c9df0093affb92c61de7d5b0d299bf644524afe31c1/cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431", size = 4096946 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/cd/d165adcf3e707d6a049d44ade6ca89973549bed0ab3686fa49efdeefea53/cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc", size = 2616826 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/b7/38924229e84c41b0e88d7a5eed8a29d05a44364f85fbb9ddb3984b746fd2/cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778", size = 3078700 },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/d7/397515233e6a861f921bd0365b162b38e0cc513fcf4f1bdd9cc7bc5a3384/cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66", size = 6242814 },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/aa/99b2c00a4f54c60d210d6d1759c720ecf28305aa32d6fb1bb1853f415be6/cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5", size = 3809467 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/eb/ab783b47b3b9b55371b4361c7ec695144bde1a3343ff2b7a8c1d8fe617bb/cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e", size = 3998617 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/62/62770f34290ebb1b6542bd3f13b3b102875b90aed4804e296f8d2a5ac6d7/cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5", size = 3794003 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/6c/b42660b3075ff543065b2c1c5a3d9bedaadcff8ebce2ee981be2babc2934/cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f", size = 4008774 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/74/028cea86db9315ba3f991e307adabf9f0aa15067011137c38b2fb2aa16eb/cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0", size = 3900098 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/f6/e4387edb55563e2546028ba4c634522fe727693d3cdd9ec0ecacedc75411/cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b", size = 4096867 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/61/55560405e75432bdd9f6cf72fa516cab623b83a3f6d230791bc8fc4afeee/cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf", size = 2616481 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/3d/696e7a0f04555c58a2813d47aaa78cb5ba863c1f453c74a4f45ae772b054/cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709", size = 3081462 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -532,15 +507,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "docutils"
|
||||
version = "0.21.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "ewmhlib"
|
||||
version = "0.2"
|
||||
@@ -832,15 +798,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "imagesize"
|
||||
version = "1.4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "import-linter"
|
||||
version = "2.0"
|
||||
@@ -857,14 +814,14 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "importlib-metadata"
|
||||
version = "8.0.0"
|
||||
version = "8.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "zipp" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/20/ff/bd28f70283b9cca0cbf0c2a6082acbecd822d1962ae7b2a904861b9965f8/importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812", size = 52667 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/a1/db39a513aa99ab3442010a994eef1cb977a436aded53042e69bee6959f74/importlib_metadata-8.2.0.tar.gz", hash = "sha256:72e8d4399996132204f9a16dcc751af254a48f8d1b20b9ff0f98d4a8f901e73d", size = 53907 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/ef/38766b2edb096260d9b1b6ad35adaa0bce3b0567abb452b21eb074af88c4/importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f", size = 24769 },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/47/bb25ec04985d0693da478797c3d8c1092b140f3a53ccb984fbbd38affa5b/importlib_metadata-8.2.0-py3-none-any.whl", hash = "sha256:11901fa0c2f97919b288679932bb64febaeacf289d18ac84dd68cb2e74213369", size = 25920 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -1053,23 +1010,11 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "markdown"
|
||||
version = "3.6"
|
||||
version = "3.3.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/22/02/4785861427848cc11e452cc62bb541006a1087cf04a1de83aedd5530b948/Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224", size = 354715 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d6/58/79df20de6e67a83f0d0bbfe6c19bb82adf68cdf362885257eb01099f930a/Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874", size = 324130 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/b3/0c0c994fe49cd661084f8d5dc06562af53818cc0abefaca35bdc894577c3/Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f", size = 105381 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "markdown-it-py"
|
||||
version = "3.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mdurl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/df/ca72f352e15b6f8ce32b74af029f1189abffb906f7c137501ffe69c98a65/Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621", size = 97778 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -1131,27 +1076,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/31/aeab8a3db1fb22a7d04c5215f872b92451baf7f6595ffd59004aeead0b2c/matplotlib-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7", size = 7974774 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mdit-py-plugins"
|
||||
version = "0.4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markdown-it-py" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/6c/79c52651b22b64dba5c7bbabd7a294cc410bfb2353250dc8ade44d7d8ad8/mdit_py_plugins-0.4.1.tar.gz", hash = "sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c", size = 42713 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/f7/8a4dcea720a581e69ac8c5a38524baf0e3e2bb5f3819a9ff661464fe7d10/mdit_py_plugins-0.4.1-py3-none-any.whl", hash = "sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a", size = 54794 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mergedeep"
|
||||
version = "1.3.4"
|
||||
@@ -1190,9 +1114,18 @@ dependencies = [
|
||||
{ name = "yapf" },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mistletoe"
|
||||
version = "1.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/11/96/ea46a376a7c4cd56955ecdfff0ea68de43996a4e6d1aee4599729453bd11/mistletoe-1.4.0.tar.gz", hash = "sha256:1630f906e5e4bbe66fdeb4d29d277e2ea515d642bb18a9b49b136361a9818c9d", size = 107203 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/0f/b5e545f0c7962be90366af3418989b12cf441d9da1e5d89d88f2f3e5cf8f/mistletoe-1.4.0-py3-none-any.whl", hash = "sha256:44a477803861de1237ba22e375c6b617690a31d2902b47279d1f8f7ed498a794", size = 51304 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mkdocs"
|
||||
version = "1.6.0"
|
||||
version = "1.4.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
@@ -1200,32 +1133,29 @@ dependencies = [
|
||||
{ name = "ghp-import" },
|
||||
{ name = "jinja2" },
|
||||
{ name = "markdown" },
|
||||
{ name = "markupsafe" },
|
||||
{ name = "mergedeep" },
|
||||
{ name = "mkdocs-get-deps" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pathspec" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "pyyaml-env-tag" },
|
||||
{ name = "watchdog" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cc/6b/26b33cc8ad54e8bc0345cddc061c2c5c23e364de0ecd97969df23f95a673/mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512", size = 3888392 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b0/ef/49b4427e5eec761b77a3c3c421d3fd63010e2798b7401dc0fa2b875ef6b5/mkdocs-1.4.3.tar.gz", hash = "sha256:5955093bbd4dd2e9403c5afaf57324ad8b04f16886512a3ee6ef828956481c57", size = 3624951 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/c0/930dcf5a3e96b9c8e7ad15502603fc61d495479699e2d2c381e3d37294d1/mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7", size = 3862264 },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/7a/5ed794942ace9d00bb77a8036c64c999cda6ebaab57e9b8a6ec1aa5fc900/mkdocs-1.4.3-py3-none-any.whl", hash = "sha256:6ee46d309bda331aac915cd24aab882c179a933bd9e77b80ce7d2eaaa3f689dd", size = 3654464 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mkdocs-get-deps"
|
||||
version = "0.2.0"
|
||||
name = "mkdocs-plugin-commonmark"
|
||||
version = "0.0.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mergedeep" },
|
||||
{ name = "platformdirs" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "markdown" },
|
||||
{ name = "mistletoe" },
|
||||
{ name = "mkdocs" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fa/a1/4aaa744deec61d75dbe3c67c18f6e4c1fa7699bc2661b6eff5f891e83023/mkdocs-plugin-commonmark-0.0.4.tar.gz", hash = "sha256:9034507af26646e95188a130782dd07d65c86507fddd3b47ea340c02683e85e7", size = 10805 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/4a/4333ef1eb57ff130c7715ba0847dbdae471d153d94507004c92c591cb3c5/mkdocs_plugin_commonmark-0.0.4-py3-none-any.whl", hash = "sha256:70a33394d86a04ec97877ca1b2dff6181de3ec01ef4c7add178fa45b327da535", size = 12532 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -1255,19 +1185,6 @@ dependencies = [
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850 }
|
||||
|
||||
[[distribution]]
|
||||
name = "mpld3"
|
||||
version = "0.5.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "jinja2" },
|
||||
{ name = "matplotlib" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/90/58/19378f4189a034eb3efc17b133426b8551af1d3b2c70d641a63124579629/mpld3-0.5.10.tar.gz", hash = "sha256:a478eb404fa5212505c59133cf272cd9a94105872e605597720e7f84de38fbc7", size = 1027709 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/95/6a/e3691bcc47485f38b09853207c928130571821d187cf174eed5418d45e82/mpld3-0.5.10-py3-none-any.whl", hash = "sha256:80877acce87ea447380fad7374668737505c8c0684aab05238e7c5dc1fab38c1", size = 202561 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "mpmath"
|
||||
version = "1.3.0"
|
||||
@@ -1279,17 +1196,16 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "msal"
|
||||
version = "1.29.0"
|
||||
version = "1.30.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cryptography" },
|
||||
{ name = "pyjwt" },
|
||||
{ name = "pyjwt", extra = "crypto" },
|
||||
{ name = "pyjwt", extra = ["crypto"] },
|
||||
{ name = "requests" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/39/d8/438af3c52f48bab135edbd47f24447c4985ec81c122ebf36e027621f6742/msal-1.29.0.tar.gz", hash = "sha256:8f6725f099752553f9b2fe84125e2a5ebe47b49f92eacca33ebedd3a9ebaae25", size = 140817 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/03/ce/45b9af8f43fbbf34d15162e1e39ce34b675c234c56638277cc05562b6dbf/msal-1.30.0.tar.gz", hash = "sha256:b4bf00850092e465157d814efa24a18f788284c9a479491024d62903085ea2fb", size = 142510 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/a7/5b51016902118052a1342e073138a319b758020cd66f3ee79a7e98e56d62/msal-1.29.0-py3-none-any.whl", hash = "sha256:6b301e63f967481f0cc1a3a3bac0cf322b276855bc1b0955468d9deb3f33d511", size = 110860 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/82/8f19334da43b7ef72d995587991a446f140346d76edb96a2c1a2689588e9/msal-1.30.0-py3-none-any.whl", hash = "sha256:423872177410cb61683566dc3932db7a76f661a5d2f6f52f02a047f101e1c1de", size = 111760 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -1346,25 +1262,25 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "mypy"
|
||||
version = "1.10.1"
|
||||
version = "1.11.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mypy-extensions" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/b9/81e4c6dbb1ec1e72503de3ff2c5fe4b7f224e04613b670f8b9004cd8a4dd/mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0", size = 3022304 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/95/a6dbb4fef19402c488b001ff4bd9f1a770e44049ce049b904dcffc65356c/mypy-1.11.0.tar.gz", hash = "sha256:93743608c7348772fdc717af4aeee1997293a1ad04bc0ea6efa15bf65385c538", size = 3078260 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/38/cf/0645128c6edf70eb9b9687ad42fcb61ea344a7927ed2b78ce2275282fe87/mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a", size = 10740526 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/c9/10842953066265e6063c41a85bbee3b877501947c970ea84a1db5f11d32e/mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84", size = 9898375 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/9e/551e897f67c5d67aa1976bc3b4951f297d1daf07250c421bb045b2613350/mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f", size = 12602338 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/a4/55e3635253e5fa7051674dd5a67582f08b0ba8823e1fdbf7241ed5b32d4e/mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b", size = 12680741 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/cc/aa881ad051f99915887db0b5de8facc0e224295be22f92178c8f77fd8359/mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e", size = 9393661 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/86/3c3bdaccc3cbd1372acb15667a2c2cb773523a710a22e2748cbda9a7c1e2/mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7", size = 10864022 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/05/7c87b26b6a769b70f6c0b8a6daef01fc6f3ae566df89a2fa9d04f690b0d3/mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3", size = 9857795 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/b5/cbccba4dca9703c4c467171e7f61ea6a1a75eae991208aa5bc7d49807f91/mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e", size = 12647633 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/3c/1f5e57c8cfab4299f7189821ae8bb4896e8e623a04d293fd32e32eb0e617/mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04", size = 12730251 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/20/d33608e8dc3bc0f5966fc1f6c2d16671f0725dcca279beec47c3e19afd9d/mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31", size = 9491734 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/ee/d53a3d4792a09b6cd757978951d6dcf8b10825a8b8522b68e9b5eb53b9a1/mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a", size = 2580108 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/69/728aca603433e52b7d2d659678f47562fead09106686a28967d978ef50b8/mypy-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98790025861cb2c3db8c2f5ad10fc8c336ed2a55f4daf1b8b3f877826b6ff2eb", size = 10872601 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/fd/ba4064c7c0e3c650ef496bf6f41785eaa9091532f0ddffe47186ae24db08/mypy-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25bcfa75b9b5a5f8d67147a54ea97ed63a653995a82798221cca2a315c0238c1", size = 10034398 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/43/ef3b86ac6899dc211bb1dbef79df589991e0155cc9ac05925b44fc676d86/mypy-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bea2a0e71c2a375c9fa0ede3d98324214d67b3cbbfcbd55ac8f750f85a414e3", size = 12418537 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/3e/db067303af93fdc532b784b719e887d69d26a13ff52477c65304555c3198/mypy-1.11.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d2b3d36baac48e40e3064d2901f2fbd2a2d6880ec6ce6358825c85031d7c0d4d", size = 12895138 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/56/a1ac65714ee33a35d9f1b6173b8c989c05120cb386dbbe6709ba4cc7a9e4/mypy-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8e2e43977f0e09f149ea69fd0556623919f816764e26d74da0c8a7b48f3e18a", size = 9562630 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/f2/656171fddcfc81527f6c1a8c9550896999e7f7da9606aae1ffde2518f0c7/mypy-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1d44c1e44a8be986b54b09f15f2c1a66368eb43861b4e82573026e04c48a9e20", size = 11002476 },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/c9/a906c097dddacbcc52068196db1f3c6ecf636b039dd002baf9ffe6904e99/mypy-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cea3d0fb69637944dd321f41bc896e11d0fb0b0aa531d887a6da70f6e7473aba", size = 10001386 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/3a/9cb76b2fca4fb4a3aafa9f6f487c873360f3c6a1b2d05fedaa19ba681f28/mypy-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a83ec98ae12d51c252be61521aa5731f5512231d0b738b4cb2498344f0b840cd", size = 12505911 },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/87/47fe67de644f2eefce265425742e439206653c7d7abf589a9db7adda2c16/mypy-1.11.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7b73a856522417beb78e0fb6d33ef89474e7a622db2653bc1285af36e2e3e3d", size = 12952479 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/80/aa7b8d066bce6fe07f9b7fab2e557f428e22eff417481ffe065378275402/mypy-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:f2268d9fcd9686b61ab64f077be7ffbc6fbcdfb4103e5dd0cc5eaab53a8886c2", size = 9662673 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/0e/fc28db5d225623cbbca54d9f4207a3ebf4937d816ba4b61aa3a5ad2af2e7/mypy-1.11.0-py3-none-any.whl", hash = "sha256:56913ec8c7638b0091ef4da6fcc9136896914a9d60d54670a75880c3e5b99ace", size = 2619149 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -1376,23 +1292,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "myst-parser"
|
||||
version = "3.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "docutils" },
|
||||
{ name = "jinja2" },
|
||||
{ name = "markdown-it-py" },
|
||||
{ name = "mdit-py-plugins" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "sphinx" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/49/64/e2f13dac02f599980798c01156393b781aec983b52a6e4057ee58f07c43a/myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87", size = 92392 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", size = 83163 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "natsort"
|
||||
version = "8.4.0"
|
||||
@@ -1525,7 +1424,8 @@ source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
{ name = "aiortc" },
|
||||
{ name = "casadi" },
|
||||
{ name = "casadi", version = "3.6.5", source = { registry = "https://pypi.org/simple" }, marker = "python_version < '3.12' or python_version > '3.12' or platform_machine != 'aarch64'" },
|
||||
{ name = "casadi", version = "3.6.6", source = { url = "https://github.com/commaai/casadi/releases/download/nightly-release-3.6.6/casadi-3.6.6-cp312-none-manylinux2014_aarch64.whl" }, marker = "python_version == '3.12' and platform_machine == 'aarch64'" },
|
||||
{ name = "cffi" },
|
||||
{ name = "crcmod" },
|
||||
{ name = "cython" },
|
||||
@@ -1561,7 +1461,6 @@ dev = [
|
||||
{ name = "av" },
|
||||
{ name = "azure-identity" },
|
||||
{ name = "azure-storage-blob" },
|
||||
{ name = "breathe" },
|
||||
{ name = "control" },
|
||||
{ name = "dictdiffer" },
|
||||
{ name = "flaky" },
|
||||
@@ -1570,15 +1469,12 @@ dev = [
|
||||
{ name = "lru-dict" },
|
||||
{ name = "matplotlib" },
|
||||
{ name = "metadrive-simulator", marker = "platform_machine != 'aarch64'" },
|
||||
{ name = "mpld3" },
|
||||
{ name = "myst-parser" },
|
||||
{ name = "natsort" },
|
||||
{ name = "opencv-python-headless" },
|
||||
{ name = "parameterized" },
|
||||
{ name = "pyautogui" },
|
||||
{ name = "pyopencl", marker = "platform_machine != 'aarch64'" },
|
||||
{ name = "pyprof2calltree" },
|
||||
{ name = "pyqt5", marker = "platform_machine == 'x86_64'" },
|
||||
{ name = "pytools", marker = "platform_machine != 'aarch64'" },
|
||||
{ name = "pywinctl" },
|
||||
{ name = "rerun-sdk" },
|
||||
{ name = "tabulate" },
|
||||
@@ -1588,7 +1484,9 @@ dev = [
|
||||
docs = [
|
||||
{ name = "jinja2" },
|
||||
{ name = "mkdocs" },
|
||||
{ name = "mkdocs-plugin-commonmark" },
|
||||
{ name = "mkdocs-terminal" },
|
||||
{ name = "natsort" },
|
||||
]
|
||||
testing = [
|
||||
{ name = "coverage" },
|
||||
@@ -1699,15 +1597,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/31/13/fe468c8c7400a8eca204e6e160a29bf7dcd45a76e20f1c030f3eaa690d93/parameterized-0.8.1-py2.py3-none-any.whl", hash = "sha256:9cbb0b69a03e8695d68b3399a8a5825200976536fe1cb79db60ed6a4c8c9efe9", size = 26354 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "pillow"
|
||||
version = "10.4.0"
|
||||
@@ -1834,27 +1723,27 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "pyarrow"
|
||||
version = "16.1.0"
|
||||
version = "17.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "numpy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1a/f2/67533f116deb6dae7a0ac04681695fe06135912253a115c5ecdc714a32d4/pyarrow-16.1.0.tar.gz", hash = "sha256:15fbb22ea96d11f0b5768504a3f961edab25eaf4197c341720c4a387f6c60315", size = 1080280 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/27/4e/ea6d43f324169f8aec0e57569443a38bab4b398d09769ca64f7b4d467de3/pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28", size = 1112479 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/28/17/a12aaddb818b7b73d17f3304afc22bce32ccb26723b507cc9c267aa809f3/pyarrow-16.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d0ebea336b535b37eee9eee31761813086d33ed06de9ab6fc6aaa0bace7b250c", size = 28380406 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/94/4e2a579bbac1adb19e63b054b300f6f7fa04f32f212ce86c18727bdda698/pyarrow-16.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e73cfc4a99e796727919c5541c65bb88b973377501e39b9842ea71401ca6c1c", size = 26040531 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/34/d5b6eb5066553533dd6eb9782d50f353f8c6451ee2e49e0ea54d0e67bc34/pyarrow-16.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9251264247ecfe93e5f5a0cd43b8ae834f1e61d1abca22da55b20c788417f6", size = 38666685 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/34/4e3c04e7398764e56ef00f8f267f8ebf565808478f5fee850cef4be670c3/pyarrow-16.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf5aace92d520d3d2a20031d8b0ec27b4395cab9f74e07cc95edf42a5cc0147", size = 40949577 },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/62/b446ee0971b00e7437b9c54a8409ae20413235a64c0a301d7cf97070cffa/pyarrow-16.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:25233642583bf658f629eb230b9bb79d9af4d9f9229890b3c878699c82f7d11e", size = 38077480 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/15/48a68b30542a0231a75c26d8661bc5c9bbc07b42c5b219e929adba814ba7/pyarrow-16.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a33a64576fddfbec0a44112eaf844c20853647ca833e9a647bfae0582b2ff94b", size = 40821141 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/4d/62a09116ec357ade462fac4086e0711457a87177bea25ae46b25897d6d7c/pyarrow-16.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:185d121b50836379fe012753cf15c4ba9638bda9645183ab36246923875f8d1b", size = 25889334 },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/bd/d5903125e38c33b74f7b3d57ffffd4ef48145208cfd8742367f12effb59c/pyarrow-16.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:2e51ca1d6ed7f2e9d5c3c83decf27b0d17bb207a7dea986e8dc3e24f80ff7d6f", size = 28372822 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/73/560ef6bf05f16305502b8e368c771e8f82d774898b37a3fb231f89c13342/pyarrow-16.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a", size = 26004052 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/5e/3cd956aceb1c960e8ac6fdc6eea69d642aa2e6ee10e2f10ce7815dbf62a9/pyarrow-16.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b04707f1979815f5e49824ce52d1dceb46e2f12909a48a6a753fe7cafbc44a0c", size = 38660648 },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/4a/668e7fb6bc564e5361097f1f160b2891ca40bcacfe018638e2841073ec3d/pyarrow-16.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d32000693deff8dc5df444b032b5985a48592c0697cb6e3071a5d59888714e2", size = 40961053 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/8f/a51a290a855172514b8496c8a74f0e0b98e5e0582d44ae7547cf68dd033b/pyarrow-16.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8785bb10d5d6fd5e15d718ee1d1f914fe768bf8b4d1e5e9bf253de8a26cb1628", size = 38060675 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/7b/8da91f8de0b40b760dd748031973b6ac2aa3d4f85c67f45b7e58577ca22e/pyarrow-16.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e1369af39587b794873b8a307cc6623a3b1194e69399af0efd05bb202195a5a7", size = 40826735 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/2b/a0053f1304586f2976cb2c37ddb0e52cf4114220e805ebba272a1e231ccc/pyarrow-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:febde33305f1498f6df85e8020bca496d0e9ebf2093bab9e0f65e2b4ae2b3444", size = 25838156 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/46/ce89f87c2936f5bb9d879473b9663ce7a4b1f4359acc2f0eb39865eaa1af/pyarrow-17.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977", size = 29028748 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/8e/ce2e9b2146de422f6638333c01903140e9ada244a2a477918a368306c64c/pyarrow-17.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3", size = 27190965 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/c8/5675719570eb1acd809481c6d64e2136ffb340bc387f4ca62dce79516cea/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15", size = 39269081 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/78/3931194f16ab681ebb87ad252e7b8d2c8b23dad49706cadc865dff4a1dd3/pyarrow-17.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597", size = 39864921 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/81/69b6606093363f55a2a574c018901c40952d4e902e670656d18213c71ad7/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420", size = 38740798 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/21/9ca93b84b92ef927814cb7ba37f0774a484c849d58f0b692b16af8eebcfb/pyarrow-17.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4", size = 39871877 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/d1/63a7c248432c71c7d3ee803e706590a0b81ce1a8d2b2ae49677774b813bb/pyarrow-17.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03", size = 25151089 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/62/ce6ac1275a432b4a27c55fe96c58147f111d8ba1ad800a112d31859fae2f/pyarrow-17.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22", size = 29019418 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/0a/dbd0c134e7a0c30bea439675cc120012337202e5fac7163ba839aa3691d2/pyarrow-17.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053", size = 27152197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/05/3f4a16498349db79090767620d6dc23c1ec0c658a668d61d76b87706c65d/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a", size = 39263026 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/0c/ea2107236740be8fa0e0d4a293a095c9f43546a2465bb7df34eee9126b09/pyarrow-17.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc", size = 39880798 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/b0/b9164a8bc495083c10c281cc65064553ec87b7537d6f742a89d5953a2a3e/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a", size = 38715172 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/c4/9625418a1413005e486c006e56675334929fad864347c5ae7c1b2e7fe639/pyarrow-17.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b", size = 39874508 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/49/baafe2a964f663413be3bd1cf5c45ed98c5e42e804e2328e18f4570027c1/pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7", size = 25099235 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -2036,15 +1925,15 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "pymdown-extensions"
|
||||
version = "10.8.1"
|
||||
version = "10.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markdown" },
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/09/11/0a1da270c1011194a6efee7ec1ac07d8b75a9706eed4a80675403f6a9d70/pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940", size = 812097 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/85/71/5f48080bde77b07ca1eba6d7cb5c5598ac6c8f2a399846159b3c8b45e171/pymdown_extensions-10.4.tar.gz", hash = "sha256:bc46f11749ecd4d6b71cf62396104b4a200bad3498cb0f5dad1b8502fe461a35", size = 785151 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/d7/e19f9bee2729a8d65b9bf822bb69ac364bf782bac8d761c62b4252769ae0/pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb", size = 250833 },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/2d/2929de81618c7213176899dd6372d6ec9c8f24337841dd74634fb69864ae/pymdown_extensions-10.4-py3-none-any.whl", hash = "sha256:cfc28d6a09d19448bcbf8eee3ce098c7d17ff99f7bd3069db4819af181212037", size = 240838 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -4581,14 +4470,14 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "pyopenssl"
|
||||
version = "24.1.0"
|
||||
version = "24.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cryptography" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/91/a8/cbeec652549e30103b9e6147ad433405fdd18807ac2d54e6dbb73184d8a1/pyOpenSSL-24.1.0.tar.gz", hash = "sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f", size = 179671 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5d/70/ff56a63248562e77c0c8ee4aefc3224258f1856977e0c1472672b62dadb8/pyopenssl-24.2.1.tar.gz", hash = "sha256:4247f0dbe3748d560dcbb2ff3ea01af0f9a1a001ef5f7c4c647956ed8cbf0e95", size = 184323 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/a7/2104f674a5a6845b04c8ff01659becc6b8978ca410b82b94287e0b1e018b/pyOpenSSL-24.1.0-py3-none-any.whl", hash = "sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad", size = 56945 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/dd/e0aa7ebef5168c75b772eda64978c597a9129b46be17779054652a7999e4/pyOpenSSL-24.2.1-py3-none-any.whl", hash = "sha256:967d5719b12b243588573f39b0c677637145c7a1ffedcd495a487e58177fbb8d", size = 58390 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -4699,7 +4588,7 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "pytest"
|
||||
version = "8.2.2"
|
||||
version = "8.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
@@ -4707,21 +4596,21 @@ dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a6/58/e993ca5357553c966b9e73cb3475d9c935fe9488746e13ebdf9b80fae508/pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977", size = 1427980 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", size = 1439314 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", size = 339873 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.23.7"
|
||||
version = "0.23.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/13/d9/1dcac9b3fc6eccf8f1e3a657439c11ffc5cf762edd20f65577f832ba248b/pytest_asyncio-0.23.7.tar.gz", hash = "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268", size = 46296 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/de/b4/0b378b7bf26a8ae161c3890c0b48a91a04106c5713ce81b4b080ea2f4f18/pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3", size = 46920 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/98/947690b1a79af83e584143cb904497caff05bb6016614b38326a81076357/pytest_asyncio-0.23.7-py3-none-any.whl", hash = "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b", size = 17585 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2", size = 17663 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -4788,15 +4677,15 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "pytest-subtests"
|
||||
version = "0.13.0"
|
||||
version = "0.13.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "attrs" },
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/95/be/cebc1b9f6358d174443f46737979e244048a385fe2b0be6fab2b96771dc5/pytest_subtests-0.13.0.tar.gz", hash = "sha256:9e02b9d243c0379b02abf3e0887da122bcb2714b021c3608a37f17ce210adce5", size = 15842 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/67/fe/e691d2f4ce061a475f488cad1ef58431556affea323dde5c764fd7515a70/pytest_subtests-0.13.1.tar.gz", hash = "sha256:989e38f0f1c01bc7c6b2e04db7d9fd859db35d77c2c1a430c831a70cbf3fde2d", size = 15936 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/74/19/9fd9ff6e8827983bcfc74a39c4a98ab6b4c32b3f3403b917f352f7b83777/pytest_subtests-0.13.0-py3-none-any.whl", hash = "sha256:5a142064218df37a52299ddb393b1a6b2c1161ca19e71ca60c3a8040eb17e811", size = 8038 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/ac/fc132cb88e8f2042cebcb6ef0ffac40017c514fbadf3931e0b4bcb4bdfb6/pytest_subtests-0.13.1-py3-none-any.whl", hash = "sha256:ab616a22f64cd17c1aee65f18af94dbc30c444f8683de2b30895c3778265e3bd", size = 8038 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -4856,15 +4745,16 @@ sdist = { url = "https://files.pythonhosted.org/packages/ef/c6/2c5999de3bb153352
|
||||
|
||||
[[distribution]]
|
||||
name = "pytools"
|
||||
version = "2024.1.8"
|
||||
version = "2024.1.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "platformdirs" },
|
||||
{ name = "siphash24" },
|
||||
{ name = "typing-extensions", marker = "python_version < '3.13'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c0/0a/33961bdb345c0621f2883e6c192f05116fe7e4871700eb2100d3e37d152a/pytools-2024.1.8.tar.gz", hash = "sha256:cccc184a10af56dabab3077af82ab0cf7a5b06625313cae0b2f06a3c4b126001", size = 82220 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/0f/56e109c0307f831b5d598ad73976aaaa84b4d0e98da29a642e797eaa940c/pytools-2024.1.10.tar.gz", hash = "sha256:9af6f4b045212c49be32bb31fe19606c478ee4b09631886d05a32459f4ce0a12", size = 81741 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/ea/fa3124d613e07ee93aaf1ec38b846c712a25eda3035af20ae2e7cd5927e5/pytools-2024.1.8-py3-none-any.whl", hash = "sha256:3fe89cf182e97d16842de78f2b08c009030c895c4e1496e96e3679664cf2bd3b", size = 88527 },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/cf/0a6aaa44b1f9e02b8c0648b5665a82246a93bcc75224c167b4fafa25c093/pytools-2024.1.10-py3-none-any.whl", hash = "sha256:9cabb71038048291400e244e2da441a051d86053339bc484e64e58d8ea263f44", size = 88108 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -5042,27 +4932,27 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "ruff"
|
||||
version = "0.5.2"
|
||||
version = "0.5.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/79/6c/147f04f6a799f659cc810352742994e51441b14c7a5621e285d021261388/ruff-0.5.2.tar.gz", hash = "sha256:2c0df2d2de685433794a14d8d2e240df619b748fbe3367346baa519d8e6f1ca2", size = 2596910 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/95/15/3945cfecfd3de874633d2466327ebb01eabf4f61f962a0dd4bf5ce2dc997/ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a", size = 2434890 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/05/9ec81c397be41596e4329b340780d56bfa9ad1cb95247148bf9859edf575/ruff-0.5.2-py3-none-linux_armv6l.whl", hash = "sha256:7bab8345df60f9368d5f4594bfb8b71157496b44c30ff035d1d01972e764d3be", size = 9482764 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/ea/ebf3ea51ad48abfc6e0bbb762e71b0ffc6220a6fb8735cb09bd5aca7c52e/ruff-0.5.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aa7acad382ada0189dbe76095cf0a36cd0036779607c397ffdea16517f535b1", size = 8612665 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/52/9e7868770615c16be60549746ad6f48f483320f7ecf5a294f4f051f4e7d4/ruff-0.5.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aec618d5a0cdba5592c60c2dee7d9c865180627f1a4a691257dea14ac1aa264d", size = 8191223 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/9d/c880e41895b9bc48bf7051c81bcf270d2f6eebdce3c8f02c72fdef582d20/ruff-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b62adc5ce81780ff04077e88bac0986363e4a3260ad3ef11ae9c14aa0e67ef", size = 9972748 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/0b/17a0730f425f7f630446978b880ac0ad62a7c7e20fb4e21d2ab0a5154887/ruff-0.5.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc42ebf56ede83cb080a50eba35a06e636775649a1ffd03dc986533f878702a3", size = 9289379 },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/c4/1dcdc4a381aa07509d15dd78ec65e8fedd14c0a70a674ca3bbafa48502ed/ruff-0.5.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c15c6e9f88c67ffa442681365d11df38afb11059fc44238e71a9d9f1fd51de70", size = 10087604 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/fc/2707aa15de9e2485f024535b0fe239013d1be13bb475050f3e21b33109c9/ruff-0.5.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d3de9a5960f72c335ef00763d861fc5005ef0644cb260ba1b5a115a102157251", size = 10875118 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/db/4890a8c350b3fad767c663991052ba5ce42feae05f433fbf73acc3d1e8c3/ruff-0.5.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe5a968ae933e8f7627a7b2fc8893336ac2be0eb0aace762d3421f6e8f7b7f83", size = 10464801 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/30/0018669eb5a0bfd42d4be1d961fa4533bba1926ba83b8cf3e50223ee7d21/ruff-0.5.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a04f54a9018f75615ae52f36ea1c5515e356e5d5e214b22609ddb546baef7132", size = 11356413 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/60/e2a9ae058b34128caa5f863f268e1c9bd083793264f4bf7e8e469be651f9/ruff-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed02fb52e3741f0738db5f93e10ae0fb5c71eb33a4f2ba87c9a2fa97462a649", size = 10123340 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/fd/83b9f0107f5d0eea1c4b3a98655d789586d8e2662819df011a7964efa675/ruff-0.5.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3cf8fe659f6362530435d97d738eb413e9f090e7e993f88711b0377fbdc99f60", size = 9940668 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/75/2a98e9348bed95e0a121c3e1693c335530ef70280a364cf17f1d2da947cd/ruff-0.5.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:237a37e673e9f3cbfff0d2243e797c4862a44c93d2f52a52021c1a1b0899f846", size = 9380450 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/77/474f883393954f2323febd5cf7c96bfe8c684561f8d22ca843e90d122d73/ruff-0.5.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2a2949ce7c1cbd8317432ada80fe32156df825b2fd611688814c8557824ef060", size = 9718297 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/5a/72b3a1ddefbc7ccb382bcf9668648a6f1fdc4bfcc3d6687f14e6feb40636/ruff-0.5.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:481af57c8e99da92ad168924fd82220266043c8255942a1cb87958b108ac9335", size = 10221735 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/22/7aa3fb2b95dda4d485e5e5f15041679d3170a31b9317b24c6182f4c8faf1/ruff-0.5.2-py3-none-win32.whl", hash = "sha256:f1aea290c56d913e363066d83d3fc26848814a1fed3d72144ff9c930e8c7c718", size = 7786506 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/a0/f28c8380f4eff7451896618ca0cce097e65aef150c60c298a0b5c9f40311/ruff-0.5.2-py3-none-win_amd64.whl", hash = "sha256:8532660b72b5d94d2a0a7a27ae7b9b40053662d00357bb2a6864dd7e38819084", size = 8583643 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/c3/dd06a34c98fc887a8c027e1b17e7ceca479db98b24d3a2d98f8239f0ee71/ruff-0.5.2-py3-none-win_arm64.whl", hash = "sha256:73439805c5cb68f364d826a5c5c4b6c798ded6b7ebaa4011f01ce6c94e4d5583", size = 8012737 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/4d/f9e5e37369b22d74588fe496e82d2aa2fff508f0c05b34c38374194f5a8e/ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf", size = 9505926 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/48/ee53a87351dd03472cf1cb8073019a53a7282e4295e7ae62d7f5ae24202a/ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8", size = 8585187 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/ec/2c0bd5ec0965672bb2957abf6e44d93c2c7aab2ceb4251ea77eb9234ffd3/ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3", size = 8175846 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/d7/e476f96c013d59af08b7b155f2beee03e7595915718573c724a01681bea8/ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16", size = 9948714 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/da/00269f4905b5ceab77f64ec9ed2e8f848ccba68884b66b2423c9f8962878/ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b", size = 9299822 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/ce/8784906480809b5b43cfbb346bddcc3b9e8716fd73927e4d70fb5260c18e/ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e", size = 10100197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/a4/4f4796e6b440ed42ec8486e19fe9b9489d94f13c2debf49e68ed58af5d0b/ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0", size = 10813891 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/a4/9a0084212e0b2810beadd993f1b36f156438465a4d4193fd5bb2ab833892/ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7", size = 10439725 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/f7/4480e739af49f66f04edf2b1dd7ac6fa5e55639491e47267dbfa70d62488/ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884", size = 11358405 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/fd/7a6e01b8098c3375ce694427956a8192c708941051cebd279b988304a753/ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091", size = 10130793 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/4a/ba83ca67da7e81a8a191da36f3f6a350243210518c78c2e809fb25cac6c4/ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523", size = 9910666 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/6d/c982a93907559fa5cb62fd68c74b21662a4f088a09ad27f813244c7379c1/ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f", size = 9365153 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/a6/b3dbdb4505086d80ab8202c8592ad90a811fc328dc4a5966e065cda12dcc/ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8", size = 9736802 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/ba/b850fa0925ce59bc0bce412d18a9633a92126f23153f970437a51be711f0/ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab", size = 10198368 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/db/a9162178c90cada13f4c9bed9860947a1c5a79d7ecadd27250c67681dc81/ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d", size = 7798506 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/5b/13288039ea8190c121b70f1a11be2c4830cb3ebb57dc91d91fc5d3c65fc6/ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445", size = 8611739 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/b3/525847f73ab956053b130ec9f5d1ea078d94282b1d5eda90c09b8a81a935/ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6", size = 8039120 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -5117,24 +5007,24 @@ wheels = [
|
||||
|
||||
[[distribution]]
|
||||
name = "sentry-sdk"
|
||||
version = "2.10.0"
|
||||
version = "2.11.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/34/d8/ec3e43d4ce31e4f4cb6adb7210950362d71ce87a96c89934c4ac94f7110f/sentry_sdk-2.10.0.tar.gz", hash = "sha256:545fcc6e36c335faa6d6cda84669b6e17025f31efbf3b2211ec14efe008b75d1", size = 273996 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/b3/39e4cd04b75a1ada788342d0d30a781cf65b5e43da806d5bf2bad4846ea3/sentry_sdk-2.11.0.tar.gz", hash = "sha256:4ca16e9f5c7c6bc2fb2d5c956219f4926b148e511fffdbbde711dc94f1e0468f", size = 276242 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/9e/9298785949269c8930e1fd3707b960da6e1a95a2442b747b8f8cca4578cb/sentry_sdk-2.10.0-py2.py3-none-any.whl", hash = "sha256:87b3d413c87d8e7f816cc9334bff255a83d8b577db2b22042651c30c19c09190", size = 302064 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/3c/a8ab3309d22c1d7142f811882e7d45449696f87c6e4e723b1433b6069b84/sentry_sdk-2.11.0-py2.py3-none-any.whl", hash = "sha256:d964710e2dbe015d9dc4ff0ad16225d68c3b36936b742a6fe0504565b760a3b7", size = 303581 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "setuptools"
|
||||
version = "70.3.0"
|
||||
version = "71.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/65/d8/10a70e86f6c28ae59f101a9de6d77bf70f147180fbf40c3af0f64080adc3/setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5", size = 2333112 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/32/c0/5b8013b5a812701c72e3b1e2b378edaa6514d06bee6704a5ab0d7fa52931/setuptools-71.1.0.tar.gz", hash = "sha256:032d42ee9fb536e33087fb66cac5f840eb9391ed05637b3f2a76a7c8fb477936", size = 2422233 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/15/88e46eb9387e905704b69849618e699dc2f54407d8953cc4ec4b8b46528d/setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc", size = 931070 },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/a0/ee460cc54e68afcf33190d198299c9579a5eafeadef0016ae8563237ccb6/setuptools-71.1.0-py3-none-any.whl", hash = "sha256:33874fdc59b3188304b2e7c80d9029097ea31627180896fb549c578ceb8a0855", size = 2341722 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
@@ -5198,15 +5088,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/5b/3ada173f07b4ec9bfa03b779e59ecada48eb7cb1a29f51cfce70edce7f3f/smbus2-0.4.3-py2.py3-none-any.whl", hash = "sha256:a2fc29cfda4081ead2ed61ef2c4fc041d71dd40a8d917e85216f44786fca2d1d", size = 11553 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "snowballstemmer"
|
||||
version = "2.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sortedcontainers"
|
||||
version = "2.4.0"
|
||||
@@ -5231,87 +5112,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/09/bfdd393f1bb1b90b4a6849b84972b7059c95e36818cc489922228d58cc63/sounddevice-0.4.7-py3-none-win_amd64.whl", hash = "sha256:0c8b3543da1496f282b66a7bc54b755577ba638b1af06c146d4ac7f39d86b548", size = 200096 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinx"
|
||||
version = "7.4.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "alabaster" },
|
||||
{ name = "babel" },
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "docutils" },
|
||||
{ name = "imagesize" },
|
||||
{ name = "jinja2" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pygments" },
|
||||
{ name = "requests" },
|
||||
{ name = "snowballstemmer" },
|
||||
{ name = "sphinxcontrib-applehelp" },
|
||||
{ name = "sphinxcontrib-devhelp" },
|
||||
{ name = "sphinxcontrib-htmlhelp" },
|
||||
{ name = "sphinxcontrib-jsmath" },
|
||||
{ name = "sphinxcontrib-qthelp" },
|
||||
{ name = "sphinxcontrib-serializinghtml" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/7a/bc303eb950025a2cfa8f6968471fda8b28e8114621e2ab43f518094a4225/sphinx-7.4.3.tar.gz", hash = "sha256:bd846bcb09fd2b6e94ce3e1ad50f4618bccf03cc7c17d0f3fa87393c0bd9178b", size = 8113870 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/b8/8594be28e66d19c287c13dbc609a7695e5330ea59abce654a3f41b8a589e/sphinx-7.4.3-py3-none-any.whl", hash = "sha256:a3c295d0e8be6277e0a5ba5c6909a308bd208876b0f4f68c7cc591f566129412", size = 3454542 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-applehelp"
|
||||
version = "1.0.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/26/6b/68f470fc337ed24043fec987b101f25b35010970bd958970c2ae5990859f/sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619", size = 19674 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/56/89/fea3fbf6785b388e6cb8a1beaf62f96e80b37311bdeed6e133388a732426/sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4", size = 120035 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-devhelp"
|
||||
version = "1.0.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c7/a1/80b7e9f677abc673cb9320bf255ad4e08931ccbc2e66bde4b59bad3809ad/sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3", size = 12480 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/52/1049d918d1d1c72857d285c3f0c64c1cbe0be394ce1c93a3d2aa4f39fe3b/sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f", size = 83499 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-htmlhelp"
|
||||
version = "2.0.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8a/03/2f9d699fbfdf03ecb3b6d0e2a268a8998d009f2a9f699c2dcc936899257d/sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015", size = 21925 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/e9/74c4cda5b409af3222fda38f0774e616011bc935f639dbc0da5ca2d1be7d/sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04", size = 99217 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-jsmath"
|
||||
version = "1.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-qthelp"
|
||||
version = "1.0.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/29/705cd4e93e98a8473d62b5c32288e6de3f0c9660d3c97d4e80d3dbbad82b/sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6", size = 16685 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/80/b3/1beac14a88654d2e5120d0143b49be5ad450b86eb1963523d8dbdcc51eb2/sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182", size = 89441 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "sphinxcontrib-serializinghtml"
|
||||
version = "1.1.10"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/54/13/8dd7a7ed9c58e16e20c7f4ce8e4cb6943eb580955236d0c0d00079a73c49/sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f", size = 15592 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/38/24/228bb903ea87b9e08ab33470e6102402a644127108c7117ac9c00d849f82/sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7", size = 92725 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
name = "spidev"
|
||||
version = "3.6"
|
||||
@@ -5320,14 +5120,14 @@ sdist = { url = "https://files.pythonhosted.org/packages/c7/d9/401c0a7be089e0282
|
||||
|
||||
[[distribution]]
|
||||
name = "sympy"
|
||||
version = "1.13.0"
|
||||
version = "1.13.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mpmath" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cb/f5/8c7d91ce35816b72c2dd061dc4a33f00f59053aeffe881d42aed17279381/sympy-1.13.0.tar.gz", hash = "sha256:3b6af8f4d008b9a1a6a4268b335b984b23835f26d1d60b0526ebc71d48a25f57", size = 7532455 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/62/74/7e6c65ee89ff43942bffffdbb238634f16967bf327aee3c76efcf6e49587/sympy-1.13.0-py3-none-any.whl", hash = "sha256:6b0b32a4673fb91bd3cac3b55406c8e01d53ae22780be467301cc452f6680c92", size = 6188245 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 },
|
||||
]
|
||||
|
||||
[[distribution]]
|
||||
|
||||
Reference in New Issue
Block a user