diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f1cfc82159..0f1c4baf99 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,7 +28,9 @@ "installOhMyZsh": false, "upgradePackages": false, "username": "batman" - } + }, + "ghcr.io/devcontainers-contrib/features/gh-cli:1": {}, + "ghcr.io/devcontainers/features/azure-cli:1": {} }, "containerUser": "batman", "remoteUser": "batman", diff --git a/.github/PULL_REQUEST_TEMPLATE/car_port.md b/.github/PULL_REQUEST_TEMPLATE/car_port.md index 690c24c9b0..c7aa2b96c2 100644 --- a/.github/PULL_REQUEST_TEMPLATE/car_port.md +++ b/.github/PULL_REQUEST_TEMPLATE/car_port.md @@ -8,7 +8,7 @@ assignees: '' **Checklist** -- [ ] added entry to CarInfo in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs +- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs - [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py) - [ ] route with openpilot: - [ ] route with stock system: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3e3f42dcbc..2b4a5ed48f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -44,7 +44,7 @@ Explain how you tested this bug fix. **Checklist** -- [ ] added entry to CarInfo in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs +- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs - [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py) - [ ] route with openpilot: - [ ] route with stock system: diff --git a/.github/workflows/auto-cache/action.yaml b/.github/workflows/auto-cache/action.yaml index 173803f7f0..c5506e4769 100644 --- a/.github/workflows/auto-cache/action.yaml +++ b/.github/workflows/auto-cache/action.yaml @@ -19,7 +19,7 @@ runs: using: "composite" steps: - name: setup namespace cache - if: ${{ contains(runner.name, 'nsc') }} + if: ${{ contains(runner.name, 'nsc') }} uses: namespacelabs/nscloud-cache-action@v1 with: path: ${{ inputs.path }} diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index d1dff147f2..bfd2b82dc8 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -69,7 +69,7 @@ jobs: matrix: arch: ${{ fromJson( ((github.repository == 'commaai/openpilot') && - ((github.event_name != 'pull_request') || + ((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-20.04' }} steps: @@ -122,7 +122,7 @@ jobs: static_analysis: name: static analysis runs-on: ${{ ((github.repository == 'commaai/openpilot') && - ((github.event_name != 'pull_request') || + ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-20.04' }} steps: - uses: actions/checkout@v4 @@ -155,7 +155,7 @@ jobs: unit_tests: name: unit tests runs-on: ${{ ((github.repository == 'commaai/openpilot') && - ((github.event_name != 'pull_request') || + ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-20.04' }} steps: - uses: actions/checkout@v4 @@ -186,7 +186,7 @@ jobs: process_replay: name: process replay runs-on: ${{ ((github.repository == 'commaai/openpilot') && - ((github.event_name != 'pull_request') || + ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-20.04' }} steps: - uses: actions/checkout@v4 @@ -235,7 +235,7 @@ jobs: regen: name: regen runs-on: 'ubuntu-20.04' - steps: + steps: - uses: actions/checkout@v4 with: submodules: true @@ -293,7 +293,7 @@ jobs: test_cars: name: cars runs-on: ${{ ((github.repository == 'commaai/openpilot') && - ((github.event_name != 'pull_request') || + ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-20.04' }} strategy: fail-fast: false @@ -340,7 +340,7 @@ jobs: - uses: ./.github/workflows/setup-with-retry - name: Get base car info run: | - ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_info.py --path /tmp/openpilot_cache/base_car_info" + ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs" sudo chown -R $USER:$USER ${{ github.workspace }} - uses: actions/checkout@v4 with: @@ -352,7 +352,7 @@ jobs: run: | cd current ${{ env.RUN }} "scons -j$(nproc)" - output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_info") + output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs") output="${output//$'\n'/'%0A'}" echo "::set-output name=diff::$output" - name: Find comment @@ -395,7 +395,7 @@ jobs: run: > ${{ env.RUN }} "PYTHONWARNINGS=ignore && source selfdrive/test/setup_xvfb.sh && - export MAPBOX_TOKEN='pk.eyJ1Ijoiam5ld2IiLCJhIjoiY2xxNW8zZXprMGw1ZzJwbzZneHd2NHljbSJ9.gV7VPRfbXFetD-1OVF0XZg' && + export MAPBOX_TOKEN='pk.eyJ1Ijoiam5ld2IiLCJhIjoiY2xxNW8zZXprMGw1ZzJwbzZneHd2NHljbSJ9.gV7VPRfbXFetD-1OVF0XZg' && python selfdrive/ui/tests/test_ui/run.py" - name: Upload Test Report uses: actions/upload-artifact@v2 diff --git a/.github/workflows/setup-pre-commit/action.yaml b/.github/workflows/setup-pre-commit/action.yaml index 1b3e16e73f..f07a106861 100644 --- a/.github/workflows/setup-pre-commit/action.yaml +++ b/.github/workflows/setup-pre-commit/action.yaml @@ -4,7 +4,7 @@ runs: using: "composite" steps: - uses: ./.github/workflows/auto-cache - with: + with: path: .ci_cache/pre-commit key: pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }} restore-keys: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6db68e55bc..1d152fee2a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 - --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.2 + rev: v0.3.3 hooks: - id: ruff exclude: '^(third_party/)|(cereal/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)' diff --git a/.vscode/settings.json b/.vscode/settings.json index 811306f399..f0731c362d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,6 +21,7 @@ "common/**", "selfdrive/**", "system/**", + "third_party/**", "tools/**", ] } diff --git a/Jenkinsfile b/Jenkinsfile index d716510bfe..4afb3964f7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -194,7 +194,7 @@ node { ["test pandad", "pytest selfdrive/boardd/tests/test_pandad.py"], ["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"], ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], - ["test pigeond", "pytest system/sensord/tests/test_pigeond.py"], + ["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"], ["test manager", "pytest selfdrive/manager/test/test_manager.py"], ]) }, diff --git a/RELEASES.md b/RELEASES.md index 4ec4c4fad5..2af124d4e6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,6 +1,7 @@ Version 0.9.7 (2024-XX-XX) ======================== * New driving model +* Adjust driving personality with the follow distance button * Support for hybrid variants of supported Ford models Version 0.9.6 (2024-02-27) diff --git a/cereal b/cereal index cf7bb3e749..430535068a 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit cf7bb3e74974879abef94286fab4d39398fe402b +Subproject commit 430535068ac3bb94d3e117a3cfbc348ef37eb72d diff --git a/common/git.py b/common/git.py new file mode 100644 index 0000000000..e15a5051d2 --- /dev/null +++ b/common/git.py @@ -0,0 +1,42 @@ +import subprocess +from openpilot.common.utils import cache +from openpilot.common.run import run_cmd, run_cmd_default + + +@cache +def get_commit(branch: str = "HEAD") -> str: + return run_cmd_default(["git", "rev-parse", branch]) + + +@cache +def get_commit_date(commit: str = "HEAD") -> str: + return run_cmd_default(["git", "show", "--no-patch", "--format='%ct %ci'", commit]) + + +@cache +def get_short_branch() -> str: + return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"]) + + +@cache +def get_branch() -> str: + return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]) + + +@cache +def get_origin() -> str: + try: + local_branch = run_cmd(["git", "name-rev", "--name-only", "HEAD"]) + tracking_remote = run_cmd(["git", "config", "branch." + local_branch + ".remote"]) + return run_cmd(["git", "config", "remote." + tracking_remote + ".url"]) + except subprocess.CalledProcessError: # Not on a branch, fallback + return run_cmd_default(["git", "config", "--get", "remote.origin.url"]) + + +@cache +def get_normalized_origin() -> str: + return get_origin() \ + .replace("git@", "", 1) \ + .replace(".git", "", 1) \ + .replace("https://", "", 1) \ + .replace(":", "/", 1) diff --git a/common/params.cc b/common/params.cc index f68e1e4c6b..38d96a30b0 100644 --- a/common/params.cc +++ b/common/params.cc @@ -207,7 +207,6 @@ std::unordered_map keys = { {"UpdaterTargetBranch", CLEAR_ON_MANAGER_START}, {"UpdaterLastFetchTime", PERSISTENT}, {"Version", PERSISTENT}, - {"VisionRadarToggle", PERSISTENT}, }; } // namespace diff --git a/common/run.py b/common/run.py new file mode 100644 index 0000000000..25abe98c41 --- /dev/null +++ b/common/run.py @@ -0,0 +1,13 @@ +import subprocess + + +def run_cmd(cmd: list[str]) -> str: + return subprocess.check_output(cmd, encoding='utf8').strip() + + +def run_cmd_default(cmd: list[str], default: str = "") -> str: + try: + return run_cmd(cmd) + except subprocess.CalledProcessError: + return default + diff --git a/common/transformations/camera.py b/common/transformations/camera.py index c643cb5702..dc3ca5f388 100644 --- a/common/transformations/camera.py +++ b/common/transformations/camera.py @@ -1,55 +1,74 @@ +import itertools import numpy as np +from dataclasses import dataclass import openpilot.common.transformations.orientation as orient ## -- hardcoded hardware params -- -eon_f_focal_length = 910.0 -eon_d_focal_length = 650.0 -tici_f_focal_length = 2648.0 -tici_e_focal_length = tici_d_focal_length = 567.0 # probably wrong? magnification is not consistent across frame - -eon_f_frame_size = (1164, 874) -eon_d_frame_size = (816, 612) -tici_f_frame_size = tici_e_frame_size = tici_d_frame_size = (1928, 1208) - -# aka 'K' aka camera_frame_from_view_frame -eon_fcam_intrinsics = np.array([ - [eon_f_focal_length, 0.0, float(eon_f_frame_size[0])/2], - [0.0, eon_f_focal_length, float(eon_f_frame_size[1])/2], - [0.0, 0.0, 1.0]]) -eon_intrinsics = eon_fcam_intrinsics # xx - -eon_dcam_intrinsics = np.array([ - [eon_d_focal_length, 0.0, float(eon_d_frame_size[0])/2], - [0.0, eon_d_focal_length, float(eon_d_frame_size[1])/2], - [0.0, 0.0, 1.0]]) - -tici_fcam_intrinsics = np.array([ - [tici_f_focal_length, 0.0, float(tici_f_frame_size[0])/2], - [0.0, tici_f_focal_length, float(tici_f_frame_size[1])/2], - [0.0, 0.0, 1.0]]) - -tici_dcam_intrinsics = np.array([ - [tici_d_focal_length, 0.0, float(tici_d_frame_size[0])/2], - [0.0, tici_d_focal_length, float(tici_d_frame_size[1])/2], - [0.0, 0.0, 1.0]]) - -tici_ecam_intrinsics = tici_dcam_intrinsics - -# aka 'K_inv' aka view_frame_from_camera_frame -eon_fcam_intrinsics_inv = np.linalg.inv(eon_fcam_intrinsics) -eon_intrinsics_inv = eon_fcam_intrinsics_inv # xx - -tici_fcam_intrinsics_inv = np.linalg.inv(tici_fcam_intrinsics) -tici_ecam_intrinsics_inv = np.linalg.inv(tici_ecam_intrinsics) - - -FULL_FRAME_SIZE = tici_f_frame_size -FOCAL = tici_f_focal_length -fcam_intrinsics = tici_fcam_intrinsics - -W, H = FULL_FRAME_SIZE[0], FULL_FRAME_SIZE[1] - +@dataclass(frozen=True) +class CameraConfig: + width: int + height: int + focal_length: float + + @property + def size(self): + return (self.width, self.height) + + @property + def intrinsics(self): + # aka 'K' aka camera_frame_from_view_frame + return np.array([ + [self.focal_length, 0.0, float(self.width)/2], + [0.0, self.focal_length, float(self.height)/2], + [0.0, 0.0, 1.0] + ]) + + @property + def intrinsics_inv(self): + # aka 'K_inv' aka view_frame_from_camera_frame + return np.linalg.inv(self.intrinsics) + +@dataclass(frozen=True) +class _NoneCameraConfig(CameraConfig): + width: int = 0 + height: int = 0 + focal_length: float = 0 + +@dataclass(frozen=True) +class DeviceCameraConfig: + fcam: CameraConfig + dcam: CameraConfig + ecam: CameraConfig + + def all_cams(self): + for cam in ['fcam', 'dcam', 'ecam']: + if not isinstance(getattr(self, cam), _NoneCameraConfig): + yield cam, getattr(self, cam) + +_ar_ox_fisheye = CameraConfig(1928, 1208, 567.0) # focal length probably wrong? magnification is not consistent across frame +_os_fisheye = CameraConfig(2688, 1520, 567.0 / 2 * 3) +_ar_ox_config = DeviceCameraConfig(CameraConfig(1928, 1208, 2648.0), _ar_ox_fisheye, _ar_ox_fisheye) +_os_config = DeviceCameraConfig(CameraConfig(2688, 1520, 2648.0 * 2 / 3), _os_fisheye, _os_fisheye) +_neo_config = DeviceCameraConfig(CameraConfig(1164, 874, 910.0), CameraConfig(816, 612, 650.0), _NoneCameraConfig()) + +DEVICE_CAMERAS = { + # A "device camera" is defined by a device type and sensor + + # sensor type was never set on eon/neo/two + ("neo", "unknown"): _neo_config, + # unknown here is AR0231, field was added with OX03C10 support + ("tici", "unknown"): _ar_ox_config, + + # before deviceState.deviceType was set, assume tici AR config + ("unknown", "ar0231"): _ar_ox_config, + ("unknown", "ox03c10"): _ar_ox_config, + + # simulator (emulates a tici) + ("pc", "unknown"): _ar_ox_config, +} +prods = itertools.product(('tici', 'tizi', 'mici'), (('ar0231', _ar_ox_config), ('ox03c10', _ar_ox_config), ('os04c10', _os_config))) +DEVICE_CAMERAS.update({(d, c[0]): c[1] for d, c in prods}) # device/mesh : x->forward, y-> right, z->down # view : x->right, y->down, z->forward @@ -93,7 +112,7 @@ def roll_from_ke(m): -(m[0, 0] - m[0, 1] * m[2, 0] / m[2, 1])) -def normalize(img_pts, intrinsics=fcam_intrinsics): +def normalize(img_pts, intrinsics): # normalizes image coordinates # accepts single pt or array of pts intrinsics_inv = np.linalg.inv(intrinsics) @@ -106,7 +125,7 @@ def normalize(img_pts, intrinsics=fcam_intrinsics): return img_pts_normalized[:, :2].reshape(input_shape) -def denormalize(img_pts, intrinsics=fcam_intrinsics, width=np.inf, height=np.inf): +def denormalize(img_pts, intrinsics, width=np.inf, height=np.inf): # denormalizes image coordinates # accepts single pt or array of pts img_pts = np.array(img_pts) @@ -123,7 +142,7 @@ def denormalize(img_pts, intrinsics=fcam_intrinsics, width=np.inf, height=np.inf return img_pts_denormalized[:, :2].reshape(input_shape) -def get_calib_from_vp(vp, intrinsics=fcam_intrinsics): +def get_calib_from_vp(vp, intrinsics): vp_norm = normalize(vp, intrinsics) yaw_calib = np.arctan(vp_norm[0]) pitch_calib = -np.arctan(vp_norm[1]*np.cos(yaw_calib)) diff --git a/common/transformations/model.py b/common/transformations/model.py index 7e40767f63..aaa12d776a 100644 --- a/common/transformations/model.py +++ b/common/transformations/model.py @@ -1,19 +1,11 @@ import numpy as np from openpilot.common.transformations.orientation import rot_from_euler -from openpilot.common.transformations.camera import ( - FULL_FRAME_SIZE, get_view_frame_from_calib_frame, view_frame_from_device_frame, - eon_fcam_intrinsics, tici_ecam_intrinsics, tici_fcam_intrinsics) +from openpilot.common.transformations.camera import get_view_frame_from_calib_frame, view_frame_from_device_frame # segnet SEGNET_SIZE = (512, 384) -def get_segnet_frame_from_camera_frame(segnet_size=SEGNET_SIZE, full_frame_size=FULL_FRAME_SIZE): - return np.array([[float(segnet_size[0]) / full_frame_size[0], 0.0], - [0.0, float(segnet_size[1]) / full_frame_size[1]]]) -segnet_frame_from_camera_frame = get_segnet_frame_from_camera_frame() # xx - - # MED model MEDMODEL_INPUT_SIZE = (512, 256) MEDMODEL_YUV_SIZE = (MEDMODEL_INPUT_SIZE[0], MEDMODEL_INPUT_SIZE[1] * 3 // 2) @@ -63,16 +55,9 @@ calib_from_medmodel = np.linalg.inv(medmodel_frame_from_calib_frame[:, :3]) calib_from_sbigmodel = np.linalg.inv(sbigmodel_frame_from_calib_frame[:, :3]) # This function is verified to give similar results to xx.uncommon.utils.transform_img -def get_warp_matrix(device_from_calib_euler: np.ndarray, wide_camera: bool = False, bigmodel_frame: bool = False, tici: bool = True) -> np.ndarray: - if tici and wide_camera: - cam_intrinsics = tici_ecam_intrinsics - elif tici: - cam_intrinsics = tici_fcam_intrinsics - else: - cam_intrinsics = eon_fcam_intrinsics - +def get_warp_matrix(device_from_calib_euler: np.ndarray, intrinsics: np.ndarray, bigmodel_frame: bool = False) -> np.ndarray: calib_from_model = calib_from_sbigmodel if bigmodel_frame else calib_from_medmodel device_from_calib = rot_from_euler(device_from_calib_euler) - camera_from_calib = cam_intrinsics @ view_frame_from_device_frame @ device_from_calib + camera_from_calib = intrinsics @ view_frame_from_device_frame @ device_from_calib warp_matrix: np.ndarray = camera_from_calib @ calib_from_model return warp_matrix diff --git a/common/utils.py b/common/utils.py index b9de020ee6..e37f2448c5 100644 --- a/common/utils.py +++ b/common/utils.py @@ -1,3 +1,11 @@ +from collections.abc import Callable +from functools import lru_cache +from typing import TypeVar + + +_RT = TypeVar("_RT") + + class Freezable: _frozen: bool = False @@ -9,3 +17,7 @@ class Freezable: if self._frozen: raise Exception("cannot modify frozen object") super().__setattr__(*args, **kwargs) + + +def cache(user_function: Callable[..., _RT], /) -> Callable[..., _RT]: + return lru_cache(maxsize=None)(user_function) diff --git a/docs/BOUNTIES.md b/docs/BOUNTIES.md index 5ff5dd939f..7e7ee3b8d3 100644 --- a/docs/BOUNTIES.md +++ b/docs/BOUNTIES.md @@ -10,7 +10,8 @@ Get paid to improve openpilot! * open a ticket at [comma.ai/support](https://comma.ai/support/shop-order) with links to your PRs to claim * get an extra 20% if you redeem your bounty in [comma shop](https://comma.ai/shop) credit (including refunds on previous orders) -New bounties can be proposed in the [**#contributing**](https://discord.com/channels/469524606043160576/1183173332531687454) channel in Discord. +We put up each bounty with the intention that it'll get merged, but occasionally the right resolution is to close the bounty, which only becomes clear once some effort is put in. +This is still valuable work, so we'll pay out $100 for getting any bounty closed with a good explanation. ## Issue bounties @@ -20,6 +21,8 @@ We've tagged bounty-eligible issues across openpilot and the rest of our repos; * **$500** - a few days of work for an experienced openpilot developer * **$1k+** - a week or two of work (could be less for the right person) +New bounties can be proposed in the [**#contributing**](https://discord.com/channels/469524606043160576/1183173332531687454) channel in Discord. + ## Car bounties The car bounties only apply to cars that have a path to ship in openpilot release, which excludes unsupportable cars (e.g. Fords with a steering lockout) or cars that require extra hardware (Honda Accord with serial steering). diff --git a/docs/CARS.md b/docs/CARS.md index 591a76e4cb..35a77fd78f 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -35,7 +35,7 @@ A supported vehicle is one that just works when you install a comma device. All |Chrysler|Pacifica Hybrid 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|| |Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Bronco Sport 2021-23|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -47,14 +47,14 @@ A supported vehicle is one that just works when you install a comma device. All |Ford|Kuga Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Kuga Plug-in Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Maverick 2022|LARIAT Luxury|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Ford|Maverick 2023|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Ford|Maverick Hybrid 2023|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Genesis|G70 2020|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Genesis|G70 2020-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G80 2017|All|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai J connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|G80 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Genesis|G90 2017-18|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Genesis|G90 2017-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|GV60 (Advanced Trim) 2023[6](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|GV60 (Performance Trim) 2023[6](#footnotes)|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Genesis|GV70 (2.5T Trim) 2022-23[6](#footnotes)|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai L connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -110,7 +110,7 @@ A supported vehicle is one that just works when you install a comma device. All |Hyundai|Kona Electric (with HDA II, Korea only) 2023[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai R connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai I connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Palisade 2020-22|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Hyundai|Santa Cruz 2022-23[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Hyundai|Santa Cruz 2022-24[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Santa Fe 2019-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Santa Fe 2021-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai L connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Hyundai|Santa Fe Hybrid 2022-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai L connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -148,9 +148,9 @@ A supported vehicle is one that just works when you install a comma device. All |Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Niro Hybrid 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Niro Plug-in Hybrid 2018-19|All|Stock|10 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Kia|Niro Plug-in Hybrid 2020|All|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Kia|Niro Plug-in Hybrid 2021|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Kia|Niro Plug-in Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Kia|Niro Plug-in Hybrid 2020|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Kia|Niro Plug-in Hybrid 2021|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Kia|Niro Plug-in Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai B connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai G connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai H connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -160,7 +160,7 @@ A supported vehicle is one that just works when you install a comma device. All |Kia|Sorento 2021-23[6](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Sorento Hybrid 2021-23[6](#footnotes)|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Sorento Plug-in Hybrid 2022-23[6](#footnotes)|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai A connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Kia|Sportage 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Kia|Sportage 2023-24[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Sportage Hybrid 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Kia|Stinger 2022-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Hyundai K connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -256,8 +256,8 @@ A supported vehicle is one that just works when you install a comma device. All |Toyota|RAV4 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 2023-24|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|openpilot available[2](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Toyota|RAV4 Hybrid 2017-18|All|openpilot available[2](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Toyota|RAV4 Hybrid 2016|Toyota Safety Sense P|openpilot available[2](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Toyota|RAV4 Hybrid 2017-18|All|openpilot available[2](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Toyota|RAV4 Hybrid 2023-24|All|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/panda b/panda index 41e9610ff8..567dbfe6d8 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 41e9610ff841e4cf62051c6df09c1870f5d12477 +Subproject commit 567dbfe6d86ddda6d803da371942603c6dbe36c8 diff --git a/poetry.lock b/poetry.lock index 588186d138..c2e0baad9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -112,34 +112,34 @@ ifaddr = ">=0.2.0" [[package]] name = "aiortc" -version = "1.7.0" +version = "1.8.0" description = "An implementation of WebRTC and ORTC" optional = false python-versions = ">=3.8" files = [ - {file = "aiortc-1.7.0-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aba47eac61ee7fb7e89876f40e4132aa66a13ed2a730dff003342e57219f34c0"}, - {file = "aiortc-1.7.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:169abaaa0c11a1695942b3eeea9d9032ea4992c6e84958c1b31c6ba22fcf4b0e"}, - {file = "aiortc-1.7.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5323a347d02d53989e61944eead19e550d930afbb872dd0fb51b3d065aaa833"}, - {file = "aiortc-1.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71c18762ebfeb239352705672e598c57f0e56e5c1b7955dba27651c801c56ea2"}, - {file = "aiortc-1.7.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:817526c2e429a1ef1226ca9cdb4ff3c5d03857eb31de0f5a00433dc4cb5569f3"}, - {file = "aiortc-1.7.0-cp38-abi3-win32.whl", hash = "sha256:a63c4da5c4a9d96ef6e3948c1f4675e02b0b908605eff4cea8b5e2fa5a34da4e"}, - {file = "aiortc-1.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:e60f19f810a552690bf6e969429c624df39af2b5079ee0d95fb75d110b978e20"}, - {file = "aiortc-1.7.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7407d7065cbc649adf866927c007d84f94eeb3fcaa65f44eb94def8c2c5bbca"}, - {file = "aiortc-1.7.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35e1dce2697762841dd3cc5a6e23ef8a0d96207e3fd33b834b5a8686748f6143"}, - {file = "aiortc-1.7.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77cc2d757d7c3c37c6157cce36fe13fc161c5cb5aea62759c8b0d3e6d7f45f9"}, - {file = "aiortc-1.7.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80465daa66f89e4fd22b6afd3a6ae71ffd506343cf30025dbc36eb5453f95330"}, - {file = "aiortc-1.7.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8fcf352df6fabad32fd337dc51b629060de80d06987a8544c3c842ecc04254f8"}, - {file = "aiortc-1.7.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5b1427673e3ef8889dbd1c4f05d3d2aa7895cbfdc985532d54892ad6f96fc08c"}, - {file = "aiortc-1.7.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec2d018bd01c7532188be5842e11de252a1346156880ff3387d4f879c9f163d2"}, - {file = "aiortc-1.7.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f21e0024c0c7b07fec87e1ffcc30b6dbd57d1b822324d9c0128731388a82f08"}, - {file = "aiortc-1.7.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd267c338bd6578b46fb8f664418f9a48ad5d1582895eb029b4c5087e105fc89"}, - {file = "aiortc-1.7.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:919b6edbc1e462cb00e313d44368798066c3ebe81525ec6fb6008e0cad572c97"}, - {file = "aiortc-1.7.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:573314501d4aa2ef5e8826abe7e675742c92d25908f5f6b48ea2f5fababdfb4b"}, - {file = "aiortc-1.7.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:791f525577033572ee937853159cff2c63121d1e30d9c93df4ef3a4c94eec5ec"}, - {file = "aiortc-1.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52e945b2ba536e4e78c106e6c923f73b1838bf0c35592d729ea9b3ba6791b108"}, - {file = "aiortc-1.7.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89a8aef4067c68ccbc97872d506b9b80d5ed39e0cc41a46d641b66c518e00240"}, - {file = "aiortc-1.7.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0b7248716706c52e3bc1f21a89a1a9ca205e95a74c0b4aa4b2863d2162fd2552"}, - {file = "aiortc-1.7.0.tar.gz", hash = "sha256:4fd900797b419a9189443b7c95a2ce4bf5aa0d9542d8d19edfabf30aa5fbc296"}, + {file = "aiortc-1.8.0-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ac0bc48c9f98a744f6696be287b0403648deb3e20bd7f8fa91eb841e1c6c4e8d"}, + {file = "aiortc-1.8.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:639afa23b7d5c6f7d4f3f7af5fadb9cc67c82d56e17840b4433d2e5f73958bb5"}, + {file = "aiortc-1.8.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:173dcfa6f0e989f65eb9d38f151d8834677df0f696f9f4ad925ee9795e914eaf"}, + {file = "aiortc-1.8.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b453def215c246486747e8ba5c1307a538071d6bfbb2a4e74ebfef583771a429"}, + {file = "aiortc-1.8.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22efeb53dab9eb58a1a6c2dcdeb72ae526de0a2b30334fc40782341df92a657d"}, + {file = "aiortc-1.8.0-cp38-abi3-win32.whl", hash = "sha256:4ec0c5c284c3345a9d994253ced4ad909acf9e375271a7ff01db165b09890ce8"}, + {file = "aiortc-1.8.0-cp38-abi3-win_amd64.whl", hash = "sha256:76454c55a59441a76f6ab7cd1218454389520d6a3cc9b0d13d428f6a3f2ebbcc"}, + {file = "aiortc-1.8.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b0eb1342595e386befcad56cd0f91cd5cd16daa7612ffc5c8abf7e5b58e529f5"}, + {file = "aiortc-1.8.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cbbdf78ac55e05d838fe4de326ed095ca6df1cd10d571958d2ef8f23792203b"}, + {file = "aiortc-1.8.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0bb565acb623474d8052926f2ee768dbf1f87a71d271df78482319c0bec7c817"}, + {file = "aiortc-1.8.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd50def722eb6b999ebc831eca7bea79019d2eda71dc79f4219a9ab19d65c961"}, + {file = "aiortc-1.8.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4054f42f9ef875c67e38c0e86532e85e7ba528957052bc3d99e7c7caf273c456"}, + {file = "aiortc-1.8.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ef40f132262a670169121b888a448e1973e892f1ed8a5f5980ab05a12ee78a32"}, + {file = "aiortc-1.8.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e53d9f999104a2438c0c23f2cbc991c5e15e46c0fe71476d60c222b62e4c5a70"}, + {file = "aiortc-1.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a1ef2e0d657aaca42106558c7c8d6e84c7088d0b70bc1fe3f93c555c242e38"}, + {file = "aiortc-1.8.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:454012e08c9ef5027c2543d4e97b6f1323ce027ec395202478a7e431b2519c5b"}, + {file = "aiortc-1.8.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09dd2fad7a52f8fc66c86cdd2dd4d281b9815afd996e41301dd2706ccd57438a"}, + {file = "aiortc-1.8.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d669b635bbd8cf76fce63d3ceb83da5b219cea8bae4b566233f68618e69446cb"}, + {file = "aiortc-1.8.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ccc4da8821e7ecdd2179bc5eb7fd5f12e50db8fc6affdbc8baa55f3f14dd377"}, + {file = "aiortc-1.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29ba65bcb4c4cd1b25109d1e7ee5cf303654b757a3b7b59a28e162953e5f6c36"}, + {file = "aiortc-1.8.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1be4571e70e15b443f5b9ae651e24ac9dafb8b9abc1cdeb14e5f4bf028639944"}, + {file = "aiortc-1.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2e20fe3cb4a8b6db4f5e8f625ff1eb9dafc67b7c0c9a0cb9969b646570aebd34"}, + {file = "aiortc-1.8.0.tar.gz", hash = "sha256:2363c08d1d2cb3aaed563c1fb256f5dae9f3ba75b70ad5e5df6d448504122591"}, ] [package.dependencies] @@ -255,13 +255,13 @@ files = [ [[package]] name = "azure-core" -version = "1.30.0" +version = "1.30.1" description = "Microsoft Azure Core Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure-core-1.30.0.tar.gz", hash = "sha256:6f3a7883ef184722f6bd997262eddaf80cfe7e5b3e0caaaf8db1695695893d35"}, - {file = "azure_core-1.30.0-py3-none-any.whl", hash = "sha256:3dae7962aad109610e68c9a7abb31d79720e1d982ddf61363038d175a5025e89"}, + {file = "azure-core-1.30.1.tar.gz", hash = "sha256:26273a254131f84269e8ea4464f3560c731f29c0c1f69ac99010845f239c1a8f"}, + {file = "azure_core-1.30.1-py3-none-any.whl", hash = "sha256:7c5ee397e48f281ec4dd773d67a0a47a0962ed6fa833036057f9ea067f688e74"}, ] [package.dependencies] @@ -291,13 +291,13 @@ msal-extensions = ">=0.3.0,<2.0.0" [[package]] name = "azure-storage-blob" -version = "12.19.0" +version = "12.19.1" description = "Microsoft Azure Blob Storage Client Library for Python" optional = false python-versions = ">=3.7" files = [ - {file = "azure-storage-blob-12.19.0.tar.gz", hash = "sha256:26c0a4320a34a3c2a1b74528ba6812ebcb632a04cd67b1c7377232c4b01a5897"}, - {file = "azure_storage_blob-12.19.0-py3-none-any.whl", hash = "sha256:7bbc2c9c16678f7a420367fef6b172ba8730a7e66df7f4d7a55d5b3c8216615b"}, + {file = "azure-storage-blob-12.19.1.tar.gz", hash = "sha256:13e16ba42fc54ac2c7e8f976062173a5c82b9ec0594728e134aac372965a11b0"}, + {file = "azure_storage_blob-12.19.1-py3-none-any.whl", hash = "sha256:c5530dc51c21c9564e4eb706cd499befca8819b10dd89716d3fc90d747556243"}, ] [package.dependencies] @@ -751,63 +751,63 @@ test = ["pytest", "pytest-timeout"] [[package]] name = "coverage" -version = "7.4.3" +version = "7.4.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, - {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, - {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, - {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, - {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, - {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, - {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, - {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, - {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, - {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, - {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, - {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, - {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, - {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c"}, + {file = "coverage-7.4.4-cp310-cp310-win32.whl", hash = "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d"}, + {file = "coverage-7.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b"}, + {file = "coverage-7.4.4-cp311-cp311-win32.whl", hash = "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286"}, + {file = "coverage-7.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9"}, + {file = "coverage-7.4.4-cp312-cp312-win32.whl", hash = "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0"}, + {file = "coverage-7.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c"}, + {file = "coverage-7.4.4-cp38-cp38-win32.whl", hash = "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e"}, + {file = "coverage-7.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade"}, + {file = "coverage-7.4.4-cp39-cp39-win32.whl", hash = "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57"}, + {file = "coverage-7.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c"}, + {file = "coverage-7.4.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677"}, + {file = "coverage-7.4.4.tar.gz", hash = "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49"}, ] [package.extras] @@ -894,69 +894,69 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] [[package]] name = "cython" -version = "3.0.8" +version = "3.0.9" description = "The Cython compiler for writing C extensions in the Python language." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "Cython-3.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a846e0a38e2b24e9a5c5dc74b0e54c6e29420d88d1dafabc99e0fc0f3e338636"}, - {file = "Cython-3.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45523fdc2b78d79b32834cc1cc12dc2ca8967af87e22a3ee1bff20e77c7f5520"}, - {file = "Cython-3.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa0b7f3f841fe087410cab66778e2d3fb20ae2d2078a2be3dffe66c6574be39"}, - {file = "Cython-3.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e87294e33e40c289c77a135f491cd721bd089f193f956f7b8ed5aa2d0b8c558f"}, - {file = "Cython-3.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a1df7a129344b1215c20096d33c00193437df1a8fcca25b71f17c23b1a44f782"}, - {file = "Cython-3.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:13c2a5e57a0358da467d97667297bf820b62a1a87ae47c5f87938b9bb593acbd"}, - {file = "Cython-3.0.8-cp310-cp310-win32.whl", hash = "sha256:96b028f044f5880e3cb18ecdcfc6c8d3ce9d0af28418d5ab464509f26d8adf12"}, - {file = "Cython-3.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:8140597a8b5cc4f119a1190f5a2228a84f5ca6d8d9ec386cfce24663f48b2539"}, - {file = "Cython-3.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aae26f9663e50caf9657148403d9874eea41770ecdd6caf381d177c2b1bb82ba"}, - {file = "Cython-3.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:547eb3cdb2f8c6f48e6865d5a741d9dd051c25b3ce076fbca571727977b28ac3"}, - {file = "Cython-3.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a567d4b9ba70b26db89d75b243529de9e649a2f56384287533cf91512705bee"}, - {file = "Cython-3.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51d1426263b0e82fb22bda8ea60dc77a428581cc19e97741011b938445d383f1"}, - {file = "Cython-3.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c26daaeccda072459b48d211415fd1e5507c06bcd976fa0d5b8b9f1063467d7b"}, - {file = "Cython-3.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:289ce7838208211cd166e975865fd73b0649bf118170b6cebaedfbdaf4a37795"}, - {file = "Cython-3.0.8-cp311-cp311-win32.whl", hash = "sha256:c8aa05f5e17f8042a3be052c24f2edc013fb8af874b0bf76907d16c51b4e7871"}, - {file = "Cython-3.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:000dc9e135d0eec6ecb2b40a5b02d0868a2f8d2e027a41b0fe16a908a9e6de02"}, - {file = "Cython-3.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:90d3fe31db55685d8cb97d43b0ec39ef614fcf660f83c77ed06aa670cb0e164f"}, - {file = "Cython-3.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e24791ddae2324e88e3c902a765595c738f19ae34ee66bfb1a6dac54b1833419"}, - {file = "Cython-3.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f020fa1c0552052e0660790b8153b79e3fc9a15dbd8f1d0b841fe5d204a6ae6"}, - {file = "Cython-3.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18bfa387d7a7f77d7b2526af69a65dbd0b731b8d941aaff5becff8e21f6d7717"}, - {file = "Cython-3.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fe81b339cffd87c0069c6049b4d33e28bdd1874625ee515785bf42c9fdff3658"}, - {file = "Cython-3.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80fd94c076e1e1b1ee40a309be03080b75f413e8997cddcf401a118879863388"}, - {file = "Cython-3.0.8-cp312-cp312-win32.whl", hash = "sha256:85077915a93e359a9b920280d214dc0cf8a62773e1f3d7d30fab8ea4daed670c"}, - {file = "Cython-3.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:0cb2dcc565c7851f75d496f724a384a790fab12d1b82461b663e66605bec429a"}, - {file = "Cython-3.0.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:870d2a0a7e3cbd5efa65aecdb38d715ea337a904ea7bb22324036e78fb7068e7"}, - {file = "Cython-3.0.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e8f2454128974905258d86534f4fd4f91d2f1343605657ecab779d80c9d6d5e"}, - {file = "Cython-3.0.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1949d6aa7bc792554bee2b67a9fe41008acbfe22f4f8df7b6ec7b799613a4b3"}, - {file = "Cython-3.0.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9f2c6e1b8f3bcd6cb230bac1843f85114780bb8be8614855b1628b36bb510e0"}, - {file = "Cython-3.0.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:05d7eddc668ae7993643f32c7661f25544e791edb745758672ea5b1a82ecffa6"}, - {file = "Cython-3.0.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bfabe115deef4ada5d23c87bddb11289123336dcc14347011832c07db616dd93"}, - {file = "Cython-3.0.8-cp36-cp36m-win32.whl", hash = "sha256:0c38c9f0bcce2df0c3347285863621be904ac6b64c5792d871130569d893efd7"}, - {file = "Cython-3.0.8-cp36-cp36m-win_amd64.whl", hash = "sha256:6c46939c3983217d140999de7c238c3141f56b1ea349e47ca49cae899969aa2c"}, - {file = "Cython-3.0.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:115f0a50f752da6c99941b103b5cb090da63eb206abbc7c2ad33856ffc73f064"}, - {file = "Cython-3.0.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c0f29246734561c90f36e70ed0506b61aa3d044e4cc4cba559065a2a741fae"}, - {file = "Cython-3.0.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ab75242869ff71e5665fe5c96f3378e79e792fa3c11762641b6c5afbbbbe026"}, - {file = "Cython-3.0.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6717c06e9cfc6c1df18543cd31a21f5d8e378a40f70c851fa2d34f0597037abc"}, - {file = "Cython-3.0.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9d3f74388db378a3c6fd06e79a809ed98df3f56484d317b81ee762dbf3c263e0"}, - {file = "Cython-3.0.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae7ac561fd8253a9ae96311e91d12af5f701383564edc11d6338a7b60b285a6f"}, - {file = "Cython-3.0.8-cp37-cp37m-win32.whl", hash = "sha256:97b2a45845b993304f1799664fa88da676ee19442b15fdcaa31f9da7e1acc434"}, - {file = "Cython-3.0.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9e2be2b340fea46fb849d378f9b80d3c08ff2e81e2bfbcdb656e2e3cd8c6b2dc"}, - {file = "Cython-3.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2cde23c555470db3f149ede78b518e8274853745289c956a0e06ad8d982e4db9"}, - {file = "Cython-3.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7990ca127e1f1beedaf8fc8bf66541d066ef4723ad7d8d47a7cbf842e0f47580"}, - {file = "Cython-3.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b983c8e6803f016146c26854d9150ddad5662960c804ea7f0c752c9266752f0"}, - {file = "Cython-3.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a973268d7ca1a2bdf78575e459a94a78e1a0a9bb62a7db0c50041949a73b02ff"}, - {file = "Cython-3.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:61a237bc9dd23c7faef0fcfce88c11c65d0c9bb73c74ccfa408b3a012073c20e"}, - {file = "Cython-3.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3a3d67f079598af49e90ff9655bf85bd358f093d727eb21ca2708f467c489cae"}, - {file = "Cython-3.0.8-cp38-cp38-win32.whl", hash = "sha256:17a642bb01a693e34c914106566f59844b4461665066613913463a719e0dd15d"}, - {file = "Cython-3.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:2cdfc32252f3b6dc7c94032ab744dcedb45286733443c294d8f909a4854e7f83"}, - {file = "Cython-3.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa97893d99385386925d00074654aeae3a98867f298d1e12ceaf38a9054a9bae"}, - {file = "Cython-3.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05c0bf9d085c031df8f583f0d506aa3be1692023de18c45d0aaf78685bbb944"}, - {file = "Cython-3.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de892422582f5758bd8de187e98ac829330ec1007bc42c661f687792999988a7"}, - {file = "Cython-3.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:314f2355a1f1d06e3c431eaad4708cf10037b5e91e4b231d89c913989d0bdafd"}, - {file = "Cython-3.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:78825a3774211e7d5089730f00cdf7f473042acc9ceb8b9eeebe13ed3a5541de"}, - {file = "Cython-3.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:df8093deabc55f37028190cf5e575c26aad23fc673f34b85d5f45076bc37ce39"}, - {file = "Cython-3.0.8-cp39-cp39-win32.whl", hash = "sha256:1aca1b97e0095b3a9a6c33eada3f661a4ed0d499067d121239b193e5ba3bb4f0"}, - {file = "Cython-3.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:16873d78be63bd38ffb759da7ab82814b36f56c769ee02b1d5859560e4c3ac3c"}, - {file = "Cython-3.0.8-py2.py3-none-any.whl", hash = "sha256:171b27051253d3f9108e9759e504ba59ff06e7f7ba944457f94deaf9c21bf0b6"}, - {file = "Cython-3.0.8.tar.gz", hash = "sha256:8333423d8fd5765e7cceea3a9985dd1e0a5dfeb2734629e1a2ed2d6233d39de6"}, + {file = "Cython-3.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:296bd30d4445ac61b66c9d766567f6e81a6e262835d261e903c60c891a6729d3"}, + {file = "Cython-3.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496b52845cb45568a69d6359a2c335135233003e708ea02155c10ce3548aa89"}, + {file = "Cython-3.0.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:858c3766b9aa3ab8a413392c72bbab1c144a9766b7c7bfdef64e2e414363fa0c"}, + {file = "Cython-3.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0eb1e6ef036028a52525fd9a012a556f6dd4788a0e8755fe864ba0e70cde2ff"}, + {file = "Cython-3.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c8191941073ea5896321de3c8c958fd66e5f304b0cd1f22c59edd0b86c4dd90d"}, + {file = "Cython-3.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e32b016030bc72a8a22a1f21f470a2f57573761a4f00fbfe8347263f4fbdb9f1"}, + {file = "Cython-3.0.9-cp310-cp310-win32.whl", hash = "sha256:d6f3ff1cd6123973fe03e0fb8ee936622f976c0c41138969975824d08886572b"}, + {file = "Cython-3.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:56f3b643dbe14449248bbeb9a63fe3878a24256664bc8c8ef6efd45d102596d8"}, + {file = "Cython-3.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:35e6665a20d6b8a152d72b7fd87dbb2af6bb6b18a235b71add68122d594dbd41"}, + {file = "Cython-3.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92f4960c40ad027bd8c364c50db11104eadc59ffeb9e5b7f605ca2f05946e20"}, + {file = "Cython-3.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38df37d0e732fbd9a2fef898788492e82b770c33d1e4ed12444bbc8a3b3f89c0"}, + {file = "Cython-3.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad7fd88ebaeaf2e76fd729a8919fae80dab3d6ac0005e28494261d52ff347a8f"}, + {file = "Cython-3.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1365d5f76bf4d19df3d19ce932584c9bb76e9fb096185168918ef9b36e06bfa4"}, + {file = "Cython-3.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c232e7f279388ac9625c3e5a5a9f0078a9334959c5d6458052c65bbbba895e1e"}, + {file = "Cython-3.0.9-cp311-cp311-win32.whl", hash = "sha256:357e2fad46a25030b0c0496487e01a9dc0fdd0c09df0897f554d8ba3c1bc4872"}, + {file = "Cython-3.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:1315aee506506e8d69cf6631d8769e6b10131fdcc0eb66df2698f2a3ddaeeff2"}, + {file = "Cython-3.0.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:157973807c2796addbed5fbc4d9c882ab34bbc60dc297ca729504901479d5df7"}, + {file = "Cython-3.0.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00b105b5d050645dd59e6767bc0f18b48a4aa11c85f42ec7dd8181606f4059e3"}, + {file = "Cython-3.0.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac5536d09bef240cae0416d5a703d298b74c7bbc397da803ac9d344e732d4369"}, + {file = "Cython-3.0.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09c44501d476d16aaa4cbc29c87f8c0f54fc20e69b650d59cbfa4863426fc70c"}, + {file = "Cython-3.0.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:cc9c3b9f20d8e298618e5ccd32083ca386e785b08f9893fbec4c50b6b85be772"}, + {file = "Cython-3.0.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a30d96938c633e3ec37000ac3796525da71254ef109e66bdfd78f29891af6454"}, + {file = "Cython-3.0.9-cp312-cp312-win32.whl", hash = "sha256:757ca93bdd80702546df4d610d2494ef2e74249cac4d5ba9464589fb464bd8a3"}, + {file = "Cython-3.0.9-cp312-cp312-win_amd64.whl", hash = "sha256:1dc320a9905ab95414013f6de805efbff9e17bb5fb3b90bbac533f017bec8136"}, + {file = "Cython-3.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4ae349960ebe0da0d33724eaa7f1eb866688fe5434cc67ce4dbc06d6a719fbfc"}, + {file = "Cython-3.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63d2537bf688247f76ded6dee28ebd26274f019309aef1eb4f2f9c5c482fde2d"}, + {file = "Cython-3.0.9-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36f5a2dfc724bea1f710b649f02d802d80fc18320c8e6396684ba4a48412445a"}, + {file = "Cython-3.0.9-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:deaf4197d4b0bcd5714a497158ea96a2bd6d0f9636095437448f7e06453cc83d"}, + {file = "Cython-3.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:000af6deb7412eb7ac0c635ff5e637fb8725dd0a7b88cc58dfc2b3de14e701c4"}, + {file = "Cython-3.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:15c7f5c2d35bed9aa5f2a51eaac0df23ae72f2dbacf62fc672dd6bfaa75d2d6f"}, + {file = "Cython-3.0.9-cp36-cp36m-win32.whl", hash = "sha256:f49aa4970cd3bec66ac22e701def16dca2a49c59cceba519898dd7526e0be2c0"}, + {file = "Cython-3.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:4558814fa025b193058d42eeee498a53d6b04b2980d01339fc2444b23fd98e58"}, + {file = "Cython-3.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:539cd1d74fd61f6cfc310fa6bbbad5adc144627f2b7486a07075d4e002fd6aad"}, + {file = "Cython-3.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3232926cd406ee02eabb732206f6e882c3aed9d58f0fea764013d9240405bcf"}, + {file = "Cython-3.0.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33b6ac376538a7fc8c567b85d3c71504308a9318702ec0485dd66c059f3165cb"}, + {file = "Cython-3.0.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2cc92504b5d22ac66031ffb827bd3a967fc75a5f0f76ab48bce62df19be6fdfd"}, + {file = "Cython-3.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:22b8fae756c5c0d8968691bed520876de452f216c28ec896a00739a12dba3bd9"}, + {file = "Cython-3.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9cda0d92a09f3520f29bd91009f1194ba9600777c02c30c6d2d4ac65fb63e40d"}, + {file = "Cython-3.0.9-cp37-cp37m-win32.whl", hash = "sha256:ec612418490941ed16c50c8d3784c7bdc4c4b2a10c361259871790b02ec8c1db"}, + {file = "Cython-3.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:976c8d2bedc91ff6493fc973d38b2dc01020324039e2af0e049704a8e1b22936"}, + {file = "Cython-3.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5055988b007c92256b6e9896441c3055556038c3497fcbf8c921a6c1fce90719"}, + {file = "Cython-3.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9360606d964c2d0492a866464efcf9d0a92715644eede3f6a2aa696de54a137"}, + {file = "Cython-3.0.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02c6e809f060bed073dc7cba1648077fe3b68208863d517c8b39f3920eecf9dd"}, + {file = "Cython-3.0.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95ed792c966f969cea7489c32ff90150b415c1f3567db8d5a9d489c7c1602dac"}, + {file = "Cython-3.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8edd59d22950b400b03ca78d27dc694d2836a92ef0cac4f64cb4b2ff902f7e25"}, + {file = "Cython-3.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4cf0ed273bf60e97922fcbbdd380c39693922a597760160b4b4355e6078ca188"}, + {file = "Cython-3.0.9-cp38-cp38-win32.whl", hash = "sha256:5eb9bd4ae12ebb2bc79a193d95aacf090fbd8d7013e11ed5412711650cb34934"}, + {file = "Cython-3.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:44457279da56e0f829bb1fc5a5dc0836e5d498dbcf9b2324f32f7cc9d2ec6569"}, + {file = "Cython-3.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4b419a1adc2af43f4660e2f6eaf1e4fac2dbac59490771eb8ac3d6063f22356"}, + {file = "Cython-3.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f836192140f033b2319a0128936367c295c2b32e23df05b03b672a6015757ea"}, + {file = "Cython-3.0.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fd198c1a7f8e9382904d622cc0efa3c184605881fd5262c64cbb7168c4c1ec5"}, + {file = "Cython-3.0.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a274fe9ca5c53fafbcf5c8f262f8ad6896206a466f0eeb40aaf36a7951e957c0"}, + {file = "Cython-3.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:158c38360bbc5063341b1e78d3737f1251050f89f58a3df0d10fb171c44262be"}, + {file = "Cython-3.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8bf30b045f7deda0014b042c1b41c1d272facc762ab657529e3b05505888e878"}, + {file = "Cython-3.0.9-cp39-cp39-win32.whl", hash = "sha256:9a001fd95c140c94d934078544ff60a3c46aca2dc86e75a76e4121d3cd1f4b33"}, + {file = "Cython-3.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:530c01c4aebba709c0ec9c7ecefe07177d0b9fd7ffee29450a118d92192ccbdf"}, + {file = "Cython-3.0.9-py2.py3-none-any.whl", hash = "sha256:bf96417714353c5454c2e3238fca9338599330cf51625cdc1ca698684465646f"}, + {file = "Cython-3.0.9.tar.gz", hash = "sha256:a2d354f059d1f055d34cfaa62c5b68bc78ac2ceab6407148d47fb508cf3ba4f3"}, ] [[package]] @@ -1061,35 +1061,35 @@ typing = ["typing-extensions (>=4.8)"] [[package]] name = "fiona" -version = "1.9.5" +version = "1.9.6" description = "Fiona reads and writes spatial data files" optional = false python-versions = ">=3.7" files = [ - {file = "fiona-1.9.5-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:5f40a40529ecfca5294260316cf987a0420c77a2f0cf0849f529d1afbccd093e"}, - {file = "fiona-1.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:374efe749143ecb5cfdd79b585d83917d2bf8ecfbfc6953c819586b336ce9c63"}, - {file = "fiona-1.9.5-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:35dae4b0308eb44617cdc4461ceb91f891d944fdebbcba5479efe524ec5db8de"}, - {file = "fiona-1.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:5b4c6a3df53bee8f85bb46685562b21b43346be1fe96419f18f70fa1ab8c561c"}, - {file = "fiona-1.9.5-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:6ad04c1877b9fd742871b11965606c6a52f40706f56a48d66a87cc3073943828"}, - {file = "fiona-1.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9fb9a24a8046c724787719e20557141b33049466145fc3e665764ac7caf5748c"}, - {file = "fiona-1.9.5-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:d722d7f01a66f4ab6cd08d156df3fdb92f0669cf5f8708ddcb209352f416f241"}, - {file = "fiona-1.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:7ede8ddc798f3d447536080c6db9a5fb73733ad8bdb190cb65eed4e289dd4c50"}, - {file = "fiona-1.9.5-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:8b098054a27c12afac4f819f98cb4d4bf2db9853f70b0c588d7d97d26e128c39"}, - {file = "fiona-1.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d9f29e9bcbb33232ff7fa98b4a3c2234db910c1dc6c4147fc36c0b8b930f2e0"}, - {file = "fiona-1.9.5-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:f1af08da4ecea5036cb81c9131946be4404245d1b434b5b24fd3871a1d4030d9"}, - {file = "fiona-1.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:c521e1135c78dec0d7774303e5a1b4c62e0efb0e602bb8f167550ef95e0a2691"}, - {file = "fiona-1.9.5-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:fce4b1dd98810cabccdaa1828430c7402d283295c2ae31bea4f34188ea9e88d7"}, - {file = "fiona-1.9.5-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:3ea04ec2d8c57b5f81a31200fb352cb3242aa106fc3e328963f30ffbdf0ff7c8"}, - {file = "fiona-1.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4877cc745d9e82b12b3eafce3719db75759c27bd8a695521202135b36b58c2e7"}, - {file = "fiona-1.9.5-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ac2c250f509ec19fad7959d75b531984776517ef3c1222d1cc5b4f962825880b"}, - {file = "fiona-1.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4df21906235928faad856c288cfea0298e9647f09c9a69a230535cbc8eadfa21"}, - {file = "fiona-1.9.5-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:81d502369493687746cb8d3cd77e5ada4447fb71d513721c9a1826e4fb32b23a"}, - {file = "fiona-1.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:ce3b29230ef70947ead4e701f3f82be81082b7f37fd4899009b1445cc8fc276a"}, - {file = "fiona-1.9.5-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:8b53ce8de773fcd5e2e102e833c8c58479edd8796a522f3d83ef9e08b62bfeea"}, - {file = "fiona-1.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bd2355e859a1cd24a3e485c6dc5003129f27a2051629def70036535ffa7e16a4"}, - {file = "fiona-1.9.5-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:9a2da52f865db1aff0eaf41cdd4c87a7c079b3996514e8e7a1ca38457309e825"}, - {file = "fiona-1.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:cfef6db5b779d463298b1113b50daa6c5b55f26f834dc9e37752116fa17277c1"}, - {file = "fiona-1.9.5.tar.gz", hash = "sha256:99e2604332caa7692855c2ae6ed91e1fffdf9b59449aa8032dd18e070e59a2f7"}, + {file = "fiona-1.9.6-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:63e528b5ea3d8b1038d788e7c65117835c787ba7fdc94b1b42f09c2cbc0aaff2"}, + {file = "fiona-1.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:918bd27d8625416672e834593970f96dff63215108f81efb876fe5c0bc58a3b4"}, + {file = "fiona-1.9.6-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:e313210b30d09ed8f829bf625599e248dadd78622728030221f6526580ff26c5"}, + {file = "fiona-1.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:89095c2d542325ee45894b8837e8048cdbb2f22274934e1be3b673ca628010d7"}, + {file = "fiona-1.9.6-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:98cea6f435843b2119731c6b0470e5b7386aa16b6aa7edabbf1ed93aefe029c3"}, + {file = "fiona-1.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4230eccbd896a79d1ebfa551d84bf90f512f7bcbe1ca61e3f82231321f1a532"}, + {file = "fiona-1.9.6-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:48b6218224e96de5e36b5eb259f37160092260e5de0dcd82ca200b1887aa9884"}, + {file = "fiona-1.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:c1dd5fbc29b7303bb87eb683455e8451e1a53bb8faf20ef97fdcd843c9e4a7f6"}, + {file = "fiona-1.9.6-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:42d8a0e5570948d3821c493b6141866d9a4d7a64edad2be4ecbb89f81904baac"}, + {file = "fiona-1.9.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39819fb8f5ec6d9971cb01b912b4431615a3d3f50c83798565d8ce41917930db"}, + {file = "fiona-1.9.6-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:9b53034efdf93ada9295b081e6a8280af7c75496a20df82d4c2ca46d65b85905"}, + {file = "fiona-1.9.6-cp312-cp312-win_amd64.whl", hash = "sha256:1dcd6eca7524535baf2a39d7981b4a46d33ae28c313934a7c3eae62eecf9dfa5"}, + {file = "fiona-1.9.6-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e5404ed08c711489abcb3a50a184816825b8af06eb73ad2a99e18b8e7b47c96a"}, + {file = "fiona-1.9.6-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:53bedd2989e255df1bf3378ae9c06d6d241ec273c280c544bb44ffffebb97fb0"}, + {file = "fiona-1.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:77653a08564a44e634c44cd74a068d2f55d1d4029edd16d1c8aadcc4d8cc1d2c"}, + {file = "fiona-1.9.6-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e7617563b36d2be99f048f0d0054b4d765f4aae454398f88f19de9c2c324b7f8"}, + {file = "fiona-1.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:50037c3b7a5f6f434b562b5b1a5b664f1caa7a4383b00af23cdb59bfc6ba852c"}, + {file = "fiona-1.9.6-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:bf51846ad602757bf27876f458c5c9f14b09421fac612f64273cc4e3fcabc441"}, + {file = "fiona-1.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:11af1afc1255642a7787fe112c29d01f968f1053e4d4700fc6f3bb879c1622e0"}, + {file = "fiona-1.9.6-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:52e8fec650b72fc5253d8f86b63859acc687182281c29bfacd3930496cf982d1"}, + {file = "fiona-1.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c9b92aa1badb2773e7cac19bef3064d73e9d80c67c42f0928db2520a04be6f2f"}, + {file = "fiona-1.9.6-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:0eaffbf3bfae9960484c0c08ea461b0c40e111497f04e9475ebf15ac7a22d9dc"}, + {file = "fiona-1.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f1b49d51a744874608b689f029766aa1e078dd72e94b44cf8eeef6d7bd2e9051"}, + {file = "fiona-1.9.6.tar.gz", hash = "sha256:791b3494f8b218c06ea56f892bd6ba893dfa23525347761d066fb7738acda3b1"}, ] [package.dependencies] @@ -1098,86 +1098,85 @@ certifi = "*" click = ">=8.0,<9.0" click-plugins = ">=1.0" cligj = ">=0.5" -setuptools = "*" six = "*" [package.extras] -all = ["Fiona[calc,s3,test]"] +all = ["fiona[calc,s3,test]"] calc = ["shapely"] s3 = ["boto3 (>=1.3.1)"] -test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] +test = ["fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"] [[package]] name = "flaky" -version = "3.7.0" -description = "Plugin for nose or pytest that automatically reruns flaky tests." +version = "3.8.1" +description = "Plugin for pytest that automatically reruns flaky tests." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.5" files = [ - {file = "flaky-3.7.0-py2.py3-none-any.whl", hash = "sha256:d6eda73cab5ae7364504b7c44670f70abed9e75f77dd116352f662817592ec9c"}, - {file = "flaky-3.7.0.tar.gz", hash = "sha256:3ad100780721a1911f57a165809b7ea265a7863305acb66708220820caf8aa0d"}, + {file = "flaky-3.8.1-py2.py3-none-any.whl", hash = "sha256:194ccf4f0d3a22b2de7130f4b62e45e977ac1b5ccad74d4d48f3005dcc38815e"}, + {file = "flaky-3.8.1.tar.gz", hash = "sha256:47204a81ec905f3d5acfbd61daeabcada8f9d4031616d9bcb0618461729699f5"}, ] [[package]] name = "flatbuffers" -version = "23.5.26" +version = "24.3.7" description = "The FlatBuffers serialization format for Python" optional = false python-versions = "*" files = [ - {file = "flatbuffers-23.5.26-py2.py3-none-any.whl", hash = "sha256:c0ff356da363087b915fde4b8b45bdda73432fc17cddb3c8157472eab1422ad1"}, - {file = "flatbuffers-23.5.26.tar.gz", hash = "sha256:9ea1144cac05ce5d86e2859f431c6cd5e66cd9c78c558317c7955fb8d4c78d89"}, + {file = "flatbuffers-24.3.7-py2.py3-none-any.whl", hash = "sha256:80c4f5dcad0ee76b7e349671a0d657f2fbba927a0244f88dd3f5ed6a3694e1fc"}, + {file = "flatbuffers-24.3.7.tar.gz", hash = "sha256:0895c22b9a6019ff2f4de2e5e2f7cd15914043e6e7033a94c0c6369422690f22"}, ] [[package]] name = "fonttools" -version = "4.49.0" +version = "4.50.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717"}, - {file = "fonttools-4.49.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc"}, - {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559"}, - {file = "fonttools-4.49.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29"}, - {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532"}, - {file = "fonttools-4.49.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828"}, - {file = "fonttools-4.49.0-cp310-cp310-win32.whl", hash = "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b"}, - {file = "fonttools-4.49.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf"}, - {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e"}, - {file = "fonttools-4.49.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814"}, - {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22"}, - {file = "fonttools-4.49.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942"}, - {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a"}, - {file = "fonttools-4.49.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86"}, - {file = "fonttools-4.49.0-cp311-cp311-win32.whl", hash = "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e"}, - {file = "fonttools-4.49.0-cp311-cp311-win_amd64.whl", hash = "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6"}, - {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075"}, - {file = "fonttools-4.49.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e"}, - {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff"}, - {file = "fonttools-4.49.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5"}, - {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb"}, - {file = "fonttools-4.49.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7"}, - {file = "fonttools-4.49.0-cp312-cp312-win32.whl", hash = "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880"}, - {file = "fonttools-4.49.0-cp312-cp312-win_amd64.whl", hash = "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034"}, - {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb"}, - {file = "fonttools-4.49.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4"}, - {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75"}, - {file = "fonttools-4.49.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9"}, - {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd"}, - {file = "fonttools-4.49.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036"}, - {file = "fonttools-4.49.0-cp38-cp38-win32.whl", hash = "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844"}, - {file = "fonttools-4.49.0-cp38-cp38-win_amd64.whl", hash = "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a"}, - {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc"}, - {file = "fonttools-4.49.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"}, - {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2"}, - {file = "fonttools-4.49.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42"}, - {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be"}, - {file = "fonttools-4.49.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c"}, - {file = "fonttools-4.49.0-cp39-cp39-win32.whl", hash = "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133"}, - {file = "fonttools-4.49.0-cp39-cp39-win_amd64.whl", hash = "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836"}, - {file = "fonttools-4.49.0-py3-none-any.whl", hash = "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18"}, - {file = "fonttools-4.49.0.tar.gz", hash = "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321"}, + {file = "fonttools-4.50.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effd303fb422f8ce06543a36ca69148471144c534cc25f30e5be752bc4f46736"}, + {file = "fonttools-4.50.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7913992ab836f621d06aabac118fc258b9947a775a607e1a737eb3a91c360335"}, + {file = "fonttools-4.50.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e0a1c5bd2f63da4043b63888534b52c5a1fd7ae187c8ffc64cbb7ae475b9dab"}, + {file = "fonttools-4.50.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d40fc98540fa5360e7ecf2c56ddf3c6e7dd04929543618fd7b5cc76e66390562"}, + {file = "fonttools-4.50.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fff65fbb7afe137bac3113827855e0204482727bddd00a806034ab0d3951d0d"}, + {file = "fonttools-4.50.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1aeae3dd2ee719074a9372c89ad94f7c581903306d76befdaca2a559f802472"}, + {file = "fonttools-4.50.0-cp310-cp310-win32.whl", hash = "sha256:e9623afa319405da33b43c85cceb0585a6f5d3a1d7c604daf4f7e1dd55c03d1f"}, + {file = "fonttools-4.50.0-cp310-cp310-win_amd64.whl", hash = "sha256:778c5f43e7e654ef7fe0605e80894930bc3a7772e2f496238e57218610140f54"}, + {file = "fonttools-4.50.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3dfb102e7f63b78c832e4539969167ffcc0375b013080e6472350965a5fe8048"}, + {file = "fonttools-4.50.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e58fe34cb379ba3d01d5d319d67dd3ce7ca9a47ad044ea2b22635cd2d1247fc"}, + {file = "fonttools-4.50.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c673ab40d15a442a4e6eb09bf007c1dda47c84ac1e2eecbdf359adacb799c24"}, + {file = "fonttools-4.50.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b3ac35cdcd1a4c90c23a5200212c1bb74fa05833cc7c14291d7043a52ca2aaa"}, + {file = "fonttools-4.50.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8844e7a2c5f7ecf977e82eb6b3014f025c8b454e046d941ece05b768be5847ae"}, + {file = "fonttools-4.50.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f849bd3c5c2249b49c98eca5aaebb920d2bfd92b3c69e84ca9bddf133e9f83f0"}, + {file = "fonttools-4.50.0-cp311-cp311-win32.whl", hash = "sha256:39293ff231b36b035575e81c14626dfc14407a20de5262f9596c2cbb199c3625"}, + {file = "fonttools-4.50.0-cp311-cp311-win_amd64.whl", hash = "sha256:c33d5023523b44d3481624f840c8646656a1def7630ca562f222eb3ead16c438"}, + {file = "fonttools-4.50.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b4a886a6dbe60100ba1cd24de962f8cd18139bd32808da80de1fa9f9f27bf1dc"}, + {file = "fonttools-4.50.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b2ca1837bfbe5eafa11313dbc7edada79052709a1fffa10cea691210af4aa1fa"}, + {file = "fonttools-4.50.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0493dd97ac8977e48ffc1476b932b37c847cbb87fd68673dee5182004906828"}, + {file = "fonttools-4.50.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77844e2f1b0889120b6c222fc49b2b75c3d88b930615e98893b899b9352a27ea"}, + {file = "fonttools-4.50.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3566bfb8c55ed9100afe1ba6f0f12265cd63a1387b9661eb6031a1578a28bad1"}, + {file = "fonttools-4.50.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:35e10ddbc129cf61775d58a14f2d44121178d89874d32cae1eac722e687d9019"}, + {file = "fonttools-4.50.0-cp312-cp312-win32.whl", hash = "sha256:cc8140baf9fa8f9b903f2b393a6c413a220fa990264b215bf48484f3d0bf8710"}, + {file = "fonttools-4.50.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ccc85fd96373ab73c59833b824d7a73846670a0cb1f3afbaee2b2c426a8f931"}, + {file = "fonttools-4.50.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e270a406219af37581d96c810172001ec536e29e5593aa40d4c01cca3e145aa6"}, + {file = "fonttools-4.50.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac2463de667233372e9e1c7e9de3d914b708437ef52a3199fdbf5a60184f190c"}, + {file = "fonttools-4.50.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47abd6669195abe87c22750dbcd366dc3a0648f1b7c93c2baa97429c4dc1506e"}, + {file = "fonttools-4.50.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:074841375e2e3d559aecc86e1224caf78e8b8417bb391e7d2506412538f21adc"}, + {file = "fonttools-4.50.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0743fd2191ad7ab43d78cd747215b12033ddee24fa1e088605a3efe80d6984de"}, + {file = "fonttools-4.50.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3d7080cce7be5ed65bee3496f09f79a82865a514863197ff4d4d177389e981b0"}, + {file = "fonttools-4.50.0-cp38-cp38-win32.whl", hash = "sha256:a467ba4e2eadc1d5cc1a11d355abb945f680473fbe30d15617e104c81f483045"}, + {file = "fonttools-4.50.0-cp38-cp38-win_amd64.whl", hash = "sha256:f77e048f805e00870659d6318fd89ef28ca4ee16a22b4c5e1905b735495fc422"}, + {file = "fonttools-4.50.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b6245eafd553c4e9a0708e93be51392bd2288c773523892fbd616d33fd2fda59"}, + {file = "fonttools-4.50.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a4062cc7e8de26f1603323ef3ae2171c9d29c8a9f5e067d555a2813cd5c7a7e0"}, + {file = "fonttools-4.50.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34692850dfd64ba06af61e5791a441f664cb7d21e7b544e8f385718430e8f8e4"}, + {file = "fonttools-4.50.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678dd95f26a67e02c50dcb5bf250f95231d455642afbc65a3b0bcdacd4e4dd38"}, + {file = "fonttools-4.50.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4f2ce7b0b295fe64ac0a85aef46a0f2614995774bd7bc643b85679c0283287f9"}, + {file = "fonttools-4.50.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d346f4dc2221bfb7ab652d1e37d327578434ce559baf7113b0f55768437fe6a0"}, + {file = "fonttools-4.50.0-cp39-cp39-win32.whl", hash = "sha256:a51eeaf52ba3afd70bf489be20e52fdfafe6c03d652b02477c6ce23c995222f4"}, + {file = "fonttools-4.50.0-cp39-cp39-win_amd64.whl", hash = "sha256:8639be40d583e5d9da67795aa3eeeda0488fb577a1d42ae11a5036f18fb16d93"}, + {file = "fonttools-4.50.0-py3-none-any.whl", hash = "sha256:48fa36da06247aa8282766cfd63efff1bb24e55f020f29a335939ed3844d20d3"}, + {file = "fonttools-4.50.0.tar.gz", hash = "sha256:fa5cf61058c7dbb104c2ac4e782bf1b2016a8cf2f69de6e4dd6a865d2c969bb5"}, ] [package.extras] @@ -1469,49 +1468,51 @@ toy-text = ["pygame (==2.1.3)", "pygame (==2.1.3)"] [[package]] name = "h3" -version = "3.7.6" +version = "3.7.7" description = "Hierarchical hexagonal geospatial indexing system" optional = false python-versions = "*" files = [ - {file = "h3-3.7.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:cd4a5103a86a7d98cffa3be77eb82080aa2e9d676bbd1661f3db9ecad7a4ef2b"}, - {file = "h3-3.7.6-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:231959dceb4cc4ae86fe4fe2c385b176ed81712549e787b889dfa66f583676df"}, - {file = "h3-3.7.6-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:b9de9da755c90bbc90d6c041396a20c91816cd86a0bafa3b8899681cfdc2c4c6"}, - {file = "h3-3.7.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cda9a427b0de0d4069115ec765118888f180d0db915b5bc0dba52f5ae957b789"}, - {file = "h3-3.7.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8bf1e080b9a47774754834e7f10155f3d2e3542bf895488a0519b2ae7d5b15db"}, - {file = "h3-3.7.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d3b93e3f38eb6c8fc5051d1b289b74614fb5f2415d272fea18085dea260d6b0"}, - {file = "h3-3.7.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783b2ca4448360c5a184fd43b84fc5554e3a8fd02738ff31349506189c5b4b49"}, - {file = "h3-3.7.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3bae8b95f21f20f04141a35f15c8caa74f2046eb01ef49e35fc45e6a8edfc8df"}, - {file = "h3-3.7.6-cp310-cp310-win_amd64.whl", hash = "sha256:6ca9dd410e250d37f24a87c4ecb0615bb6d44a3f90eb5dbbf1b5e3d4489b8703"}, - {file = "h3-3.7.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:991ee991f2ae41f629feb1cd32fa677b8512c72696eb0ad94fcf359d61184b2e"}, - {file = "h3-3.7.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fcbfff87d223279f8e38bbee3ebf52b1b96ae280e9e7de24674d3c284373d946"}, - {file = "h3-3.7.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eddf10d1d2139b3ea3ad1618c2074e1c47d3d36bddb5359e4955f5fd0b089d93"}, - {file = "h3-3.7.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76abc02f14a8df42fb5d80e6045023fb756c49d3cb08d69a8ceb9362b95d4bec"}, - {file = "h3-3.7.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc8030968586a7810aa192397ad9a4f7d7a963f57c9b3e210fc38de0aa5c2533"}, - {file = "h3-3.7.6-cp311-cp311-win_amd64.whl", hash = "sha256:1bdc790d91138e781973dcaade5231db7fe8a876330939e0903f602acc4fb64c"}, - {file = "h3-3.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:198718ab20a06ebe52f0aaafc02469e4a51964e5ba7990c3cc1d2fc32e7a54d9"}, - {file = "h3-3.7.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02faa911f2d8425c641a1f7c08f3dc9c10a5a3d81408832afa40748534b999c8"}, - {file = "h3-3.7.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4db92ceaeb9a51cc875c302cdc5e1aa27eed776d95943ee55c941bc2f219a3"}, - {file = "h3-3.7.6-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4810ddb3d91411a6cbf87a28108fe31712f618ef223c349e1f6675602af2c473"}, - {file = "h3-3.7.6-cp36-cp36m-win_amd64.whl", hash = "sha256:211ef3317dcf7863e2d01a97ab6da319b8451d78cd1633dd28faaf69e66bc321"}, - {file = "h3-3.7.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:99b81620608378fc9910a5c630b0f17eb939156fa13e1adc55229d31f8c3f5ca"}, - {file = "h3-3.7.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f3175bd3ea3ee528dbf49308e7215a58351ce425e1c3a9838ae22526663311"}, - {file = "h3-3.7.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d7b69015f5bab2525914fad370b96dc386437e19a14cfed3eb13868589263db"}, - {file = "h3-3.7.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d0c2890fa10fa8695c020569c8d55da79e2c552a39533de4ae6991c7acb122e1"}, - {file = "h3-3.7.6-cp37-cp37m-win_amd64.whl", hash = "sha256:1cd4f07c49721023c5fef401a4de03c47000705dfd116579dc6b61cad821305d"}, - {file = "h3-3.7.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f8d1db3dcd8f6ce7f54e061e6c9fbecbb5c3978b9e54e44af05a53787c4f99b3"}, - {file = "h3-3.7.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:495e37b1dee0ec46ccd88b278e571234b0d0d30648f161799d65a8d7f390b3f2"}, - {file = "h3-3.7.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e2c4808b7691b176c89ebf23c173b3b23dd4ce42f8f494b32c6e31ceee49af"}, - {file = "h3-3.7.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58b1298bf1068704c6d9426749c8ae6021b53d982d5153cc4161c7042ecd810"}, - {file = "h3-3.7.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a2872f695168c4700c73edd6eab9c6181387d7ea177de13b130ae61e613ff7de"}, - {file = "h3-3.7.6-cp38-cp38-win_amd64.whl", hash = "sha256:98c3951c3b67ca3de06ef70aa74a9752640a3eca9b4d68e0d5d8e4fc6fa72337"}, - {file = "h3-3.7.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0724d4645c1da59e02b3305050c52b93ce1d8971d1d139433d464fcc103249a6"}, - {file = "h3-3.7.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e1f6ec0f2246381ce3a7f72da1ce825a5474eb7c8fb25a2ea1f16c6606ce34a7"}, - {file = "h3-3.7.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1471ff4d3875b25b521eeec5c2b72abe27b8e6af10ab99b7da5c0de545b0e832"}, - {file = "h3-3.7.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb96f2caae519d0ed17acde625af528476dca121b0336d3eb776429d40284ef6"}, - {file = "h3-3.7.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b1b1bce0dee05175f8d422e50ffa1afacb9a7e78ae0963059aebfbef50e10175"}, - {file = "h3-3.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:36ea935833c37fdfd7ffbfc000d7cd20addcdf67f30b26a6b9bccb9210b03704"}, - {file = "h3-3.7.6.tar.gz", hash = "sha256:9bbd3dbac99532fa521d7d2e288ff55877bea3223b070f659ed7b5f8f1f213eb"}, + {file = "h3-3.7.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:951ecc9da0bcd5091670b13636928747bc98bc76891da0fa725524ec017cd9de"}, + {file = "h3-3.7.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26b9dd605541223ef927cc913deccb236cee024b16032f4a3e4387e2791479f2"}, + {file = "h3-3.7.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:996ebb32dc26dd607af7493149f94ce316117be6f42971f7b33bbd326ec695d2"}, + {file = "h3-3.7.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa2a4aa888cd9476788b874b4e11e178293f5b86e8461c36596bf183c242d417"}, + {file = "h3-3.7.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0256e42687470c6f0044ca78fe375fe32a654be8b5a8313b4a68f52f513389c6"}, + {file = "h3-3.7.7-cp310-cp310-win_amd64.whl", hash = "sha256:a3e2bc125490f900e0513c30480722f129bab1415f23040b6cd3a3f8d5a39336"}, + {file = "h3-3.7.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7d59018a50cd3b6d0ff0b18a54fdfcbaf2f79c13c831842f54fd2780c4b561ea"}, + {file = "h3-3.7.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e74526d941c1656fe162cc63b459b61aa83a15e257e9477b1570f26c544b51a"}, + {file = "h3-3.7.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c7398dbab685fcf3fe92f7c4c5901ab258bc66f7fa05fd1da8693375a10a549"}, + {file = "h3-3.7.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d22ea488ab5fe01c94070e9a6b3222916905a4d3f7a9d33cb2298c93fa0ffd3"}, + {file = "h3-3.7.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c94836155e8169be393980fc059f06481a14dd1913bd9cba609f6f1e8864c171"}, + {file = "h3-3.7.7-cp311-cp311-win_amd64.whl", hash = "sha256:836e74313ff55324485cd7e07783bc67df3191ec08a318035d7cd8ee0b0badab"}, + {file = "h3-3.7.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:51c2f63ef5a57e4b18ebc9c0eb56656433e280ec45ab487a514127bb6e7d6a1f"}, + {file = "h3-3.7.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d6e38dea47c220d9802af8e8bebc806f9f39358aee07b736191ff21e2c9921d"}, + {file = "h3-3.7.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e408342e94f558802a97bfcbe1baae2af8b1fd926ad9041d970ff9dbd0502099"}, + {file = "h3-3.7.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:644c3c84585aa4df62e81bc54fd305c4d6686324731de230b0ddbd7036ed172c"}, + {file = "h3-3.7.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bb4a3d5e82d0c89512dc71b4eac17976a29be29da250ba76bc94bc5b9e824f0e"}, + {file = "h3-3.7.7-cp312-cp312-win_amd64.whl", hash = "sha256:2ccff5f02589e80202597ed0b9f61ebd114e262e7dd0fe88059298602898192f"}, + {file = "h3-3.7.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ef2e71b619f984e71c4bd9d128152e2c7e3e788e2d2ec571b32cef1d295ddf38"}, + {file = "h3-3.7.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cb13f0213ed6da80e739355e5b62cfc81b7b1469af997be3384a6cbc3a1a750"}, + {file = "h3-3.7.7-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:701f72f703d892fb17e66b9fd7b6b2ad125e135b091eb7dd0ec11858b84d84d2"}, + {file = "h3-3.7.7-cp36-cp36m-win_amd64.whl", hash = "sha256:796622be7cb052690404c0ac03768183e51ae22505ce4a424b4537b2b7609fba"}, + {file = "h3-3.7.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bcd88a72d6aa97d0f3b3b87b7bfd9725a8909501e6cb9d0057d5b690b6bb37b0"}, + {file = "h3-3.7.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7358ba3f91193a2551c4a8d7ad7fd348e567b3a3581c9c161630029dfb23e07"}, + {file = "h3-3.7.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f34b204edc2e8f7d99a6db4ed1b5d202b7ea3ec6817d373ec432dee14efe04"}, + {file = "h3-3.7.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aa0f8ce89b5e694815ee7a5172a782d58f2652267329de7008354b110b53955"}, + {file = "h3-3.7.7-cp37-cp37m-win_amd64.whl", hash = "sha256:4c851baa1c2d4f29b01157ce2a4cdb1f3879fff5c36ff7861dad1526963a17a7"}, + {file = "h3-3.7.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6f3a9da5472820b0a4add342f96fe52f65fbb8f46984383885738517b38af69e"}, + {file = "h3-3.7.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1c57da776a3c1a01e2986b1f6a31d497ee0be8fcdbaaf9b23bb90f5a90eb8f0b"}, + {file = "h3-3.7.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a5c0c0ddd9c57694ecc3b9ba99cbef2842882f8943d6edc676a365e139dbc6d"}, + {file = "h3-3.7.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c1b5a0a652719b645387231bf6d7d4dd85150e4440a4ce72a804a10e86592ae"}, + {file = "h3-3.7.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:64f76dc827fef94e9f43f95a1daea2e11f2ad2e8c55deac072f3d59bd62412d4"}, + {file = "h3-3.7.7-cp38-cp38-win_amd64.whl", hash = "sha256:c993a36120d7f5607f24ba9e39caf715eaf9cd9d44f5d5660fd85e3f4e0c6bf7"}, + {file = "h3-3.7.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eb154d2af699870b888e10476e327c895078009d2d2a6ef2d053d7dcf0e2c270"}, + {file = "h3-3.7.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c96ad74e246bb7638d413efa8199dd4c58ee929424a4dcaadb16365195f77f87"}, + {file = "h3-3.7.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52901f14f8b6e2c82075fd52c0e70176b868f621d47b5dc93f468c510e963722"}, + {file = "h3-3.7.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9d82a0fcc647e7bab36ab2e7a7392d141edc95d113ccf972e0fb7b0ddf80a0"}, + {file = "h3-3.7.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f4417d09acb36f0452346052f576923d6e4334bff3459f217d6278d40397424"}, + {file = "h3-3.7.7-cp39-cp39-win_amd64.whl", hash = "sha256:7ae774cd43b057f68dc10c99e4522fa40ed6b32ab90b2df0025595ffa15e77a0"}, + {file = "h3-3.7.7.tar.gz", hash = "sha256:33d141c3cef0725a881771fd8cb80c06a0db84a6e4ca5c647ce095ae07c61e94"}, ] [package.extras] @@ -1610,22 +1611,22 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.1" +version = "7.0.2" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, - {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, + {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"}, + {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" @@ -2418,38 +2419,38 @@ files = [ [[package]] name = "mypy" -version = "1.8.0" +version = "1.9.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, - {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, - {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, - {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, - {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, - {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, - {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, - {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, - {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, - {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, - {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, - {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, - {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, - {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, - {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, - {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, - {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, - {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, - {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, - {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, - {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, - {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, - {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, + {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, + {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, + {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, + {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, + {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, + {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, + {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, + {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, + {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, + {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, + {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, + {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, + {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, + {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, + {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, + {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, + {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, + {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, + {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, + {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, + {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, + {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, ] [package.dependencies] @@ -2715,13 +2716,13 @@ numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""} [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] @@ -3114,22 +3115,22 @@ files = [ [[package]] name = "protobuf" -version = "4.25.3" +version = "5.26.0" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, - {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, - {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, - {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, - {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, - {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, - {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, - {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, - {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, + {file = "protobuf-5.26.0-cp310-abi3-win32.whl", hash = "sha256:f9ecc8eb6f18037e0cbf43256db0325d4723f429bca7ef5cd358b7c29d65f628"}, + {file = "protobuf-5.26.0-cp310-abi3-win_amd64.whl", hash = "sha256:dfd29f6eb34107dccf289a93d44fb6b131e68888d090b784b691775ac84e8213"}, + {file = "protobuf-5.26.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:7e47c57303466c867374a17b2b5e99c5a7c8b72a94118e2f28efb599f19b4069"}, + {file = "protobuf-5.26.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e184175276edc222e2d5e314a72521e10049938a9a4961fe4bea9b25d073c03f"}, + {file = "protobuf-5.26.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:6ee9d1aa02f951c5ce10bf8c6cfb7604133773038e33f913183c8b5201350600"}, + {file = "protobuf-5.26.0-cp38-cp38-win32.whl", hash = "sha256:2c334550e1cb4efac5c8a3987384bf13a4334abaf5ab59e40479e7b70ecd6b19"}, + {file = "protobuf-5.26.0-cp38-cp38-win_amd64.whl", hash = "sha256:8eef61a90631c21b06b4f492a27e199a269827f046de3bb68b61aa84fcf50905"}, + {file = "protobuf-5.26.0-cp39-cp39-win32.whl", hash = "sha256:ca825f4eecb8c342d2ec581e6a5ad1ad1a47bededaecd768e0d3451ae4aaac2b"}, + {file = "protobuf-5.26.0-cp39-cp39-win_amd64.whl", hash = "sha256:efd4f5894c50bd76cbcfdd668cd941021333861ed0f441c78a83d8254a01cc9f"}, + {file = "protobuf-5.26.0-py3-none-any.whl", hash = "sha256:a49b6c5359bf34fb7bf965bf21abfab4476e4527d822ab5289ee3bf73f291159"}, + {file = "protobuf-5.26.0.tar.gz", hash = "sha256:82f5870d74c99addfe4152777bdf8168244b9cf0ac65f8eccf045ddfa9d80d9b"}, ] [[package]] @@ -3495,2741 +3496,2762 @@ files = [ [[package]] name = "pyobjc" -version = "10.1" +version = "10.2" description = "Python<->ObjC Interoperability Module" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-10.1-py3-none-any.whl", hash = "sha256:2687ff02217e7b2aba52c6b948bccea864a8f034af6c90528564d496b343c418"}, - {file = "pyobjc-10.1.tar.gz", hash = "sha256:f54baff4c40d53c3fb3812816ebd130d3186805936628cc1f212f95979af5b98"}, -] - -[package.dependencies] -pyobjc-core = "10.1" -pyobjc-framework-Accessibility = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-Accounts = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-AddressBook = "10.1" -pyobjc-framework-AdServices = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-AdSupport = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-AppleScriptKit = "10.1" -pyobjc-framework-AppleScriptObjC = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-ApplicationServices = "10.1" -pyobjc-framework-AppTrackingTransparency = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-AudioVideoBridging = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-AuthenticationServices = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-AutomaticAssessmentConfiguration = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-Automator = "10.1" -pyobjc-framework-AVFoundation = {version = "10.1", markers = "platform_release >= \"11.0\""} -pyobjc-framework-AVKit = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-AVRouting = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-BackgroundAssets = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-BusinessChat = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-CalendarStore = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-CallKit = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-CFNetwork = "10.1" -pyobjc-framework-Cinematic = {version = "10.1", markers = "platform_release >= \"23.0\""} -pyobjc-framework-ClassKit = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-CloudKit = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-Cocoa = "10.1" -pyobjc-framework-Collaboration = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-ColorSync = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-Contacts = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-ContactsUI = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-CoreAudio = "10.1" -pyobjc-framework-CoreAudioKit = "10.1" -pyobjc-framework-CoreBluetooth = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-CoreData = "10.1" -pyobjc-framework-CoreHaptics = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-CoreLocation = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-CoreMedia = {version = "10.1", markers = "platform_release >= \"11.0\""} -pyobjc-framework-CoreMediaIO = {version = "10.1", markers = "platform_release >= \"11.0\""} -pyobjc-framework-CoreMIDI = "10.1" -pyobjc-framework-CoreML = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-CoreMotion = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-CoreServices = "10.1" -pyobjc-framework-CoreSpotlight = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-CoreText = "10.1" -pyobjc-framework-CoreWLAN = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-CryptoTokenKit = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-DataDetection = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-DeviceCheck = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-DictionaryServices = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-DiscRecording = "10.1" -pyobjc-framework-DiscRecordingUI = "10.1" -pyobjc-framework-DiskArbitration = "10.1" -pyobjc-framework-DVDPlayback = "10.1" -pyobjc-framework-EventKit = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-ExceptionHandling = "10.1" -pyobjc-framework-ExecutionPolicy = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-ExtensionKit = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-ExternalAccessory = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-FileProvider = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-FileProviderUI = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-FinderSync = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-FSEvents = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-GameCenter = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-GameController = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-GameKit = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-GameplayKit = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-HealthKit = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-ImageCaptureCore = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-InputMethodKit = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-InstallerPlugins = "10.1" -pyobjc-framework-InstantMessage = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-Intents = {version = "10.1", markers = "platform_release >= \"16.0\""} -pyobjc-framework-IntentsUI = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-IOBluetooth = "10.1" -pyobjc-framework-IOBluetoothUI = "10.1" -pyobjc-framework-IOSurface = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-iTunesLibrary = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-KernelManagement = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-LatentSemanticMapping = "10.1" -pyobjc-framework-LaunchServices = "10.1" -pyobjc-framework-libdispatch = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-libxpc = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-LinkPresentation = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-LocalAuthentication = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-LocalAuthenticationEmbeddedUI = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-MailKit = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-MapKit = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-MediaAccessibility = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-MediaLibrary = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-MediaPlayer = {version = "10.1", markers = "platform_release >= \"16.0\""} -pyobjc-framework-MediaToolbox = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-Metal = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-MetalFX = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-MetalKit = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-MetalPerformanceShaders = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-MetalPerformanceShadersGraph = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-MetricKit = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-MLCompute = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-ModelIO = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-MultipeerConnectivity = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-NaturalLanguage = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-NetFS = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-Network = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-NetworkExtension = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-NotificationCenter = {version = "10.1", markers = "platform_release >= \"14.0\""} -pyobjc-framework-OpenDirectory = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-OSAKit = "10.1" -pyobjc-framework-OSLog = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-PassKit = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-PencilKit = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-PHASE = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-Photos = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-PhotosUI = {version = "10.1", markers = "platform_release >= \"15.0\""} -pyobjc-framework-PreferencePanes = "10.1" -pyobjc-framework-PubSub = {version = "10.1", markers = "platform_release >= \"9.0\" and platform_release < \"18.0\""} -pyobjc-framework-PushKit = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-Quartz = "10.1" -pyobjc-framework-QuickLookThumbnailing = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-ReplayKit = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-SafariServices = {version = "10.1", markers = "platform_release >= \"16.0\""} -pyobjc-framework-SafetyKit = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-SceneKit = {version = "10.1", markers = "platform_release >= \"11.0\""} -pyobjc-framework-ScreenCaptureKit = {version = "10.1", markers = "platform_release >= \"21.4\""} -pyobjc-framework-ScreenSaver = "10.1" -pyobjc-framework-ScreenTime = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-ScriptingBridge = {version = "10.1", markers = "platform_release >= \"9.0\""} -pyobjc-framework-SearchKit = "10.1" -pyobjc-framework-Security = "10.1" -pyobjc-framework-SecurityFoundation = "10.1" -pyobjc-framework-SecurityInterface = "10.1" -pyobjc-framework-SensitiveContentAnalysis = {version = "10.1", markers = "platform_release >= \"23.0\""} -pyobjc-framework-ServiceManagement = {version = "10.1", markers = "platform_release >= \"10.0\""} -pyobjc-framework-SharedWithYou = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-SharedWithYouCore = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-ShazamKit = {version = "10.1", markers = "platform_release >= \"21.0\""} -pyobjc-framework-Social = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-SoundAnalysis = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-Speech = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-SpriteKit = {version = "10.1", markers = "platform_release >= \"13.0\""} -pyobjc-framework-StoreKit = {version = "10.1", markers = "platform_release >= \"11.0\""} -pyobjc-framework-Symbols = {version = "10.1", markers = "platform_release >= \"23.0\""} -pyobjc-framework-SyncServices = "10.1" -pyobjc-framework-SystemConfiguration = "10.1" -pyobjc-framework-SystemExtensions = {version = "10.1", markers = "platform_release >= \"19.0\""} -pyobjc-framework-ThreadNetwork = {version = "10.1", markers = "platform_release >= \"22.0\""} -pyobjc-framework-UniformTypeIdentifiers = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-UserNotifications = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-UserNotificationsUI = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-VideoSubscriberAccount = {version = "10.1", markers = "platform_release >= \"18.0\""} -pyobjc-framework-VideoToolbox = {version = "10.1", markers = "platform_release >= \"12.0\""} -pyobjc-framework-Virtualization = {version = "10.1", markers = "platform_release >= \"20.0\""} -pyobjc-framework-Vision = {version = "10.1", markers = "platform_release >= \"17.0\""} -pyobjc-framework-WebKit = "10.1" + {file = "pyobjc-10.2-py3-none-any.whl", hash = "sha256:976c8f8af49a91195307b3efbc2d63517be63aae2b4b3689dcff4f317669c23a"}, + {file = "pyobjc-10.2.tar.gz", hash = "sha256:bfea9891750ce3af6439ee102e8e417917f1a7ed7fc4f54b5da9d7457fbb7fc6"}, +] + +[package.dependencies] +pyobjc-core = "10.2" +pyobjc-framework-Accessibility = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-Accounts = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-AddressBook = "10.2" +pyobjc-framework-AdServices = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-AdSupport = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-AppleScriptKit = "10.2" +pyobjc-framework-AppleScriptObjC = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-ApplicationServices = "10.2" +pyobjc-framework-AppTrackingTransparency = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-AudioVideoBridging = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-AuthenticationServices = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-AutomaticAssessmentConfiguration = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-Automator = "10.2" +pyobjc-framework-AVFoundation = {version = "10.2", markers = "platform_release >= \"11.0\""} +pyobjc-framework-AVKit = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-AVRouting = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-BackgroundAssets = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-BrowserEngineKit = {version = "10.2", markers = "platform_release >= \"23.4\""} +pyobjc-framework-BusinessChat = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-CalendarStore = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-CallKit = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-CFNetwork = "10.2" +pyobjc-framework-Cinematic = {version = "10.2", markers = "platform_release >= \"23.0\""} +pyobjc-framework-ClassKit = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-CloudKit = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-Cocoa = "10.2" +pyobjc-framework-Collaboration = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-ColorSync = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-Contacts = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-ContactsUI = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-CoreAudio = "10.2" +pyobjc-framework-CoreAudioKit = "10.2" +pyobjc-framework-CoreBluetooth = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-CoreData = "10.2" +pyobjc-framework-CoreHaptics = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-CoreLocation = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-CoreMedia = {version = "10.2", markers = "platform_release >= \"11.0\""} +pyobjc-framework-CoreMediaIO = {version = "10.2", markers = "platform_release >= \"11.0\""} +pyobjc-framework-CoreMIDI = "10.2" +pyobjc-framework-CoreML = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-CoreMotion = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-CoreServices = "10.2" +pyobjc-framework-CoreSpotlight = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-CoreText = "10.2" +pyobjc-framework-CoreWLAN = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-CryptoTokenKit = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-DataDetection = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-DeviceCheck = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-DictionaryServices = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-DiscRecording = "10.2" +pyobjc-framework-DiscRecordingUI = "10.2" +pyobjc-framework-DiskArbitration = "10.2" +pyobjc-framework-DVDPlayback = "10.2" +pyobjc-framework-EventKit = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-ExceptionHandling = "10.2" +pyobjc-framework-ExecutionPolicy = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-ExtensionKit = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-ExternalAccessory = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-FileProvider = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-FileProviderUI = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-FinderSync = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-FSEvents = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-GameCenter = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-GameController = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-GameKit = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-GameplayKit = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-HealthKit = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-ImageCaptureCore = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-InputMethodKit = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-InstallerPlugins = "10.2" +pyobjc-framework-InstantMessage = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-Intents = {version = "10.2", markers = "platform_release >= \"16.0\""} +pyobjc-framework-IntentsUI = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-IOBluetooth = "10.2" +pyobjc-framework-IOBluetoothUI = "10.2" +pyobjc-framework-IOSurface = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-iTunesLibrary = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-KernelManagement = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-LatentSemanticMapping = "10.2" +pyobjc-framework-LaunchServices = "10.2" +pyobjc-framework-libdispatch = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-libxpc = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-LinkPresentation = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-LocalAuthentication = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-LocalAuthenticationEmbeddedUI = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-MailKit = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-MapKit = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-MediaAccessibility = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-MediaLibrary = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-MediaPlayer = {version = "10.2", markers = "platform_release >= \"16.0\""} +pyobjc-framework-MediaToolbox = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-Metal = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-MetalFX = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-MetalKit = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-MetalPerformanceShaders = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-MetalPerformanceShadersGraph = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-MetricKit = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-MLCompute = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-ModelIO = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-MultipeerConnectivity = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-NaturalLanguage = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-NetFS = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-Network = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-NetworkExtension = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-NotificationCenter = {version = "10.2", markers = "platform_release >= \"14.0\""} +pyobjc-framework-OpenDirectory = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-OSAKit = "10.2" +pyobjc-framework-OSLog = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-PassKit = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-PencilKit = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-PHASE = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-Photos = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-PhotosUI = {version = "10.2", markers = "platform_release >= \"15.0\""} +pyobjc-framework-PreferencePanes = "10.2" +pyobjc-framework-PubSub = {version = "10.2", markers = "platform_release >= \"9.0\" and platform_release < \"18.0\""} +pyobjc-framework-PushKit = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-Quartz = "10.2" +pyobjc-framework-QuickLookThumbnailing = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-ReplayKit = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-SafariServices = {version = "10.2", markers = "platform_release >= \"16.0\""} +pyobjc-framework-SafetyKit = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-SceneKit = {version = "10.2", markers = "platform_release >= \"11.0\""} +pyobjc-framework-ScreenCaptureKit = {version = "10.2", markers = "platform_release >= \"21.4\""} +pyobjc-framework-ScreenSaver = "10.2" +pyobjc-framework-ScreenTime = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-ScriptingBridge = {version = "10.2", markers = "platform_release >= \"9.0\""} +pyobjc-framework-SearchKit = "10.2" +pyobjc-framework-Security = "10.2" +pyobjc-framework-SecurityFoundation = "10.2" +pyobjc-framework-SecurityInterface = "10.2" +pyobjc-framework-SensitiveContentAnalysis = {version = "10.2", markers = "platform_release >= \"23.0\""} +pyobjc-framework-ServiceManagement = {version = "10.2", markers = "platform_release >= \"10.0\""} +pyobjc-framework-SharedWithYou = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-SharedWithYouCore = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-ShazamKit = {version = "10.2", markers = "platform_release >= \"21.0\""} +pyobjc-framework-Social = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-SoundAnalysis = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-Speech = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-SpriteKit = {version = "10.2", markers = "platform_release >= \"13.0\""} +pyobjc-framework-StoreKit = {version = "10.2", markers = "platform_release >= \"11.0\""} +pyobjc-framework-Symbols = {version = "10.2", markers = "platform_release >= \"23.0\""} +pyobjc-framework-SyncServices = "10.2" +pyobjc-framework-SystemConfiguration = "10.2" +pyobjc-framework-SystemExtensions = {version = "10.2", markers = "platform_release >= \"19.0\""} +pyobjc-framework-ThreadNetwork = {version = "10.2", markers = "platform_release >= \"22.0\""} +pyobjc-framework-UniformTypeIdentifiers = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-UserNotifications = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-UserNotificationsUI = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-VideoSubscriberAccount = {version = "10.2", markers = "platform_release >= \"18.0\""} +pyobjc-framework-VideoToolbox = {version = "10.2", markers = "platform_release >= \"12.0\""} +pyobjc-framework-Virtualization = {version = "10.2", markers = "platform_release >= \"20.0\""} +pyobjc-framework-Vision = {version = "10.2", markers = "platform_release >= \"17.0\""} +pyobjc-framework-WebKit = "10.2" [package.extras] -allbindings = ["pyobjc-core (==10.1)", "pyobjc-framework-AVFoundation (==10.1)", "pyobjc-framework-AVKit (==10.1)", "pyobjc-framework-AVRouting (==10.1)", "pyobjc-framework-Accessibility (==10.1)", "pyobjc-framework-Accounts (==10.1)", "pyobjc-framework-AdServices (==10.1)", "pyobjc-framework-AdSupport (==10.1)", "pyobjc-framework-AddressBook (==10.1)", "pyobjc-framework-AppTrackingTransparency (==10.1)", "pyobjc-framework-AppleScriptKit (==10.1)", "pyobjc-framework-AppleScriptObjC (==10.1)", "pyobjc-framework-ApplicationServices (==10.1)", "pyobjc-framework-AudioVideoBridging (==10.1)", "pyobjc-framework-AuthenticationServices (==10.1)", "pyobjc-framework-AutomaticAssessmentConfiguration (==10.1)", "pyobjc-framework-Automator (==10.1)", "pyobjc-framework-BackgroundAssets (==10.1)", "pyobjc-framework-BusinessChat (==10.1)", "pyobjc-framework-CFNetwork (==10.1)", "pyobjc-framework-CalendarStore (==10.1)", "pyobjc-framework-CallKit (==10.1)", "pyobjc-framework-Cinematic (==10.1)", "pyobjc-framework-ClassKit (==10.1)", "pyobjc-framework-CloudKit (==10.1)", "pyobjc-framework-Cocoa (==10.1)", "pyobjc-framework-Collaboration (==10.1)", "pyobjc-framework-ColorSync (==10.1)", "pyobjc-framework-Contacts (==10.1)", "pyobjc-framework-ContactsUI (==10.1)", "pyobjc-framework-CoreAudio (==10.1)", "pyobjc-framework-CoreAudioKit (==10.1)", "pyobjc-framework-CoreBluetooth (==10.1)", "pyobjc-framework-CoreData (==10.1)", "pyobjc-framework-CoreHaptics (==10.1)", "pyobjc-framework-CoreLocation (==10.1)", "pyobjc-framework-CoreMIDI (==10.1)", "pyobjc-framework-CoreML (==10.1)", "pyobjc-framework-CoreMedia (==10.1)", "pyobjc-framework-CoreMediaIO (==10.1)", "pyobjc-framework-CoreMotion (==10.1)", "pyobjc-framework-CoreServices (==10.1)", "pyobjc-framework-CoreSpotlight (==10.1)", "pyobjc-framework-CoreText (==10.1)", "pyobjc-framework-CoreWLAN (==10.1)", "pyobjc-framework-CryptoTokenKit (==10.1)", "pyobjc-framework-DVDPlayback (==10.1)", "pyobjc-framework-DataDetection (==10.1)", "pyobjc-framework-DeviceCheck (==10.1)", "pyobjc-framework-DictionaryServices (==10.1)", "pyobjc-framework-DiscRecording (==10.1)", "pyobjc-framework-DiscRecordingUI (==10.1)", "pyobjc-framework-DiskArbitration (==10.1)", "pyobjc-framework-EventKit (==10.1)", "pyobjc-framework-ExceptionHandling (==10.1)", "pyobjc-framework-ExecutionPolicy (==10.1)", "pyobjc-framework-ExtensionKit (==10.1)", "pyobjc-framework-ExternalAccessory (==10.1)", "pyobjc-framework-FSEvents (==10.1)", "pyobjc-framework-FileProvider (==10.1)", "pyobjc-framework-FileProviderUI (==10.1)", "pyobjc-framework-FinderSync (==10.1)", "pyobjc-framework-GameCenter (==10.1)", "pyobjc-framework-GameController (==10.1)", "pyobjc-framework-GameKit (==10.1)", "pyobjc-framework-GameplayKit (==10.1)", "pyobjc-framework-HealthKit (==10.1)", "pyobjc-framework-IOBluetooth (==10.1)", "pyobjc-framework-IOBluetoothUI (==10.1)", "pyobjc-framework-IOSurface (==10.1)", "pyobjc-framework-ImageCaptureCore (==10.1)", "pyobjc-framework-InputMethodKit (==10.1)", "pyobjc-framework-InstallerPlugins (==10.1)", "pyobjc-framework-InstantMessage (==10.1)", "pyobjc-framework-Intents (==10.1)", "pyobjc-framework-IntentsUI (==10.1)", "pyobjc-framework-KernelManagement (==10.1)", "pyobjc-framework-LatentSemanticMapping (==10.1)", "pyobjc-framework-LaunchServices (==10.1)", "pyobjc-framework-LinkPresentation (==10.1)", "pyobjc-framework-LocalAuthentication (==10.1)", "pyobjc-framework-LocalAuthenticationEmbeddedUI (==10.1)", "pyobjc-framework-MLCompute (==10.1)", "pyobjc-framework-MailKit (==10.1)", "pyobjc-framework-MapKit (==10.1)", "pyobjc-framework-MediaAccessibility (==10.1)", "pyobjc-framework-MediaLibrary (==10.1)", "pyobjc-framework-MediaPlayer (==10.1)", "pyobjc-framework-MediaToolbox (==10.1)", "pyobjc-framework-Metal (==10.1)", "pyobjc-framework-MetalFX (==10.1)", "pyobjc-framework-MetalKit (==10.1)", "pyobjc-framework-MetalPerformanceShaders (==10.1)", "pyobjc-framework-MetalPerformanceShadersGraph (==10.1)", "pyobjc-framework-MetricKit (==10.1)", "pyobjc-framework-ModelIO (==10.1)", "pyobjc-framework-MultipeerConnectivity (==10.1)", "pyobjc-framework-NaturalLanguage (==10.1)", "pyobjc-framework-NetFS (==10.1)", "pyobjc-framework-Network (==10.1)", "pyobjc-framework-NetworkExtension (==10.1)", "pyobjc-framework-NotificationCenter (==10.1)", "pyobjc-framework-OSAKit (==10.1)", "pyobjc-framework-OSLog (==10.1)", "pyobjc-framework-OpenDirectory (==10.1)", "pyobjc-framework-PHASE (==10.1)", "pyobjc-framework-PassKit (==10.1)", "pyobjc-framework-PencilKit (==10.1)", "pyobjc-framework-Photos (==10.1)", "pyobjc-framework-PhotosUI (==10.1)", "pyobjc-framework-PreferencePanes (==10.1)", "pyobjc-framework-PubSub (==10.1)", "pyobjc-framework-PushKit (==10.1)", "pyobjc-framework-Quartz (==10.1)", "pyobjc-framework-QuickLookThumbnailing (==10.1)", "pyobjc-framework-ReplayKit (==10.1)", "pyobjc-framework-SafariServices (==10.1)", "pyobjc-framework-SafetyKit (==10.1)", "pyobjc-framework-SceneKit (==10.1)", "pyobjc-framework-ScreenCaptureKit (==10.1)", "pyobjc-framework-ScreenSaver (==10.1)", "pyobjc-framework-ScreenTime (==10.1)", "pyobjc-framework-ScriptingBridge (==10.1)", "pyobjc-framework-SearchKit (==10.1)", "pyobjc-framework-Security (==10.1)", "pyobjc-framework-SecurityFoundation (==10.1)", "pyobjc-framework-SecurityInterface (==10.1)", "pyobjc-framework-SensitiveContentAnalysis (==10.1)", "pyobjc-framework-ServiceManagement (==10.1)", "pyobjc-framework-SharedWithYou (==10.1)", "pyobjc-framework-SharedWithYouCore (==10.1)", "pyobjc-framework-ShazamKit (==10.1)", "pyobjc-framework-Social (==10.1)", "pyobjc-framework-SoundAnalysis (==10.1)", "pyobjc-framework-Speech (==10.1)", "pyobjc-framework-SpriteKit (==10.1)", "pyobjc-framework-StoreKit (==10.1)", "pyobjc-framework-Symbols (==10.1)", "pyobjc-framework-SyncServices (==10.1)", "pyobjc-framework-SystemConfiguration (==10.1)", "pyobjc-framework-SystemExtensions (==10.1)", "pyobjc-framework-ThreadNetwork (==10.1)", "pyobjc-framework-UniformTypeIdentifiers (==10.1)", "pyobjc-framework-UserNotifications (==10.1)", "pyobjc-framework-UserNotificationsUI (==10.1)", "pyobjc-framework-VideoSubscriberAccount (==10.1)", "pyobjc-framework-VideoToolbox (==10.1)", "pyobjc-framework-Virtualization (==10.1)", "pyobjc-framework-Vision (==10.1)", "pyobjc-framework-WebKit (==10.1)", "pyobjc-framework-iTunesLibrary (==10.1)", "pyobjc-framework-libdispatch (==10.1)", "pyobjc-framework-libxpc (==10.1)"] +allbindings = ["pyobjc-core (==10.2)", "pyobjc-framework-AVFoundation (==10.2)", "pyobjc-framework-AVKit (==10.2)", "pyobjc-framework-AVRouting (==10.2)", "pyobjc-framework-Accessibility (==10.2)", "pyobjc-framework-Accounts (==10.2)", "pyobjc-framework-AdServices (==10.2)", "pyobjc-framework-AdSupport (==10.2)", "pyobjc-framework-AddressBook (==10.2)", "pyobjc-framework-AppTrackingTransparency (==10.2)", "pyobjc-framework-AppleScriptKit (==10.2)", "pyobjc-framework-AppleScriptObjC (==10.2)", "pyobjc-framework-ApplicationServices (==10.2)", "pyobjc-framework-AudioVideoBridging (==10.2)", "pyobjc-framework-AuthenticationServices (==10.2)", "pyobjc-framework-AutomaticAssessmentConfiguration (==10.2)", "pyobjc-framework-Automator (==10.2)", "pyobjc-framework-BackgroundAssets (==10.2)", "pyobjc-framework-BrowserEngineKit (==10.2)", "pyobjc-framework-BusinessChat (==10.2)", "pyobjc-framework-CFNetwork (==10.2)", "pyobjc-framework-CalendarStore (==10.2)", "pyobjc-framework-CallKit (==10.2)", "pyobjc-framework-Cinematic (==10.2)", "pyobjc-framework-ClassKit (==10.2)", "pyobjc-framework-CloudKit (==10.2)", "pyobjc-framework-Cocoa (==10.2)", "pyobjc-framework-Collaboration (==10.2)", "pyobjc-framework-ColorSync (==10.2)", "pyobjc-framework-Contacts (==10.2)", "pyobjc-framework-ContactsUI (==10.2)", "pyobjc-framework-CoreAudio (==10.2)", "pyobjc-framework-CoreAudioKit (==10.2)", "pyobjc-framework-CoreBluetooth (==10.2)", "pyobjc-framework-CoreData (==10.2)", "pyobjc-framework-CoreHaptics (==10.2)", "pyobjc-framework-CoreLocation (==10.2)", "pyobjc-framework-CoreMIDI (==10.2)", "pyobjc-framework-CoreML (==10.2)", "pyobjc-framework-CoreMedia (==10.2)", "pyobjc-framework-CoreMediaIO (==10.2)", "pyobjc-framework-CoreMotion (==10.2)", "pyobjc-framework-CoreServices (==10.2)", "pyobjc-framework-CoreSpotlight (==10.2)", "pyobjc-framework-CoreText (==10.2)", "pyobjc-framework-CoreWLAN (==10.2)", "pyobjc-framework-CryptoTokenKit (==10.2)", "pyobjc-framework-DVDPlayback (==10.2)", "pyobjc-framework-DataDetection (==10.2)", "pyobjc-framework-DeviceCheck (==10.2)", "pyobjc-framework-DictionaryServices (==10.2)", "pyobjc-framework-DiscRecording (==10.2)", "pyobjc-framework-DiscRecordingUI (==10.2)", "pyobjc-framework-DiskArbitration (==10.2)", "pyobjc-framework-EventKit (==10.2)", "pyobjc-framework-ExceptionHandling (==10.2)", "pyobjc-framework-ExecutionPolicy (==10.2)", "pyobjc-framework-ExtensionKit (==10.2)", "pyobjc-framework-ExternalAccessory (==10.2)", "pyobjc-framework-FSEvents (==10.2)", "pyobjc-framework-FileProvider (==10.2)", "pyobjc-framework-FileProviderUI (==10.2)", "pyobjc-framework-FinderSync (==10.2)", "pyobjc-framework-GameCenter (==10.2)", "pyobjc-framework-GameController (==10.2)", "pyobjc-framework-GameKit (==10.2)", "pyobjc-framework-GameplayKit (==10.2)", "pyobjc-framework-HealthKit (==10.2)", "pyobjc-framework-IOBluetooth (==10.2)", "pyobjc-framework-IOBluetoothUI (==10.2)", "pyobjc-framework-IOSurface (==10.2)", "pyobjc-framework-ImageCaptureCore (==10.2)", "pyobjc-framework-InputMethodKit (==10.2)", "pyobjc-framework-InstallerPlugins (==10.2)", "pyobjc-framework-InstantMessage (==10.2)", "pyobjc-framework-Intents (==10.2)", "pyobjc-framework-IntentsUI (==10.2)", "pyobjc-framework-KernelManagement (==10.2)", "pyobjc-framework-LatentSemanticMapping (==10.2)", "pyobjc-framework-LaunchServices (==10.2)", "pyobjc-framework-LinkPresentation (==10.2)", "pyobjc-framework-LocalAuthentication (==10.2)", "pyobjc-framework-LocalAuthenticationEmbeddedUI (==10.2)", "pyobjc-framework-MLCompute (==10.2)", "pyobjc-framework-MailKit (==10.2)", "pyobjc-framework-MapKit (==10.2)", "pyobjc-framework-MediaAccessibility (==10.2)", "pyobjc-framework-MediaLibrary (==10.2)", "pyobjc-framework-MediaPlayer (==10.2)", "pyobjc-framework-MediaToolbox (==10.2)", "pyobjc-framework-Metal (==10.2)", "pyobjc-framework-MetalFX (==10.2)", "pyobjc-framework-MetalKit (==10.2)", "pyobjc-framework-MetalPerformanceShaders (==10.2)", "pyobjc-framework-MetalPerformanceShadersGraph (==10.2)", "pyobjc-framework-MetricKit (==10.2)", "pyobjc-framework-ModelIO (==10.2)", "pyobjc-framework-MultipeerConnectivity (==10.2)", "pyobjc-framework-NaturalLanguage (==10.2)", "pyobjc-framework-NetFS (==10.2)", "pyobjc-framework-Network (==10.2)", "pyobjc-framework-NetworkExtension (==10.2)", "pyobjc-framework-NotificationCenter (==10.2)", "pyobjc-framework-OSAKit (==10.2)", "pyobjc-framework-OSLog (==10.2)", "pyobjc-framework-OpenDirectory (==10.2)", "pyobjc-framework-PHASE (==10.2)", "pyobjc-framework-PassKit (==10.2)", "pyobjc-framework-PencilKit (==10.2)", "pyobjc-framework-Photos (==10.2)", "pyobjc-framework-PhotosUI (==10.2)", "pyobjc-framework-PreferencePanes (==10.2)", "pyobjc-framework-PubSub (==10.2)", "pyobjc-framework-PushKit (==10.2)", "pyobjc-framework-Quartz (==10.2)", "pyobjc-framework-QuickLookThumbnailing (==10.2)", "pyobjc-framework-ReplayKit (==10.2)", "pyobjc-framework-SafariServices (==10.2)", "pyobjc-framework-SafetyKit (==10.2)", "pyobjc-framework-SceneKit (==10.2)", "pyobjc-framework-ScreenCaptureKit (==10.2)", "pyobjc-framework-ScreenSaver (==10.2)", "pyobjc-framework-ScreenTime (==10.2)", "pyobjc-framework-ScriptingBridge (==10.2)", "pyobjc-framework-SearchKit (==10.2)", "pyobjc-framework-Security (==10.2)", "pyobjc-framework-SecurityFoundation (==10.2)", "pyobjc-framework-SecurityInterface (==10.2)", "pyobjc-framework-SensitiveContentAnalysis (==10.2)", "pyobjc-framework-ServiceManagement (==10.2)", "pyobjc-framework-SharedWithYou (==10.2)", "pyobjc-framework-SharedWithYouCore (==10.2)", "pyobjc-framework-ShazamKit (==10.2)", "pyobjc-framework-Social (==10.2)", "pyobjc-framework-SoundAnalysis (==10.2)", "pyobjc-framework-Speech (==10.2)", "pyobjc-framework-SpriteKit (==10.2)", "pyobjc-framework-StoreKit (==10.2)", "pyobjc-framework-Symbols (==10.2)", "pyobjc-framework-SyncServices (==10.2)", "pyobjc-framework-SystemConfiguration (==10.2)", "pyobjc-framework-SystemExtensions (==10.2)", "pyobjc-framework-ThreadNetwork (==10.2)", "pyobjc-framework-UniformTypeIdentifiers (==10.2)", "pyobjc-framework-UserNotifications (==10.2)", "pyobjc-framework-UserNotificationsUI (==10.2)", "pyobjc-framework-VideoSubscriberAccount (==10.2)", "pyobjc-framework-VideoToolbox (==10.2)", "pyobjc-framework-Virtualization (==10.2)", "pyobjc-framework-Vision (==10.2)", "pyobjc-framework-WebKit (==10.2)", "pyobjc-framework-iTunesLibrary (==10.2)", "pyobjc-framework-libdispatch (==10.2)", "pyobjc-framework-libxpc (==10.2)"] [[package]] name = "pyobjc-core" -version = "10.1" +version = "10.2" description = "Python<->ObjC Interoperability Module" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-core-10.1.tar.gz", hash = "sha256:1844f1c8e282839e6fdcb9a9722396c1c12fb1e9331eb68828a26f28a3b2b2b1"}, - {file = "pyobjc_core-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2a72a88222539ad07b5c8be411edc52ff9147d7cef311a2c849869d7bb9603fd"}, - {file = "pyobjc_core-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fe1b9987b7b0437685fb529832876c2a8463500114960d4e76bb8ae96b6bf208"}, - {file = "pyobjc_core-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9f628779c345d3abd0e20048fb0e256d894c22254577a81a6dcfdb92c3647682"}, - {file = "pyobjc_core-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25a9e5a2de19238787d24cfa7def6b7fbb94bbe89c0e3109f71c1cb108e8ab44"}, - {file = "pyobjc_core-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:2d43205d3a784aa87055b84c0ec0dfa76498e5f18d1ad16bdc58a3dcf5a7d5d0"}, - {file = "pyobjc_core-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0aa9799b5996a893944999a2f1afcf1de119cab3551c169ad9f54d12e1d38c99"}, + {file = "pyobjc-core-10.2.tar.gz", hash = "sha256:0153206e15d0e0d7abd53ee8a7fbaf5606602a032e177a028fc8589516a8771c"}, + {file = "pyobjc_core-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b8eab50ce7f17017a0f1d68c3b7e88bb1bb033415fdff62b8e0a9ee4ab72f242"}, + {file = "pyobjc_core-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f2115971463073426ab926416e17e5c16de5b90d1a1f2a2d8724637eb1c21308"}, + {file = "pyobjc_core-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a70546246177c23acb323c9324330e37638f1a0a3d13664abcba3bb75e43012c"}, + {file = "pyobjc_core-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a9b5a215080d13bd7526031d21d5eb27a410780878d863f486053a0eba7ca9a5"}, + {file = "pyobjc_core-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:eb1ab700a44bcc4ceb125091dfaae0b998b767b49990df5fdc83eb58158d8e3f"}, + {file = "pyobjc_core-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9a7163aff9c47d654f835f80361c1b112886ec754800d34e75d1e02ff52c3d7"}, ] [[package]] name = "pyobjc-framework-accessibility" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Accessibility on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Accessibility-10.1.tar.gz", hash = "sha256:70b812cf2b04b57a520c3fde9df4184c2783795fb355b416a8058114e52ad24a"}, - {file = "pyobjc_framework_Accessibility-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ef8524f2b67240fb3c3f7928f2d73e9050a8b80e18db8336e7ba4d4ba1d368df"}, - {file = "pyobjc_framework_Accessibility-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d351d7799b197524a200c54bebe450e87f9c52812f6162811b7e84823e8946df"}, - {file = "pyobjc_framework_Accessibility-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:1dc4e0acedaa0232103714dd2daa3244a628426bee6e933078c89e8eb86b7961"}, + {file = "pyobjc-framework-Accessibility-10.2.tar.gz", hash = "sha256:275c9ac0df1350bf751dbddc81d98f7702cf03ad66e0271876cef9aa70ca5c24"}, + {file = "pyobjc_framework_Accessibility-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c801ad06fadc17f281102408d8a98a844739b3496b9799e2cef2b630a8bec312"}, + {file = "pyobjc_framework_Accessibility-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:861c6f7683c1bd769df85e677905a051f17f01a99a59cbba63b68c2f4bf46066"}, + {file = "pyobjc_framework_Accessibility-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:7e0a716b0cc89fbfb68d4ac0eba4bbd9c50a092255efa2794c4bb93b27b05b98"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-accounts" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Accounts on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Accounts-10.1.tar.gz", hash = "sha256:cb436af5b60f1d6a8a59f94d84ea6decba663598d5624fce29a0babf6fad0a89"}, - {file = "pyobjc_framework_Accounts-10.1-py2.py3-none-any.whl", hash = "sha256:30da31a76f2cfd0a4021eff4d4ff69e0a70b2f293290372f5909ae267d15a010"}, + {file = "pyobjc-framework-Accounts-10.2.tar.gz", hash = "sha256:40c8d7299b58b2300db0a6189a7c7056d38385e58700cb40137a744bb03708b7"}, + {file = "pyobjc_framework_Accounts-10.2-py2.py3-none-any.whl", hash = "sha256:9616c8c27f08baadfeea7c27fb1efac043e0785fbbbfbe05f20021402ac5295f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-addressbook" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AddressBook on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AddressBook-10.1.tar.gz", hash = "sha256:9b8e01da07703990f0e745945b01cc75c59ade41913edbd6824194e21522efff"}, - {file = "pyobjc_framework_AddressBook-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2c6cb2278161ed55fba8b47515ff777a95265e484c51ad7a1c952747d8a411ee"}, - {file = "pyobjc_framework_AddressBook-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:10236b9112c8e5d83526804ca734a5f176bba435c2451c4b43c1247e76d9f73d"}, - {file = "pyobjc_framework_AddressBook-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e4305cf6366fa2e01040f490360283f572103be0a45d190774869915c2707c54"}, + {file = "pyobjc-framework-AddressBook-10.2.tar.gz", hash = "sha256:d6969fcbde1d78ec9fa0ebcefc2f453090e35d7590c4b4baf62174e060de6bce"}, + {file = "pyobjc_framework_AddressBook-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6558b05e9d40a7f40650cddde9b71cb6fb536edf891985c977d4abc626f07a63"}, + {file = "pyobjc_framework_AddressBook-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c57347c04b11310f980e3d6cadc84ebc701d2216853108f9b708c03b0d295a59"}, + {file = "pyobjc_framework_AddressBook-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ba6eff580e4764dc9616b73cf4794cd44b4389b98f95696bac0bb5190f6a1211"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-adservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AdServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AdServices-10.1.tar.gz", hash = "sha256:54d2dd3084374213e31760bae9df1e6e9da3b3f1cc04787dae3ad53f8fc12f69"}, - {file = "pyobjc_framework_AdServices-10.1-py2.py3-none-any.whl", hash = "sha256:79ec6eb744635b72ffd0bdd5e55cb5ec57603633716861bbf40b236d8dba0dfd"}, + {file = "pyobjc-framework-AdServices-10.2.tar.gz", hash = "sha256:76eafba018c819c1770f88daa68d25fc5f06dc93a9f5e369d329d0f341dec3af"}, + {file = "pyobjc_framework_AdServices-10.2-py2.py3-none-any.whl", hash = "sha256:b03fcd460b632fc1b3fd8275060255e518933d1d0da06d6eda9b128b4e2999ec"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-adsupport" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AdSupport on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AdSupport-10.1.tar.gz", hash = "sha256:df6b2d1cc1202905dcf6bcdbf35121acc45c346a57b1048f5f4d1ea15bc29c9c"}, - {file = "pyobjc_framework_AdSupport-10.1-py2.py3-none-any.whl", hash = "sha256:d61f2e44f6c2ed5c33b6520754ef8ea22470f8ac3154912aa44bee4fb792255c"}, + {file = "pyobjc-framework-AdSupport-10.2.tar.gz", hash = "sha256:1eb76dc039d081e6d25b4fd334a3987bd9f73527a17844c421bcc8289dd16968"}, + {file = "pyobjc_framework_AdSupport-10.2-py2.py3-none-any.whl", hash = "sha256:4883ac30f1d78d764b57aacb46af78018f2302b9f7e8f4e1fccb25c3cb44ab74"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-applescriptkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AppleScriptKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AppleScriptKit-10.1.tar.gz", hash = "sha256:e41cd0037cbe0af4ffecc42339d1b6255f2539dfb6dedf4f2ae00ac1a260eecf"}, - {file = "pyobjc_framework_AppleScriptKit-10.1-py2.py3-none-any.whl", hash = "sha256:b88bc8ae9e000d382c3e1d72b3c4f39499323fbe88cc84af259925448c187387"}, + {file = "pyobjc-framework-AppleScriptKit-10.2.tar.gz", hash = "sha256:871452c17b15ce33337cd7ebd293fe31daef9f02f16ebb649efc36165cfb02da"}, + {file = "pyobjc_framework_AppleScriptKit-10.2-py2.py3-none-any.whl", hash = "sha256:15af7d97f017563ff3771127a2b7c515496aa6083497415cbe8c27dd5811c50f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-applescriptobjc" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AppleScriptObjC on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AppleScriptObjC-10.1.tar.gz", hash = "sha256:cfcec31b25a4c201188936347697ff3eb1f79885a43af26559a572391c50cdf9"}, - {file = "pyobjc_framework_AppleScriptObjC-10.1-py2.py3-none-any.whl", hash = "sha256:500ed0e39bf2a4f2413d8d6dc398bb58f233ca3670f6946aa5c6d14d1b563465"}, + {file = "pyobjc-framework-AppleScriptObjC-10.2.tar.gz", hash = "sha256:71f90e41be6beb392a833d915d3af13d10526bfb29bf35cb9af1578b5ec52566"}, + {file = "pyobjc_framework_AppleScriptObjC-10.2-py2.py3-none-any.whl", hash = "sha256:41156fcc36acc3ca7bd0a62af47af4ab8089330c6072db6047b91b52f815f049"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-applicationservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ApplicationServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ApplicationServices-10.1.tar.gz", hash = "sha256:bb780eabadad0fbf36a128041dccfd71e30bbeb6b110852d37fd5c98f4a2ec04"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a74a0922b48ad5ac4e402a1ac5dda5d6ee0d177870b7e244be61bc95d639ba85"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff352c33cad3f7bf8dd9b955ebb5db02d451d88eb04478d83edf0edd0cc8bf5d"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6d0706d5d9436298c8d619a1bb5be11a1f4ff9f4733797a393c6a706568de110"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:95bd111583c3bf20656393c2a056a457b0cf08c76c0ab27cfcaedf92f707e8a9"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:90a2350ddae3d9fb7b2e35e3b672b64854edae497fda8d7d4d798679c8280fed"}, - {file = "pyobjc_framework_ApplicationServices-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8bc830ac60b73a4cab24d1b1fdd8b044f25fe02e0af63a92cd96c43a51808c96"}, + {file = "pyobjc-framework-ApplicationServices-10.2.tar.gz", hash = "sha256:f83d6ed3320afb6648be6defafe0f05bac00d0281fc84ee4766ff977309b659f"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2aebfed888f9bcb4f11d93f9ef9a76d561e92848dcb6011da5d5e9d3593371be"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:edfd3153e64ee9573bcff7ccaa1fbbbd6964658f187464c461ad34f24552bc85"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d2c89b246c19a041221ff36e9121c92e86a4422016f809a40f5ce3d647882d9"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ee1e69947f31aad5fdec44921ce37f7f921faf50a0ceb27ed40b6d54f4b15d0e"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:101f5b09d71e55bd39e6e91f0787433805d422622336b72fde969a7c54528045"}, + {file = "pyobjc_framework_ApplicationServices-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a3ef00c9aea09c5ef5840b8749d0753249869bc30e124145b763cd0b4b81155"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreText = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreText = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-apptrackingtransparency" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AppTrackingTransparency on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AppTrackingTransparency-10.1.tar.gz", hash = "sha256:7d75a1d2c07b4d60e79c014b509f7a217b8e43ffb856b05aac5e12dfb03aa662"}, - {file = "pyobjc_framework_AppTrackingTransparency-10.1-py2.py3-none-any.whl", hash = "sha256:5dee7e163a6b325315410ca4929f1e07162403fc0f62d7d6a8dd504b544e1626"}, + {file = "pyobjc-framework-AppTrackingTransparency-10.2.tar.gz", hash = "sha256:2eb7276fc70c676562e33c3f7b2fe254175236f968516c63cc8507f325ac56db"}, + {file = "pyobjc_framework_AppTrackingTransparency-10.2-py2.py3-none-any.whl", hash = "sha256:de140b6b6ca1df928d13d986b093f19b8be0c9ab7c42f4121bdbf58f5c69df48"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-audiovideobridging" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AudioVideoBridging on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AudioVideoBridging-10.1.tar.gz", hash = "sha256:73d049a9d203541c12a672af37676c8dddf68217a3e9212510544cb457e77db0"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:574ead9349db4d37ec6db865cf71d8fdf74d5b4d4b577aa5c56c77a5c17f4fff"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e9ea894545e5ed1fa9b772dcea876bdb16dac9300e021a81f8b92ec8ed876efb"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:be025276db7bf431361f908c45af631c5c97a138069127ca43e679640fd2b935"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a8d470904288e9ea7a9fb758cb704cbbebaec941c1e11d358c5260f117cbcad6"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:a4ad2cb237ffaa3868eed2ed8869488cb44a8a85a63b2dfe6421be2cb5cbde9e"}, - {file = "pyobjc_framework_AudioVideoBridging-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:41e9ed25b14b30e5eb488a8278fd86cb0973a5677698b534a18c4917b7ec9f9d"}, + {file = "pyobjc-framework-AudioVideoBridging-10.2.tar.gz", hash = "sha256:94d77284aae3a151124aa170074c2902537f540debb076376d49f5ee54fb9ce1"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:180e0d1862ba7748a8e4dff0bfeb5dc162bc4d7b0c0888a333f11dbf2569af74"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1d68f51143e8da14940ea54edd1236e5cd229dcbc83350551945df285b482704"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e0bd4ed2f8a16795b1b46ea9bed746995044f2cd6afb808018ac9c1549dc60b4"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2300d1c9ac22cfa8ef80a86dcdf3bc0be1cfa26a61c560f976fbcd0abfb4f13c"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:a5d48b8192385ef2e0bea47c7b65ca1e0d06d1bdc4a7da59f3d1df3932c5f11c"}, + {file = "pyobjc_framework_AudioVideoBridging-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3883a0f76187a120ad1478f674be245d2949d1bae436d697786ad4086d878b18"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-authenticationservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AuthenticationServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AuthenticationServices-10.1.tar.gz", hash = "sha256:2d686019564f18390ac16d3b225c6c8fead03d929e8cee16942fc532599e15be"}, - {file = "pyobjc_framework_AuthenticationServices-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:364b4f94171c78d5da9172fdf30ef71958da010d923f6fc8f673f8d2e3c8e9ef"}, - {file = "pyobjc_framework_AuthenticationServices-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:09636bd6614d440e0475ba05beba42aa79a73c4fe310e9e79dea4821e57685ae"}, - {file = "pyobjc_framework_AuthenticationServices-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:dd03dc0c4ad5c40a688ceca813b5c05ae99b72e6201a5a700d1d2722eee8fba3"}, + {file = "pyobjc-framework-AuthenticationServices-10.2.tar.gz", hash = "sha256:1be0f05458c4ebfc3e018cb59b4a8bd9022c42b18fea449b0fbf5def0b5f7ef7"}, + {file = "pyobjc_framework_AuthenticationServices-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c797abcd8fb1d9f0f48849093fcbf480814256fca9f1a835445f551a369541e2"}, + {file = "pyobjc_framework_AuthenticationServices-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cf172a06ffab3faa98a95041ce5205ec6c516b59513390d48cfafe17ff4add08"}, + {file = "pyobjc_framework_AuthenticationServices-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:3d6b81342caa28dbdc44c3f32820958e0b3865bd3e5bac7ba5ce9efc293e0d75"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-automaticassessmentconfiguration" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AutomaticAssessmentConfiguration on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AutomaticAssessmentConfiguration-10.1.tar.gz", hash = "sha256:c8f32f5586f7d7f9fd12343714c7439a1dfad5b5393f403aee440b5f91ef9f7d"}, - {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf009cddaa8d62eedaeb4878cc7acab80f4e9bb0bd83a5dff79590bab08b81ce"}, - {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c0ea6fa98e07a9cbcd90b7482022be5e1dc99e3170dcf2d4937ab17c5c2879dd"}, - {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d47b95c515781fa5553443f38782f5e9b1aa7c1938449bcbb2377776441c54c"}, + {file = "pyobjc-framework-AutomaticAssessmentConfiguration-10.2.tar.gz", hash = "sha256:ead3f75200ad74dd013b4a6372054b84b2adeacdac656ca31e763e42fb76cf7b"}, + {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f4a60e1f1dae0d8d9223cb09c945aeb5688c09b3dffa9c6e9457981b05902874"}, + {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1ca34d71b7def8bf4e820e0ee64cae0d732309c6ddc126699a5bbd0c5719dc48"}, + {file = "pyobjc_framework_AutomaticAssessmentConfiguration-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:cb3242e2943768e02208c13b4eef47068f0e1ff8ad5572fabfaef7964737daaa"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-automator" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Automator on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Automator-10.1.tar.gz", hash = "sha256:0e95fc90a2930d108d38b61b4365f3678edd5aa25d26598fe39924c890813e80"}, - {file = "pyobjc_framework_Automator-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5c46ca5a97f6193432ad5195f6dfc261d66f70aea8371aa04f5c0ef85eb959f9"}, - {file = "pyobjc_framework_Automator-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e16540ca8f432de665997566e1cf1b43e8c7bea90a3460ab0aaccdb51bdac13c"}, - {file = "pyobjc_framework_Automator-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:0a8b26890e1b0728c7150cd81dfb7c3d091752e71550a5a8db27c703915b7f40"}, + {file = "pyobjc-framework-Automator-10.2.tar.gz", hash = "sha256:fb753e5bd40bfe720fa9e60e2ea5a1777b4c92082ffeba42b4055cdd56cb022d"}, + {file = "pyobjc_framework_Automator-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:0034f9e64c3e77b8e1adc54170868954af67b50457b768982de705d8cd170792"}, + {file = "pyobjc_framework_Automator-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e3b66af8ecd2effca8d51b512518137173b026ab13c30dbdac3d0d7ee059fc48"}, + {file = "pyobjc_framework_Automator-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:d7f26be322fee0476125bfb2658a08db81b705ce0e8880e91c627562419a9821"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-avfoundation" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AVFoundation on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AVFoundation-10.1.tar.gz", hash = "sha256:07e065c6904fbd6afc434a79888461cdd4097b4153dd592dcbe9c8bef01ee701"}, - {file = "pyobjc_framework_AVFoundation-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:3475f2a5c18cab80a23266470bc7014a88c8e1e8894e96f9f75e960b82679723"}, - {file = "pyobjc_framework_AVFoundation-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fad5c9190d633f51193a62c4354f2fb7be3511c31a0c58f17e351bb30bfadad3"}, - {file = "pyobjc_framework_AVFoundation-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:6ee76be15a6ad7caf9db71c682fb677d29df6c1bb2972ed2f21283f1b3e99f45"}, + {file = "pyobjc-framework-AVFoundation-10.2.tar.gz", hash = "sha256:4d394014f2477c0c6a596dbb01ef5d92944058d0e0d954ce6121a676ae9395ce"}, + {file = "pyobjc_framework_AVFoundation-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5f20c11a8870d7d58f0e4f20f918e45e922520aa5c9dbee61dc59ca4bc4bd26d"}, + {file = "pyobjc_framework_AVFoundation-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:283355d1f96c184e5f5f479870eb3bf510747307697616737bbc5d224af3abcb"}, + {file = "pyobjc_framework_AVFoundation-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a63a4e26c088023b0b1cb29d7da2c2246aa8eca2b56767fe1cc36a18c6fb650b"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreAudio = ">=10.1" -pyobjc-framework-CoreMedia = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreAudio = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-avkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AVKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AVKit-10.1.tar.gz", hash = "sha256:15779995d4bb3b231a09d9032cf42e8f2681e4271ee677076a08c60a1b45fac7"}, - {file = "pyobjc_framework_AVKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e73da23397f0d9397a5f78223b06a49873d11cce71f06d486316a006220b587"}, - {file = "pyobjc_framework_AVKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2ea71aa0c9230c37da6dab710b237ea67ea16a5ed2cd5f6123a562c8c6b6fa20"}, - {file = "pyobjc_framework_AVKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:3c00b4448d0480e92d7a0dfe62d92d42554ddb45c7183c256931e47dafca1dce"}, + {file = "pyobjc-framework-AVKit-10.2.tar.gz", hash = "sha256:6497a5109a29235a7fd8bddcb6d79bd495ccd9373b41e84ca3f012a642e5b880"}, + {file = "pyobjc_framework_AVKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:480766be9da6bb1a6272a4f13f6a327ec952fe1cd41eb0e7c3a07abb07a3491f"}, + {file = "pyobjc_framework_AVKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c9cfdc9ef8f7c9abe53841e8e548b2671f0a425ce9e0e4961314f5d080401e68"}, + {file = "pyobjc_framework_AVKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ff811fc88fb9d676a4892adea21a1a82384777af53153c74bb829501721f3374"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-avrouting" -version = "10.1" +version = "10.2" description = "Wrappers for the framework AVRouting on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-AVRouting-10.1.tar.gz", hash = "sha256:148fc29d0d5e73fb23ed64edede3f74d902ec41b7a7869435816a7a1b37aa038"}, - {file = "pyobjc_framework_AVRouting-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2a2d6524ac870a0b022beb33f0a9ec8870dfb62524d778b7cb54b7946705a3ac"}, - {file = "pyobjc_framework_AVRouting-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:643412674490719dc05c3e4c010e464d50b51e834428e97739510f513ecc008d"}, - {file = "pyobjc_framework_AVRouting-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:103e99db20099331afe637d4bcc39ec7c5d8fe3edefa2dd0a865d6f5d15b0f65"}, + {file = "pyobjc-framework-AVRouting-10.2.tar.gz", hash = "sha256:133d646cf36cfa329c2b3a060c7b81368a95bfbb24f30e2bae2804be65b93ec9"}, + {file = "pyobjc_framework_AVRouting-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:1f72c23e92981311e218a04f3cfcd0ef4c3a93058af6e0042c7cf835320300cc"}, + {file = "pyobjc_framework_AVRouting-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a91d65fda866e64bd249c0f11017d0d9f569b3e9d6d159c38e64e1b144a04d85"}, + {file = "pyobjc_framework_AVRouting-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:3357ed6b9bf583ded7eee4531ac1854c6e1cdfe91a278f2dec18593d2381d488"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-backgroundassets" -version = "10.1" +version = "10.2" description = "Wrappers for the framework BackgroundAssets on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-BackgroundAssets-10.1.tar.gz", hash = "sha256:0a770f77f7fe6d715cf02e95a5efb70895ee19736cf0fa0ecbb3c320f4fa3430"}, - {file = "pyobjc_framework_BackgroundAssets-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:82bfc758b8c542e0b155a922e0dc901fdcd6b6a7574f4575725cfadb8d248825"}, - {file = "pyobjc_framework_BackgroundAssets-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a4f6e2dea9f2cb507e94e0c3c621e2e6af613770a8595ff17aedb34dc2fa56b4"}, - {file = "pyobjc_framework_BackgroundAssets-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:4dfe00a649dd7c7aee0f25daf96c8c35438ed69ec324bcad81d5a87110759a72"}, + {file = "pyobjc-framework-BackgroundAssets-10.2.tar.gz", hash = "sha256:97ad7b0c693e406950c0c4af2edc9320eac9aef7fdf33274903f526b4682fcb7"}, + {file = "pyobjc_framework_BackgroundAssets-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a71de388248ed05eda85abc440dbe3f04ff39567745785df25b1d5316b2aa9f1"}, + {file = "pyobjc_framework_BackgroundAssets-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:476a7fc80a4083405c82b0bb0d8551cccd10f998a2a9d35c8eab76c82915d25e"}, + {file = "pyobjc_framework_BackgroundAssets-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:9c8721ea4695f1cd5f1f7d6b2a70b3e2b9cefe484289b7427cfda5d23b48e7b6"}, +] + +[package.dependencies] +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" + +[[package]] +name = "pyobjc-framework-browserenginekit" +version = "10.2" +description = "Wrappers for the framework BrowserEngineKit on macOS" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyobjc-framework-BrowserEngineKit-10.2.tar.gz", hash = "sha256:a47648e62d3482d39179ffe51543322817dd7a639cef9dcd555dfcc7d6a6497f"}, + {file = "pyobjc_framework_BrowserEngineKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:98563b461e2c96ad387abe1885e91f7bc0686868b39c273774e087bbf1b500ac"}, + {file = "pyobjc_framework_BrowserEngineKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5eb3d8f9e198aaeb01a4a85aa739624942c39b626400d232271d632f1ee30e09"}, + {file = "pyobjc_framework_BrowserEngineKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:6824c528e10da1b560d83f55e258232b8916d49d12a578dd00d3ec4e702d3011"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreAudio = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-businesschat" -version = "10.1" +version = "10.2" description = "Wrappers for the framework BusinessChat on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-BusinessChat-10.1.tar.gz", hash = "sha256:f361139464532d84bb29d520f2b045a4a63e960d07a0dd574c6c15dd67f890ed"}, - {file = "pyobjc_framework_BusinessChat-10.1-py2.py3-none-any.whl", hash = "sha256:60df5660a9a90a461c68a6cb49326c25e81f3412e951e84be7ccc98b62eb5404"}, + {file = "pyobjc-framework-BusinessChat-10.2.tar.gz", hash = "sha256:44ecf240da59ce36f2d75d1ed9f58e05f2df46b9b1989ee0cc184a46c779fb4e"}, + {file = "pyobjc_framework_BusinessChat-10.2-py2.py3-none-any.whl", hash = "sha256:aa51d4d0b3b3eb050242e0d0e48b29e020ccfeb82a39c0d3a2289512734f53e4"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-calendarstore" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CalendarStore on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CalendarStore-10.1.tar.gz", hash = "sha256:6274d7eb94353813aefca236276c5b6dc6445a48fff39e832478db17c47e34c1"}, - {file = "pyobjc_framework_CalendarStore-10.1-py2.py3-none-any.whl", hash = "sha256:cbd8ec495d9b13cc986b018d8740e25a4e18a25732ee19de1311f0c30ab53120"}, + {file = "pyobjc-framework-CalendarStore-10.2.tar.gz", hash = "sha256:131c14faa227a251d7254afd9c00fef203361dd76224d9700ba5e99682e191d8"}, + {file = "pyobjc_framework_CalendarStore-10.2-py2.py3-none-any.whl", hash = "sha256:e289236df651953a41be8ee4ce548f477a6ab8e90aa8bbd73f46ad29032ff13f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-callkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CallKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CallKit-10.1.tar.gz", hash = "sha256:9a5165f35e31d98b7d1539c9b979cabd01064926903389fc558cbc71bf86ddd4"}, - {file = "pyobjc_framework_CallKit-10.1-py2.py3-none-any.whl", hash = "sha256:f82e791b2dbae4adfcc596949975573309a0127ba02d4c35743501f6665ec610"}, + {file = "pyobjc-framework-CallKit-10.2.tar.gz", hash = "sha256:45cd81a5b6b0107ba56e26d8e54e852b8a15b3487b7291b5818e10e94beee6d0"}, + {file = "pyobjc_framework_CallKit-10.2-py2.py3-none-any.whl", hash = "sha256:f3f26c877743a340718e0647ccee4604f9d87aa8ad5c3268c794d94f6f9246ee"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-cfnetwork" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CFNetwork on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CFNetwork-10.1.tar.gz", hash = "sha256:898fa3ec863b9d72b3262135e1b0a24bc73879b65c69a2a7b213fe840e2a11de"}, - {file = "pyobjc_framework_CFNetwork-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:82f6fa09d67e25ef1cd92596b25328a6c295341c40a572e899c9e858ce949a1d"}, - {file = "pyobjc_framework_CFNetwork-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c598f18e50480a92df3c69c22cd1752844eb487176ada5e1c1b80670fb05e4eb"}, - {file = "pyobjc_framework_CFNetwork-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:90697ae10c7fb83d81f25d3800f33846329121bedefd495b45d47a0f0d996a73"}, + {file = "pyobjc-framework-CFNetwork-10.2.tar.gz", hash = "sha256:18ebd22c645b5b77c1df6d973a91cc035ddd4666346912b2a0c847803c23f4d4"}, + {file = "pyobjc_framework_CFNetwork-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6050428c99505e09db1fe5d0eafaaca4ead407ffaaab8a5c1e5ec09e7ad31053"}, + {file = "pyobjc_framework_CFNetwork-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f7a305d7f94a11dd32d3ab9159cde1f9655f107282373841668624b124935af8"}, + {file = "pyobjc_framework_CFNetwork-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:41a211b934afebbc9dd9ce76cb5c2862244a699a41badb660ab46c198414c4cb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-cinematic" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Cinematic on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Cinematic-10.1.tar.gz", hash = "sha256:a1210338de5a739b00304555ce15b70b36deebdbd3c6940f8e9531253219edce"}, - {file = "pyobjc_framework_Cinematic-10.1-py2.py3-none-any.whl", hash = "sha256:73408d3bfd9b08389eb6787b0b5df4fe9c351c936fa9b1f95a9c723951e9a988"}, + {file = "pyobjc-framework-Cinematic-10.2.tar.gz", hash = "sha256:514effad241be5c8df4ef870683fa1387909970a7f7d8bbf343c06e840931854"}, + {file = "pyobjc_framework_Cinematic-10.2-py2.py3-none-any.whl", hash = "sha256:962af237b284605ecd30d584d2d7fb75fda40e429327578de5d651644d0316da"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-AVFoundation = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreMedia = ">=10.1" -pyobjc-framework-Metal = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-AVFoundation = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" +pyobjc-framework-Metal = ">=10.2" [[package]] name = "pyobjc-framework-classkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ClassKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ClassKit-10.1.tar.gz", hash = "sha256:baf79b1296662525d0fa486d4488720cceebe63595765cfeade61aeb78a4216f"}, - {file = "pyobjc_framework_ClassKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:502949573701363947bf64f7ac9dedab7247037c0e53c7db080c871f3ca52aa8"}, - {file = "pyobjc_framework_ClassKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e6d7c2e8b87b285ce21582c602be23960349e23111c8d02bcc3b9192090b437e"}, - {file = "pyobjc_framework_ClassKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:5ac34c1d491e15f81df83b406a281d3176fff8476e053bb8476cad7e4fa102e7"}, + {file = "pyobjc-framework-ClassKit-10.2.tar.gz", hash = "sha256:252e47e3284491e48000d4d87948b31e396aaa78eaf2447ba03a71f4b97cb989"}, + {file = "pyobjc_framework_ClassKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:9d5f69e7bba660ca989e699d4b38a93db7ee3f8cff45e67a23fb852ac3caab49"}, + {file = "pyobjc_framework_ClassKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e1acc7231ef030125eaf7302f324909c56ba1c58ff91f4e160b6632938db64df"}, + {file = "pyobjc_framework_ClassKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:87158ca3d7cd78c50af353c23f32e1e8eb0adec47dc15fa4e4d777017d308b80"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-cloudkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CloudKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CloudKit-10.1.tar.gz", hash = "sha256:8f0109f29ac6554c22cc21c06f6fd0a23e3e49556b0ab2532eb1d69ac2a7cd96"}, - {file = "pyobjc_framework_CloudKit-10.1-py2.py3-none-any.whl", hash = "sha256:ffdedaaa8384a64df6b30d45c834dffa002a63b8e74578012b6261780f31c28c"}, + {file = "pyobjc-framework-CloudKit-10.2.tar.gz", hash = "sha256:497a0dda5f5a9aafc795e1941ef3e3662c2f3240096ce68893d0d5de6d54a474"}, + {file = "pyobjc_framework_CloudKit-10.2-py2.py3-none-any.whl", hash = "sha256:32bd77c2b9109113b2321feb6ed6d754af99df6569d953371f1547123be80467"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Accounts = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreData = ">=10.1" -pyobjc-framework-CoreLocation = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Accounts = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreData = ">=10.2" +pyobjc-framework-CoreLocation = ">=10.2" [[package]] name = "pyobjc-framework-cocoa" -version = "10.1" +version = "10.2" description = "Wrappers for the Cocoa frameworks on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Cocoa-10.1.tar.gz", hash = "sha256:8faaf1292a112e488b777d0c19862d993f3f384f3927dc6eca0d8d2221906a14"}, - {file = "pyobjc_framework_Cocoa-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2e82c2e20b89811d92a7e6e487b6980f360b7c142e2576e90f0e7569caf8202b"}, - {file = "pyobjc_framework_Cocoa-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0860a9beb7e5c72a1f575679a6d1428a398fa19ad710fb116df899972912e304"}, - {file = "pyobjc_framework_Cocoa-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:34b791ea740e1afce211f19334e45469fea9a48d8fce5072e146199fd19ff49f"}, - {file = "pyobjc_framework_Cocoa-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1398c1a9bebad1a0f2549980e20f4aade00c341b9bac56b4493095a65917d34a"}, - {file = "pyobjc_framework_Cocoa-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:22be21226e223d26c9e77645564225787f2b12a750dd17c7ad99c36f428eda14"}, - {file = "pyobjc_framework_Cocoa-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0280561f4fb98a864bd23f2c480d907b0edbffe1048654f5dfab160cea8198e6"}, + {file = "pyobjc-framework-Cocoa-10.2.tar.gz", hash = "sha256:6383141379636b13855dca1b39c032752862b829f93a49d7ddb35046abfdc035"}, + {file = "pyobjc_framework_Cocoa-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9227b4f271fda2250f5a88cbc686ff30ae02c0f923bb7854bb47972397496b2"}, + {file = "pyobjc_framework_Cocoa-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6a6042b7703bdc33b7491959c715c1e810a3f8c7a560c94b36e00ef321480797"}, + {file = "pyobjc_framework_Cocoa-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:18886d5013cd7dc7ecd6e0df5134c767569b5247fc10a5e293c72ee3937b217b"}, + {file = "pyobjc_framework_Cocoa-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ecf01400ee698d2e0ff4c907bcf9608d9d710e97203fbb97b37d208507a9362"}, + {file = "pyobjc_framework_Cocoa-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:0def036a7b24e3ae37a244c77bec96b7c9c8384bf6bb4d33369f0a0c8807a70d"}, + {file = "pyobjc_framework_Cocoa-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f47ecc393bc1019c4b47e8653207188df784ac006ad54d8c2eb528906ff7013"}, ] [package.dependencies] -pyobjc-core = ">=10.1" +pyobjc-core = ">=10.2" [[package]] name = "pyobjc-framework-collaboration" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Collaboration on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Collaboration-10.1.tar.gz", hash = "sha256:e85c6bd8b74b1707f66847ed71de077565d5e9fe6e7ed4db3cdafc2408723da5"}, - {file = "pyobjc_framework_Collaboration-10.1-py2.py3-none-any.whl", hash = "sha256:9a2137aaed1ad71bf6c92c7c275253c2dc6f0062af9d2d8a1590d00bf30c1ecb"}, + {file = "pyobjc-framework-Collaboration-10.2.tar.gz", hash = "sha256:32e3a7fe8447f38fd3be5ea1fe9c1e52efef3889f4bd5781dffa3c5fa044fe20"}, + {file = "pyobjc_framework_Collaboration-10.2-py2.py3-none-any.whl", hash = "sha256:239a0505d702d49b5c3f0a3524531f9be63d599ea2cd3cbb5953147b34dbdcc1"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-colorsync" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ColorSync on Mac OS X" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ColorSync-10.1.tar.gz", hash = "sha256:2c6ee65dfca6bc41f0e9dffaf1adebc78a7fb5cee63740b092ade226710c1c32"}, - {file = "pyobjc_framework_ColorSync-10.1-py2.py3-none-any.whl", hash = "sha256:58596365b270453c3ce10bb168383c615321fa377a983eba3021f664c98f852a"}, + {file = "pyobjc-framework-ColorSync-10.2.tar.gz", hash = "sha256:108105c281b375dff7d226fcc3f860621a4880dcbab711660b74dc458a506231"}, + {file = "pyobjc_framework_ColorSync-10.2-py2.py3-none-any.whl", hash = "sha256:2fcc68eb6fa6300d34b95b1da1cc8d244f6999aed4b83099a3323d32e0349f98"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-contacts" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Contacts on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Contacts-10.1.tar.gz", hash = "sha256:949d61ff7f4f07956949f8945ad627ffa89cce3d10af9442591e519791a25cc4"}, - {file = "pyobjc_framework_Contacts-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b10c068b5a79fcb0240ea4cd1048162277f36567a84333a0bd0168f851168f99"}, - {file = "pyobjc_framework_Contacts-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a3bb6fb24deae41a0879ac321e6401b43e5fbedba0a75ced67b2048a4852c3ff"}, - {file = "pyobjc_framework_Contacts-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:16556f06202b1b4fd9da8e3186b6140b582a4032437cdab2f5f8b32b24f3e3ed"}, + {file = "pyobjc-framework-Contacts-10.2.tar.gz", hash = "sha256:5a9de975f41c7dac3c219b4c60cd08b8ba385685db7997c8622f19e0a43e6857"}, + {file = "pyobjc_framework_Contacts-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b5ff801009c9346927b7efc82434ac14a0c2798bd018daf1e7d8aad74484b490"}, + {file = "pyobjc_framework_Contacts-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:52dd5e4b4574b2438420a56867ca2069e29414087dc27ad03e7c46d536f1e641"}, + {file = "pyobjc_framework_Contacts-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8a387c47e90c74a3e6f4bc81187f1fde18a020bb1d08067497a0c35f462299f9"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-contactsui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ContactsUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ContactsUI-10.1.tar.gz", hash = "sha256:0b97e4c5599ab269f53597dd8f47a45599434c833e72185d5d3a257413a6faf4"}, - {file = "pyobjc_framework_ContactsUI-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5c70ff6b07e48331f25138bc159f7215d9b5d6825da844fec26ba403aad53f52"}, - {file = "pyobjc_framework_ContactsUI-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:876c1280fcb13c89a5fd89e7c3ace04bfd3c3b418cb64b6579dcbee1e9156377"}, - {file = "pyobjc_framework_ContactsUI-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a5ee22f1e893eb79633ed425972e50c5ec9b0a1d20cf6fbf21bf68d1bbfec436"}, + {file = "pyobjc-framework-ContactsUI-10.2.tar.gz", hash = "sha256:2dd5f1993c36caf13527de0890c6c49c08a339e58bc3b3fa303d5a04b672b418"}, + {file = "pyobjc_framework_ContactsUI-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c8af8b52853ba2a09664dad40255613f01089c9bc77e5316b29d27c65603863c"}, + {file = "pyobjc_framework_ContactsUI-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:47a8fd0aa5cb680b0ba0f1fdd37f56525729e5ed998df2a312e9f81feea8fbb0"}, + {file = "pyobjc_framework_ContactsUI-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:0575650e6e5985950bcd424da0b50e981ea5e6819d1c6fbccb075585e424e121"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Contacts = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Contacts = ">=10.2" [[package]] name = "pyobjc-framework-coreaudio" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreAudio on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreAudio-10.1.tar.gz", hash = "sha256:713ca82fc363ea6cf373d2db0b183f39058bcadceb8229d9e8839b783104f8e2"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9348f613a1f35bbeb7d1d899e2ee3876881cd0433e59f584f30ba96e179d960a"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0192dddd2f99db51cdb0959e80f29f9f531ba8bd0421e06ae9212f34a05c48a"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b1a4612ce87dfcca3c939ec5885d4578955f5ff4d017f95d4459d5fb3bdc8970"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:678d2b916850daf7fe38a95af0f73b4dd39b463ea87ec36fe287d81d050c31f7"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:807fa54de91d53ff64537e50aa123c5b262952c57eea6928ecb3d526078229c2"}, - {file = "pyobjc_framework_CoreAudio-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:db149cabae1b91ea437536e1741b6e7573a71ec2aae4274318172936a5ac7190"}, + {file = "pyobjc-framework-CoreAudio-10.2.tar.gz", hash = "sha256:5e97ae7a65be85aee83aef004b31146c5fbf28325d870362959f7312b303fb67"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:65ce01a9963692d9cf94aef36d8e342eb2e75b855a2f362f9cbcef9f3782a690"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:22b5017ed340f9d3137baacb5f0c2354266017a4ed21890a795a0667788fc0cd"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:32608ce881b5e6a7cb332c2732762fa93829ac495c5344c33e8e8b72a2431b23"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5182342257be1cdaa64bc38045cd81aca5b60bb86a9444194adbff58706ce91"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:94ec138f95801019ec7f3e7010ad6f2c575aea69d2428aa9f5b159bf0355034a"}, + {file = "pyobjc_framework_CoreAudio-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:04ad3dddff27cb65d31a432aa1aa6290ff5d82a54bc5825da44ed7d80bcdb925"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coreaudiokit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreAudioKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreAudioKit-10.1.tar.gz", hash = "sha256:85472aaee6360940f679a5e068b5a21160f8cee676d9fd0937b43b39c447d78e"}, - {file = "pyobjc_framework_CoreAudioKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bde3012be239328fdc928d0ff9da9f4627e6ab4832e05faaa0c0ea4e11078d14"}, - {file = "pyobjc_framework_CoreAudioKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:43e9643ce390e36c64dca98a1bbcb0c2c282c527d31eb52aa2b7a18e2f7c97d1"}, - {file = "pyobjc_framework_CoreAudioKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:65bb2c5870b1739703fce056cdc4daddcdcf644c1ddcb590e4b88b5ed2fc45a4"}, + {file = "pyobjc-framework-CoreAudioKit-10.2.tar.gz", hash = "sha256:38dfafba8eddb655aac352a967c0e713a90e10a4dd40d4ea1abbb4db01c5d33f"}, + {file = "pyobjc_framework_CoreAudioKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:aede4cd58a67008b014757178a01b984ee585cc055133a9eb8f10b310d764de8"}, + {file = "pyobjc_framework_CoreAudioKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:4fb992025df80b8799fbd1605b0dd4b4b3f6b467c375a16da1b286f6ac2e2854"}, + {file = "pyobjc_framework_CoreAudioKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:28f17803e5eaf35a73caa327cbd0c857efbfdea57307637a60ff8309834b7a95"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreAudio = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreAudio = ">=10.2" [[package]] name = "pyobjc-framework-corebluetooth" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreBluetooth on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreBluetooth-10.1.tar.gz", hash = "sha256:81f50fcd9ee24332f1ad85798d489cfc05be739fcc1389caa6d682e034215efd"}, - {file = "pyobjc_framework_CoreBluetooth-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:145540ae4f35992774e559840a778554f3d3d29b359ff6d7f450c954cacccf0f"}, - {file = "pyobjc_framework_CoreBluetooth-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1ef97e8479895048fa96d5afa2f88139a8432158d6b0fb80ad1db03666c1d4ad"}, - {file = "pyobjc_framework_CoreBluetooth-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e8bce7f425caa55a87b7519eff03eaa7d08ff5e5e09e9318706d3f5087b63b08"}, + {file = "pyobjc-framework-CoreBluetooth-10.2.tar.gz", hash = "sha256:fb69d2c61082935b2b12827c1ba4bb22146eb3d251695fa1d58bbd5835260729"}, + {file = "pyobjc_framework_CoreBluetooth-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6e118f08ae08289195841e0066389632206b68a8377ac384b30ac0c7e262b779"}, + {file = "pyobjc_framework_CoreBluetooth-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:411de4f937264b5e2935be25b78362c58118e2ab9f6a7af4d4d005813c458354"}, + {file = "pyobjc_framework_CoreBluetooth-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:81da4426a492089f9dd9ca50814766101f97574675782f7be7ce1a63197d497a"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coredata" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreData on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreData-10.1.tar.gz", hash = "sha256:01dfbf2bfdaa4e0aa3e636025dc868ddb62aedf710890e6af94106278f1659aa"}, - {file = "pyobjc_framework_CoreData-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ff280c893c6d472168696fa0732690809af2694167081b5db87395c25cdf6e27"}, - {file = "pyobjc_framework_CoreData-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c51d8e4723ed113684d0ddd4240900a937682859a9e75d830f35783098f04e95"}, - {file = "pyobjc_framework_CoreData-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a8a8d509ff17f65f4cec7fb35d77a21937f2c8232b5ce357e783cbf971616ad9"}, + {file = "pyobjc-framework-CoreData-10.2.tar.gz", hash = "sha256:0260bbf8f4ce6071749686fdc079618b3bd2b07976db7db4c864ecc62316bb3b"}, + {file = "pyobjc_framework_CoreData-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:41a22fe04544ba35e82232d89ad751b452c2314f07df6c72129a5ad6c3e4cbec"}, + {file = "pyobjc_framework_CoreData-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c29c6dce8ce155e15e960b9c542618516923c3ef55a50bf98ec95e60afe0aa3d"}, + {file = "pyobjc_framework_CoreData-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:cd7c419d9067ce9a9f83f6abd3c072caeb3aa20091f779881375067f7c1c417b"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-corehaptics" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreHaptics on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreHaptics-10.1.tar.gz", hash = "sha256:87c1913078963b2d7dba231839566f831f47499c4c029f8beaa46209630e75e1"}, - {file = "pyobjc_framework_CoreHaptics-10.1-py2.py3-none-any.whl", hash = "sha256:ae6143c041b0846a58199826c0094cfb2fb9080f139c93e6b63f51a6b2766552"}, + {file = "pyobjc-framework-CoreHaptics-10.2.tar.gz", hash = "sha256:7b98bd70b63506aef63401a6e03f67391d7582f39fbe8aa7bb7258dd66ab0e55"}, + {file = "pyobjc_framework_CoreHaptics-10.2-py2.py3-none-any.whl", hash = "sha256:c67fae4b543fc070cece622cfe5803796016a36d1020812428e0f22e5f5674aa"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-corelocation" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreLocation on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreLocation-10.1.tar.gz", hash = "sha256:f43637443c4386233c52b0af3131a545968229543f7b0050764298cac1604fd8"}, - {file = "pyobjc_framework_CoreLocation-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:66bad050f37966526017763e5a8c424e257a0974cfbe0c8875fa149bdc1d41c2"}, - {file = "pyobjc_framework_CoreLocation-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:eaa4ff8e3cc388f045a6c15f3ee5a950860164f6fb5a13aed29e37b6cb481607"}, - {file = "pyobjc_framework_CoreLocation-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f4dcf52c4934e99b20056f2ebc8398c9f8f8a61ceac0e5de1e2bb719b0f844c2"}, + {file = "pyobjc-framework-CoreLocation-10.2.tar.gz", hash = "sha256:59497cc210023479e03191495c880e61fb6f44ad6c435ed1c8dd8def39f3aada"}, + {file = "pyobjc_framework_CoreLocation-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c2e02352a4dfbc090cebc9c0d3716470031e584d4d33f22d97307f04c23ef01f"}, + {file = "pyobjc_framework_CoreLocation-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f7eda101abb366be52d2fd85e15c79fdf0b9f64de9aab87dc0577653375595de"}, + {file = "pyobjc_framework_CoreLocation-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8f67af17b8267aa2a066684b518e66bbe7fee9651b779e372d6286d65914df82"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coremedia" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreMedia on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreMedia-10.1.tar.gz", hash = "sha256:8210d03ff9533d5cef3244515c1aa4bb54abaeb93dfc20be6d87e3a6b3377b36"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7bd43d614f0427732ce1690e0640f1d7a40a73dd90142ac08c5dab2ba0d49e8d"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5c1f849ce7de96da6fc81dc8975ecf04444c7179129976b3fe064d9f85a91082"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ab9e44e0d3ce584a119c3b3d539de9d228b635cb98bf60f1e1a221f8aa20681e"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fffc355c038dfaa83f7d7c01497fb20590f9090421564b275cd8fd12e8e10e8e"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:e4e9221c5a4c0b7ff7484eb8a21e06be0cafc1c95b9bcc27a57c139b64692dbe"}, - {file = "pyobjc_framework_CoreMedia-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b61e986b686d4e928208c26a4a2163210e101fcec56eeb61d62b969802eaa8ca"}, + {file = "pyobjc-framework-CoreMedia-10.2.tar.gz", hash = "sha256:d726d86636217eaa135e5626d05c7eb0f9b4529ce1ed504e08069fe1e0421483"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0c91037fd4f9995021be9e849f1d7ac74579291d0130ad6898e3cb1940f870e1"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63ed4f6dbe33e5f3d5293a78674329cb516a256df34ef92e7c1fefacdb5c32db"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7fa13166a14d384bb6442e5f635310dd075c2a4b3b3bd67ac63b1e2e1fd2d65e"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bd7da9da1fad7168a63466d5c267dea8bce706808557baa960b6a931010dca48"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:c48c7f0c3709a900cd11002018950a72626af39a096d1001bb9a871574db794f"}, + {file = "pyobjc_framework_CoreMedia-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d3e86d03c6d7909058b8f1b8e54d9b5d93679049c7980eb0a5d930a5a63410e0"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coremediaio" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreMediaIO on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreMediaIO-10.1.tar.gz", hash = "sha256:c07177c58c88b6de229f88f3b88b4d97bfc59d2406f751b5aff6bed5cac4d938"}, - {file = "pyobjc_framework_CoreMediaIO-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:d44781e21632f3af8eab86194b2fe32ce235b6c6a03ff87f09e0ba034a1e7a73"}, - {file = "pyobjc_framework_CoreMediaIO-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c97bd803a17204a2ec2d9f22c14176009067359efe80b9df69e8ec197783091c"}, - {file = "pyobjc_framework_CoreMediaIO-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:d137b0eef1533af244c70ab02f1ed5716dcc8739b0ba6b6c703d36a61d9bab2e"}, + {file = "pyobjc-framework-CoreMediaIO-10.2.tar.gz", hash = "sha256:12f9fd93e610e61258f1acb023b868ed196e9444c69e38dfd314f8c256d07c9e"}, + {file = "pyobjc_framework_CoreMediaIO-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:4ede4da59fa2a611b4a9d5a532e0c09731f448186af6cc957ab733b388f86d5b"}, + {file = "pyobjc_framework_CoreMediaIO-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:184854c2ebc3d12466ad39e640b5f3d2bdb3792d8675c83f499bb48b078d3d91"}, + {file = "pyobjc_framework_CoreMediaIO-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:aa9418277d16a1d5c0b576ad8a35f8e239d3461da60bb296df310090147331f7"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coremidi" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreMIDI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreMIDI-10.1.tar.gz", hash = "sha256:e2e407dcb9d5ed53e0a8ed4622429a56c9770c26e2e4455dcb76a6620a12eba6"}, - {file = "pyobjc_framework_CoreMIDI-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b632773bea0c943a1f733166aece7560f32237a42706124d1f001b10620c4bcc"}, - {file = "pyobjc_framework_CoreMIDI-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:065cf89ee58b01700780fbbed0c00e1c5f5f383ac3d54f31642ee6d59e3c03c2"}, - {file = "pyobjc_framework_CoreMIDI-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8984ad04837efc8bc7cbf1d48ff3433eb7fea1d298ed8b72344ec1641826df48"}, + {file = "pyobjc-framework-CoreMIDI-10.2.tar.gz", hash = "sha256:8168cb1e57e5dbc31648cd68d9afe3306cd2751de03275ef5f7f9b6483f17c07"}, + {file = "pyobjc_framework_CoreMIDI-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:809a79fbf384df94884dfddcab4dad3e68eba9e85591f7b55d24f4af2fb8db94"}, + {file = "pyobjc_framework_CoreMIDI-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a48176d5f49f9e893f5a7ac86f7cd7ee63b66dc7941ef74c04876f87a1ae3475"}, + {file = "pyobjc_framework_CoreMIDI-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:cce95647865c7f374d3c9cf853a3a8a44ae06fda6fa2e65fc7ad6450dc60e50f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coreml" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreML on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreML-10.1.tar.gz", hash = "sha256:4cda220d5ad5b677a95d4d29256b076b411b692b64219c2dcb81c702fc34d57d"}, - {file = "pyobjc_framework_CoreML-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:fb85e653a0f7984fff908890b7988d9d5ac42ff92b213cd9371bb255982ee787"}, - {file = "pyobjc_framework_CoreML-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a361d35c75e749a975330f7647084a58c2166f076ecc5573491542b96bc84c28"}, - {file = "pyobjc_framework_CoreML-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:4c3b43da4afb279b02bbb6a57a3c5fb4d24ad6d48ef40c20efcda783e41077d2"}, + {file = "pyobjc-framework-CoreML-10.2.tar.gz", hash = "sha256:a1d7743a91160d096ccd3f5f5d824dafdd6b99d0c4342e8c18852333c9b3318e"}, + {file = "pyobjc_framework_CoreML-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ab99248b8ace0bebb11d15eb4094d8017093ebf76dadf828e324cacc9f1866f1"}, + {file = "pyobjc_framework_CoreML-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:074b81c0e0e4177d33b2da8267d377fb7842b47eb7b977bb07d674b9b05c32b5"}, + {file = "pyobjc_framework_CoreML-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:baedffd5ab34dc0294c2c30ad1b5bcff175957f51f107b1f9f8b20f80e15cc9c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coremotion" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreMotion on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreMotion-10.1.tar.gz", hash = "sha256:907a2f6da592f61d49f06559b34fc5addd8c0f2b85f9f277c5e4ea5d95247b67"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:630487c14e22c0c05ddc33a149db673d8a28a876b59a78ed672f1a4825ebf40e"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2219096ceb41aea91819df747c08059885f94ca14c66a078d3161ba49c1cb56e"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:de694971994df2791047c2a1039556ea54683fd09cdc30c23ee5891c63414232"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:81b138a672519ecbea8a2f2392a7f015f3d7caf150368f83b3b278cb60743e8c"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:b6cbbee7d26ef1837e382566316cb5d5fae6bca10418437608ebc312f396f898"}, - {file = "pyobjc_framework_CoreMotion-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9968b07199532b1c4ff56d1d6a6195e8ce8bc2beabbf55dc53193f473b3741f9"}, + {file = "pyobjc-framework-CoreMotion-10.2.tar.gz", hash = "sha256:1e1827f2f811ada123dd42809bc86f04a4c1ae3cec619ccf0f05a9387412bec1"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:804abc6b22db933e7fb7ba3e60b30f4c60e8921f8bb5790c3612375f7b4a6f03"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:76d5a2ed1cba375e3c423887bd93bbaab849c7a961156c5cead8e1429c26c24d"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c0a8022dca1404795e93cd7317bca9f8ad601f3ecec7bed71312d80adad296e4"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b727d5301ec386b8aa94de69a9257a412a4edbd69ca394d76b83d9f2bec6bc96"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7e4571a08475428a8171a237284036a990011f212497f141222d281fa7e2ca5c"}, + {file = "pyobjc_framework_CoreMotion-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bef81c52af0d1be75b3bd7514d5f9ef7c6e868f385f0dd8c28ad62e5d3faeeb6"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coreservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreServices-10.1.tar.gz", hash = "sha256:43d507f2b3d84a5aab808c3f67bf21fb6a7d1367d506e2e9877bf1cac9bad2eb"}, - {file = "pyobjc_framework_CoreServices-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:73162798c506f6d767e2684d7c739907c96a5547045d42e01bee47639130b848"}, - {file = "pyobjc_framework_CoreServices-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:eba7abba8f5ba194a5ef1ffeb5f9d3c0daa751e07ef0d3662e35e27e75a24d73"}, - {file = "pyobjc_framework_CoreServices-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:924bca5a67e9046e8c6146dbc1301fe22c2a1bd49bef92358fd6330ef19cfa65"}, + {file = "pyobjc-framework-CoreServices-10.2.tar.gz", hash = "sha256:90fa09e68e840fdd229b33354f4b2e55e9f95a221fcc30612f4bd92cdc530518"}, + {file = "pyobjc_framework_CoreServices-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2b0c6142490c7099c5be0a2fa10b1816e4280bc04ac4e5a4a9af17a9c2006482"}, + {file = "pyobjc_framework_CoreServices-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c2c05674d9d142abc62fcc8e39c8484bdcdfd3ad8a17f009b8aa7c631e227571"}, + {file = "pyobjc_framework_CoreServices-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f87ad202d896e596b31c98a9d0378b2e6d2e6732a2dfc7b82ceae4c70863364d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-FSEvents = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-FSEvents = ">=10.2" [[package]] name = "pyobjc-framework-corespotlight" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreSpotlight on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreSpotlight-10.1.tar.gz", hash = "sha256:b50e13d55d90b88800c2cc2955c000ea6b1de6481ff6e0092c7b7bf94fceea69"}, - {file = "pyobjc_framework_CoreSpotlight-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:421e18ded971c212fd3f2878658c209c81d1f8859eb62dd6a965abcb19a4ce5a"}, - {file = "pyobjc_framework_CoreSpotlight-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c775e0d42ee21f7d6b9374b01df1a0d4ece0b765e99c7011cb2ea74a2c2ef275"}, - {file = "pyobjc_framework_CoreSpotlight-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:7dc11f607429e21c2aee18f950cdde141a414c874369dbb66920930802cfd0fa"}, + {file = "pyobjc-framework-CoreSpotlight-10.2.tar.gz", hash = "sha256:bc4ac490953db29f6a58bc6fca6f819f8a810d0bb15d5f067451b3a8cad1cb50"}, + {file = "pyobjc_framework_CoreSpotlight-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f69dc88ddfa116262009b15ac302b880aef2dad878bf472cbf574f4473f4b059"}, + {file = "pyobjc_framework_CoreSpotlight-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:09912188648e658a0f579bbfd2cf6765afb8e0f466ee666e24019cc9931b6bc5"}, + {file = "pyobjc_framework_CoreSpotlight-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:75ba49ee4bfdbf4df733bc8c508b4417f47c442a56b83ffe5527e76e1c5bad67"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-coretext" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreText on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreText-10.1.tar.gz", hash = "sha256:b6a112e2ae8720be42af19e0fe9b866b43d7e9196726caa366d61d18294e6248"}, - {file = "pyobjc_framework_CoreText-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6ea2920c126a8a39e8a13b6de731b78b391300cec242812c9fbcf65a66ae40cf"}, - {file = "pyobjc_framework_CoreText-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:37b203d832dd82bd9566c72eea815eb89f00f128a4c9a2f352843914da4effec"}, - {file = "pyobjc_framework_CoreText-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:083700483b18f337b0c43bdfaafc43467846f8555075669d4962d460d9d6cd00"}, - {file = "pyobjc_framework_CoreText-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:59472cd1a33e83803fa62b3db20ac0e899f5ed706d22704ea81129d3f49ff0c7"}, - {file = "pyobjc_framework_CoreText-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:cc1a63ca2c6921768b1c794ce60e2a278e0177731aa4bf8f620fdde857e4835e"}, - {file = "pyobjc_framework_CoreText-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fbbdde4ce747bcad45c2aded36167ad00fead309a265d89ab22289c221038e57"}, + {file = "pyobjc-framework-CoreText-10.2.tar.gz", hash = "sha256:59ef8ca8d88bb53ce9980dda0b8094daa3e2dabe355847365ba965ff0b49f961"}, + {file = "pyobjc_framework_CoreText-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:44052f752f42b62d342fa8aced5d1b8928831e70830eccddc594726d40500d5c"}, + {file = "pyobjc_framework_CoreText-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0bc278f509a3fd3eea89124d81e77de11af10167c0df0d0cc15a369f060465a0"}, + {file = "pyobjc_framework_CoreText-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7b819119dc859e49c0ce9040ae09d6a3bd66658003793f486ef5a21e46a2d34f"}, + {file = "pyobjc_framework_CoreText-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2719c57ff08af6e4fdcddd0fa5eda56113808a1690c3325f1c6926740817f9a1"}, + {file = "pyobjc_framework_CoreText-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:8239ce92f9496587a60fc1bfd4994136832bad99405bb45572f92d960cbe746e"}, + {file = "pyobjc_framework_CoreText-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:80a1d207fcdb2999841daa430c83d760ac1a3f2f65c605949fc5ff789425b1f6"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-corewlan" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CoreWLAN on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CoreWLAN-10.1.tar.gz", hash = "sha256:a4316e992521878fb75ccff6bd633ee9c9a9bf72d5e2741e8804b43e8eeef8ac"}, - {file = "pyobjc_framework_CoreWLAN-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:e5374ebd6e258d6cdaa9fdeb21c10830c50fc1c00eaa91b2293833b0182479f7"}, - {file = "pyobjc_framework_CoreWLAN-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:57cb3fbb69500df92a111655c129b0f658ec16e14e57b08b9c1ef400f33f3bb5"}, - {file = "pyobjc_framework_CoreWLAN-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:eb2360b20ab14a0f6cc7d06dc7bf2b0832d0c95892d9f364e03c6ecf77dfc328"}, + {file = "pyobjc-framework-CoreWLAN-10.2.tar.gz", hash = "sha256:f47dcf735145eb2f817db5c2134321a7cfb9274a634161ff3069617fd2afff42"}, + {file = "pyobjc_framework_CoreWLAN-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8dc102d7d08437b5421856ae8aac32e3e9846e546c1742e4d57343abd694688f"}, + {file = "pyobjc_framework_CoreWLAN-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:85bcf84fd38a2e949760dda3201f13f8bef73b341a623f6736834b7420386f16"}, + {file = "pyobjc_framework_CoreWLAN-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ada346a6da1075e16bf5f022ccad488632fe6de972d2d925616add87e3eb9fad"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-cryptotokenkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework CryptoTokenKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-CryptoTokenKit-10.1.tar.gz", hash = "sha256:ad8fb3c4f314cc5f35cd26a5e3fdd68dd71ea0f7b063f31cffb9d78050ce76f0"}, - {file = "pyobjc_framework_CryptoTokenKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:e691877b2e96c8f257873943147315561cda79b63c911afa8d0103d6b351a88f"}, - {file = "pyobjc_framework_CryptoTokenKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5a4ce0650ad70eedadc46091d61878e28a4cf491d1c2e8da32feab2f661a4ee5"}, - {file = "pyobjc_framework_CryptoTokenKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:c0013c7795d208547d9f92c0539bc7fec09ca049d791458b62c177585552abc4"}, + {file = "pyobjc-framework-CryptoTokenKit-10.2.tar.gz", hash = "sha256:c0adfde2d53da7df1f8827bdf0cbf4419590151dd1041711ab2f66a32bd986f5"}, + {file = "pyobjc_framework_CryptoTokenKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:89264d38ca58e8b5a586a3c13260d490ee2cdc9c1498211a804cec67f7659cd7"}, + {file = "pyobjc_framework_CryptoTokenKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e13d92966273420a154cde6694b4bc7dd3dc7679e93d651534dcf2b0c5246546"}, + {file = "pyobjc_framework_CryptoTokenKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a56af323d597332090a0787c00d16c40152c62cb278d951a59723006cd3e10de"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-datadetection" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DataDetection on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DataDetection-10.1.tar.gz", hash = "sha256:f81d1ca971aa8034faeb6e457144df0832f870d7e19905886593bafe4cbfe21f"}, - {file = "pyobjc_framework_DataDetection-10.1-py2.py3-none-any.whl", hash = "sha256:f23fa282297ed385c9df384a0765e4f9743b8916de8a58137f981ab0425b80f5"}, + {file = "pyobjc-framework-DataDetection-10.2.tar.gz", hash = "sha256:9532bb697b96ec4ffc04310550bf21c45c8494fc07d8067fc41cbfd94c8ba27d"}, + {file = "pyobjc_framework_DataDetection-10.2-py2.py3-none-any.whl", hash = "sha256:4435ebaa3b3fa3de855690469fefd2d8a3568f702f51540707efaf4363ec94aa"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-devicecheck" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DeviceCheck on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DeviceCheck-10.1.tar.gz", hash = "sha256:f89e3acd15ec48134f95bf027778ca1d7e3088b9c2204e48f8c6e3bdcb28cf82"}, - {file = "pyobjc_framework_DeviceCheck-10.1-py2.py3-none-any.whl", hash = "sha256:31d5a83d85a4d95e238f432ac66cbf110a7b70afa82fd230ab4b911a5e2b9cb4"}, + {file = "pyobjc-framework-DeviceCheck-10.2.tar.gz", hash = "sha256:f620ede18e12dd36d92f24d1a68278821bcf7aeaea6577993fbfb328c118569d"}, + {file = "pyobjc_framework_DeviceCheck-10.2-py2.py3-none-any.whl", hash = "sha256:c9c87ae40af41c4c296af40317018732bba85e589111f5286b2f136f022c8ecd"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-dictionaryservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DictionaryServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DictionaryServices-10.1.tar.gz", hash = "sha256:03b3b19a9b911beb3bdc8809f5d02356a497a75dbefa0f355825ec610c050a3e"}, - {file = "pyobjc_framework_DictionaryServices-10.1-py2.py3-none-any.whl", hash = "sha256:7ace031cc3df1fa9a4eb663ff55eee0a4c7c8c34653aa1529988d579d273150b"}, + {file = "pyobjc-framework-DictionaryServices-10.2.tar.gz", hash = "sha256:858b4edce36dfbb0f906f17c6aac1aae06350d508cf0b295949113ebf383bfb4"}, + {file = "pyobjc_framework_DictionaryServices-10.2-py2.py3-none-any.whl", hash = "sha256:39b577b35c52a033cbac030df1fdcd16fb109144e8c59cb2044a13fcd803ab49"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-CoreServices = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-CoreServices = ">=10.2" [[package]] name = "pyobjc-framework-discrecording" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DiscRecording on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DiscRecording-10.1.tar.gz", hash = "sha256:321c69b6494c57d75d4a0ecf5d90ceac3800441bf877eac8196ab25dcf15ebde"}, - {file = "pyobjc_framework_DiscRecording-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:581141bd645436d009cc6b42ca6255322de9a3a36052e7dcf497e90959c7bc77"}, - {file = "pyobjc_framework_DiscRecording-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2c4144c4d1d7bf7ad537c6159cefb490876b7eff62ec95d4af7bc857813b95cd"}, - {file = "pyobjc_framework_DiscRecording-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:1c52f7ace5936edbe160aa4d6cb456a49e7bc1a43a5e34572d48cd65dee22d1e"}, + {file = "pyobjc-framework-DiscRecording-10.2.tar.gz", hash = "sha256:9670018a0970553882feb10e066585ad791c502539712f4117bad4a6647c79b3"}, + {file = "pyobjc_framework_DiscRecording-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:cbf0d9904a24bece47a71b56f87090a769e96338c0acb3f33385c3e584ed1c96"}, + {file = "pyobjc_framework_DiscRecording-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:0a7d9980ab9f59903d60d09172de4085028bbb97a63112f78b9cca0051a73639"}, + {file = "pyobjc_framework_DiscRecording-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8a6512d0b7e61064ca167ca0a9c95a3f49f8fa7216fe5e1d77eab01ce56a9414"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-discrecordingui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DiscRecordingUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DiscRecordingUI-10.1.tar.gz", hash = "sha256:2a44278b19738e8d4f2180433df37b59a0b645d9ddc0f3c3a6c81e506afc1953"}, - {file = "pyobjc_framework_DiscRecordingUI-10.1-py2.py3-none-any.whl", hash = "sha256:684925119e4c8f8ea43cfede1a3e39f785b5aa94a48f1aa7a98fd4cdc4c1d2e3"}, + {file = "pyobjc-framework-DiscRecordingUI-10.2.tar.gz", hash = "sha256:afda9756a8f9e8ce1f83930eca3b1a263a29f48c1618269457f4aba63fc1644f"}, + {file = "pyobjc_framework_DiscRecordingUI-10.2-py2.py3-none-any.whl", hash = "sha256:e0423c548851cd9eb4ad7e9e085da4db2cde2420e1f3e05d46e649498edf97d8"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-DiscRecording = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-DiscRecording = ">=10.2" [[package]] name = "pyobjc-framework-diskarbitration" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DiskArbitration on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DiskArbitration-10.1.tar.gz", hash = "sha256:c3ab3dc91375dabaf4d3470e01358e4acfecf6b425abf9ad95a26a7a56398f56"}, - {file = "pyobjc_framework_DiskArbitration-10.1-py2.py3-none-any.whl", hash = "sha256:a3bd1883b60aa1d8cff3bc18957f81ed14e5d0406d18a4a9095539ddf51dd72e"}, + {file = "pyobjc-framework-DiskArbitration-10.2.tar.gz", hash = "sha256:25b74db4f39a7128599e153533db0f88c680ad55f366c5ab6a6d7dede96eeb57"}, + {file = "pyobjc_framework_DiskArbitration-10.2-py2.py3-none-any.whl", hash = "sha256:dd14eb448865ca4c49e15a543f748f1ef6501ea0044eaa2cf04860547205c84f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-dvdplayback" -version = "10.1" +version = "10.2" description = "Wrappers for the framework DVDPlayback on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-DVDPlayback-10.1.tar.gz", hash = "sha256:2af92907a50a47c44a8dd1521217a564ad9a3dd9e9056f0a76b13275d380bee1"}, - {file = "pyobjc_framework_DVDPlayback-10.1-py2.py3-none-any.whl", hash = "sha256:bcbfb832a3f04e47aef03606a21fd58458bc28e25e1a444e7a9388bfee2f9dd3"}, + {file = "pyobjc-framework-DVDPlayback-10.2.tar.gz", hash = "sha256:0869a6e8da1c2d93713699785b4f0bbe5dd1b2820a0ff4a6adf06227b1bb96ac"}, + {file = "pyobjc_framework_DVDPlayback-10.2-py2.py3-none-any.whl", hash = "sha256:f3fb90eb3d616290d2ab652214ce682130cd19d1fd3205def6ab0ba295535dd9"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-eventkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Accounts on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-EventKit-10.1.tar.gz", hash = "sha256:53473df48000b39dec276e3b8ead88b153c66cf0fdc07b016f759b42f0b2ec50"}, - {file = "pyobjc_framework_EventKit-10.1-py2.py3-none-any.whl", hash = "sha256:3265ef0bfab38508c50febfa922b4abf6ebc55a44f105d499e19231c225a027c"}, + {file = "pyobjc-framework-EventKit-10.2.tar.gz", hash = "sha256:13c8262344f06096514d1e72d3c026fa4002d917846ce81217d4258acd861324"}, + {file = "pyobjc_framework_EventKit-10.2-py2.py3-none-any.whl", hash = "sha256:c9afa63fc2924281fdf1ef6c86cc2ba01b7b84a8545a826ddd89e4abd7077e81"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-exceptionhandling" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ExceptionHandling on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ExceptionHandling-10.1.tar.gz", hash = "sha256:ac75ac230249d6f26f750beb406c133a49d4a284e7ee62ba1139e9d9bc5ec44d"}, - {file = "pyobjc_framework_ExceptionHandling-10.1-py2.py3-none-any.whl", hash = "sha256:b8eb9142f141361982e498610bfd33803acb4f471f80b5cd9df8d382142449e9"}, + {file = "pyobjc-framework-ExceptionHandling-10.2.tar.gz", hash = "sha256:cf4cd143c24504d66ef9d4e67b4b88e2ac892716e6ead2aa9585a7d39278d943"}, + {file = "pyobjc_framework_ExceptionHandling-10.2-py2.py3-none-any.whl", hash = "sha256:fd7dfc197c29ccf187718dbb0b1dcd966a8c04ee6549ee9472959912e76a0609"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-executionpolicy" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ExecutionPolicy on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ExecutionPolicy-10.1.tar.gz", hash = "sha256:5ab7da37722b468a5e230354fa45a6a96e545c6c2aab5a76029e2227b1bae326"}, - {file = "pyobjc_framework_ExecutionPolicy-10.1-py2.py3-none-any.whl", hash = "sha256:556aa28220438b64e6f75f539f133616a343abe3e2565f0d016091f4dc4a9c3d"}, + {file = "pyobjc-framework-ExecutionPolicy-10.2.tar.gz", hash = "sha256:8976c35a58c2e51d6574123ecfcd58459bbdb32b3992716119a3c001d3cc2bcf"}, + {file = "pyobjc_framework_ExecutionPolicy-10.2-py2.py3-none-any.whl", hash = "sha256:4d95d55f82a15286035bb5bc01b339d6c36103a1cbf7d6a3d7a9feac71663626"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-extensionkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ExtensionKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ExtensionKit-10.1.tar.gz", hash = "sha256:4f0a5256149502eeb1b4e1af1455de629a3c3326aaf4d766937212e56355ad58"}, - {file = "pyobjc_framework_ExtensionKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:82eece8d6d807bafb5cf8a220c58f2b42b350a0bc9131cb0cdfd29e90294858d"}, - {file = "pyobjc_framework_ExtensionKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9e9936cfe8a17c09457aa10c21f90f77151328596bd72b55fd9b6c3e78a11384"}, - {file = "pyobjc_framework_ExtensionKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:94cdc24e19ed554bc1d8e9d11139839033b26997f5b29a381ed4be8633ad2569"}, + {file = "pyobjc-framework-ExtensionKit-10.2.tar.gz", hash = "sha256:343c17ec1696947cde6764b32f741d00d7424a620cdbaa91d9bcf47025b77718"}, + {file = "pyobjc_framework_ExtensionKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:69981d3a0f7146b57b16f1132c114419a2b89fa201677c7e240f861bc7e56670"}, + {file = "pyobjc_framework_ExtensionKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:30fa27de3f97436c867ca3e89d8e95f141337a9377f71be3c8a036795b5557fb"}, + {file = "pyobjc_framework_ExtensionKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:09e1402c9fd7c6fcacd662caa2198d79342b812665980fd9a66e906743bddf69"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-externalaccessory" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ExternalAccessory on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ExternalAccessory-10.1.tar.gz", hash = "sha256:1c206f2e27aedb0258a3cf425ed89cbea0657521829f061362b4fca586e033a8"}, - {file = "pyobjc_framework_ExternalAccessory-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:519c36e63011a797f1747306132957168eed53456e801973c38c52b06b265a0e"}, - {file = "pyobjc_framework_ExternalAccessory-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8c54367b52cc74231df057c9bbf722896d98efd91f6d6a7415e0ca7227f311b9"}, - {file = "pyobjc_framework_ExternalAccessory-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:64facb48377840e72e459f9ae88d482d0d17a1726733b2d79205de4e4449eb89"}, + {file = "pyobjc-framework-ExternalAccessory-10.2.tar.gz", hash = "sha256:e62af0029b2fd7e07c17a4abe52b20495dba05cba45d7e901acbd43ad19c4cc3"}, + {file = "pyobjc_framework_ExternalAccessory-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b279672b05f0f8a11201a5ed8754bcea5b8d3e6226ec16c6b59127e2c6e25259"}, + {file = "pyobjc_framework_ExternalAccessory-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5fbe16bb4831a30659cba6a53b77dca94b72ff12bfd318c76f118f39557427c5"}, + {file = "pyobjc_framework_ExternalAccessory-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f446ce468a369650c4c49947bb7329c58c68cd44aee801506e60be1f26cd6265"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-fileprovider" -version = "10.1" +version = "10.2" description = "Wrappers for the framework FileProvider on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-FileProvider-10.1.tar.gz", hash = "sha256:617811be28bd5d9b0cc87389073ade7593f89ee342a5d6d5ce619912748d8e00"}, - {file = "pyobjc_framework_FileProvider-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9e98efd27f69c8275dc8220dfb2bb41a486400c1fb839940cd298b8d1e44adca"}, - {file = "pyobjc_framework_FileProvider-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7046144d86b94707fea6d8bb00b2850f99e0ebaef136ee2b3db884516b585529"}, - {file = "pyobjc_framework_FileProvider-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2f4c816b87237ab2ddfb0314296e5824411cec11f9c1b5919f8b4e8c02069ff1"}, - {file = "pyobjc_framework_FileProvider-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8476daf2c291f6bc1c9f4a26f4492236a2e427774fd02a03c561c667e9ec0931"}, - {file = "pyobjc_framework_FileProvider-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:de3dcbe70943b3bf057f634be4003fdcc112e3d7296f1631be1bf20f494db212"}, - {file = "pyobjc_framework_FileProvider-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a53ebe7e4a6ef24cf3ade1c936a96a1cb0c40dd7639899e3e238e050d4813417"}, + {file = "pyobjc-framework-FileProvider-10.2.tar.gz", hash = "sha256:1accc2965c59395152d04b2f4a096cb4a5364bca8094695ce2b60d2f794bff74"}, + {file = "pyobjc_framework_FileProvider-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e69d294b0ac9fdcafb28fbb1b9770e1e851cc5467dc0ae1d7b182882ce16d1d"}, + {file = "pyobjc_framework_FileProvider-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1d5cc02d43f2c6851934c8208cd4a66ad007daf0db673f72d1938677c90b1208"}, + {file = "pyobjc_framework_FileProvider-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0ae00a293e3ac511cc9eb54ee05b67583ea35d490b47f23f448a3da6652c189b"}, + {file = "pyobjc_framework_FileProvider-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fab7da3c7961e77b09f34cb71a876205ea8d73f9d10d5db78080f7282dd5066f"}, + {file = "pyobjc_framework_FileProvider-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:5d2b581c8cb1c15304676f5a77c42e430aaad886ac92d8b2d4e5cec57cb86be3"}, + {file = "pyobjc_framework_FileProvider-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c471c0d27d9d6a7bba3d06f679f14ac8d719ed3660d9a8e6788a31e1521e71d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-fileproviderui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework FileProviderUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-FileProviderUI-10.1.tar.gz", hash = "sha256:e8f40b41f63d51401fb2aa5881dbf57ef6eacaa6c4d95f3dd1d9eb1b392a2d84"}, - {file = "pyobjc_framework_FileProviderUI-10.1-py2.py3-none-any.whl", hash = "sha256:ef85cead617c3e9b851589505503d201197bbc0ee27117a77243a1a4e99fad7d"}, + {file = "pyobjc-framework-FileProviderUI-10.2.tar.gz", hash = "sha256:a22204c1fad818e4c8d94ecb544fec59387e01a0074cbe2ca6e58de1a12c157e"}, + {file = "pyobjc_framework_FileProviderUI-10.2-py2.py3-none-any.whl", hash = "sha256:5fac2067c09a23a436708e05d71faf65d64f4c36b45ad254617720b1a682aad6"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-FileProvider = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-FileProvider = ">=10.2" [[package]] name = "pyobjc-framework-findersync" -version = "10.1" +version = "10.2" description = "Wrappers for the framework FinderSync on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-FinderSync-10.1.tar.gz", hash = "sha256:5b1fb13c10d0f9bf8bccdacd0ecd894d79376747bd13aca5a410f65306bcbc29"}, - {file = "pyobjc_framework_FinderSync-10.1-py2.py3-none-any.whl", hash = "sha256:e5a5ff1e7d55edb5208ce04868fcf2f92611053476fbbf8f48daa3064d56deb5"}, + {file = "pyobjc-framework-FinderSync-10.2.tar.gz", hash = "sha256:5ecbe9bf7fe77f28204fbe358ee541fdd2786fc076a631c4f11b74377d60ea05"}, + {file = "pyobjc_framework_FinderSync-10.2-py2.py3-none-any.whl", hash = "sha256:11d569492efe74a52883e6086038ca9d5a712a08db828f3ca43c03e756013801"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-fsevents" -version = "10.1" +version = "10.2" description = "Wrappers for the framework FSEvents on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-FSEvents-10.1.tar.gz", hash = "sha256:f5dee8cfbd878006814db264c5f70aeb1a43c06620e98f628ca6c0008beb1b1d"}, - {file = "pyobjc_framework_FSEvents-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:3c2bf6ffd49fd21df73a39e61b81d7c6651e1063f72b62b2218c6ab4bf91dc02"}, - {file = "pyobjc_framework_FSEvents-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9e57dccf14720c0789811580cb99e325353259cc96514e2622ca512e70f392c2"}, - {file = "pyobjc_framework_FSEvents-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f026f417b25f804c6994d49af0743177ca7119d5d9e885a80d71c624e12a5d47"}, + {file = "pyobjc-framework-FSEvents-10.2.tar.gz", hash = "sha256:3a75f38bb1d5d2cf6a0d3e92801b3510f32e96cf6443d81b9dd92a84d72eff0a"}, + {file = "pyobjc_framework_FSEvents-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:129f9654ab9074eff29ccb8dd09625e3740058744a38f9776d0349387f518715"}, + {file = "pyobjc_framework_FSEvents-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c71699f24482d99ee8f6b7a8d36c4c294655c670d8cbd0f3c6f146a2fda6283c"}, + {file = "pyobjc_framework_FSEvents-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a0ff7bb8c1a357181345ff3a90b7f808cd55c4757df60c723541f0f469323190"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-gamecenter" -version = "10.1" +version = "10.2" description = "Wrappers for the framework GameCenter on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-GameCenter-10.1.tar.gz", hash = "sha256:0d124b3f18bb1b3e134268c99bf92c29791e8c62a97095c1fb1eb912ebe495e0"}, - {file = "pyobjc_framework_GameCenter-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5d6cf2405e5107c8befcb61a5339c0766fbab9448a2c4e8f5dd4401a7ef380ab"}, - {file = "pyobjc_framework_GameCenter-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8ede397f1ca31022e7507cb1cf801617094e407300ee29c19415fd32f64fa758"}, - {file = "pyobjc_framework_GameCenter-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:db4e36a573e91715d8ed5250f6784fe5b03c8b2e769b97f8cf836eb7111c3777"}, + {file = "pyobjc-framework-GameCenter-10.2.tar.gz", hash = "sha256:43341b428cad2e50710cb974728924280e520e04ae9f750bc7beda5006457ae3"}, + {file = "pyobjc_framework_GameCenter-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f14ad00713519b508f4c956a8212bff01f6b6279b2a76e87d99a18262e61dfda"}, + {file = "pyobjc_framework_GameCenter-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b52932e90c6b6d90ce8c895b0ac878dc4e639d493724a5789fc990e1efec3d05"}, + {file = "pyobjc_framework_GameCenter-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:dc9de1b3d0db1921fb197ad964226ebc271744aee0cc792f9fe66afaf92b24f0"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-gamecontroller" -version = "10.1" +version = "10.2" description = "Wrappers for the framework GameController on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-GameController-10.1.tar.gz", hash = "sha256:50a17fdd151f31b3a5eae9ae811f6f48680316a5c2686413b9a607c25b6be4bc"}, - {file = "pyobjc_framework_GameController-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ec7e84c2dbc90065db8d0293c29e34d95b4fa14beeb3fb3c818fa3bcdf24d89a"}, - {file = "pyobjc_framework_GameController-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:672d99f849b803c6c6b8e89445e2c446379ae23f1f0f7e355a2a94f91d591fea"}, - {file = "pyobjc_framework_GameController-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:c56232fc2f0e95901e66534d18a008857c59363078ac75fedb2d18dcbd5dda63"}, + {file = "pyobjc-framework-GameController-10.2.tar.gz", hash = "sha256:81ad502346904995ec04b0580bab94ab32ca847fad06bca88cdf2ec6222b80ae"}, + {file = "pyobjc_framework_GameController-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:47e6dfcf10353a17adcfa7649d0f5d0cba4d4dc3ce3a66826d873574ae2afcb1"}, + {file = "pyobjc_framework_GameController-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8ef6fcb5308c1c31d1de3969165a13750b74f52c80249b722383307fc558edff"}, + {file = "pyobjc_framework_GameController-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:89a7aac243b0347c3ef10fc2bcedcb1b2ae9eb14daabccb3f3cfe1cf12c7e572"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-gamekit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework GameKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-GameKit-10.1.tar.gz", hash = "sha256:6fa87a29556cdaf78c86851fc61edb6d384f1a7370a75a66bdd208ed1250899f"}, - {file = "pyobjc_framework_GameKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bb00618d256f67b6f784b49db78bde80677a2004af4558266009de30e8804660"}, - {file = "pyobjc_framework_GameKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:38bcce65b781c5967eb7985b551ca015cda89903d18f29eab74518a52f626fec"}, - {file = "pyobjc_framework_GameKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:773e6f645731dac7c2b6e55ec7ecd92928b070f7a33b4c5ce33a3a52565ecd49"}, + {file = "pyobjc-framework-GameKit-10.2.tar.gz", hash = "sha256:0ef877db88e8888ecf682b09b9fb1ee6b879f23d521ce3a738a1b0fb2b885974"}, + {file = "pyobjc_framework_GameKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c23025087bec023a37fe0c84fcdc592cdc100d9187b49250446587f09571dbeb"}, + {file = "pyobjc_framework_GameKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6867159762db0a72046abe42df8dff080620c2f9cdf20927445eec28f3f04124"}, + {file = "pyobjc_framework_GameKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e7d91d28c4c8d240f0fbab80f84545efbeeb5a42db4c6fbd4ccb1f3face88c9c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-gameplaykit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework GameplayKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-GameplayKit-10.1.tar.gz", hash = "sha256:12a5d1dc59668df155436250476af029b1765ca68e7a1e2d440158e7130232a3"}, - {file = "pyobjc_framework_GameplayKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f877d2c449aea09187856540b3d5a3e6a98573673a09af6163b1217040d93e5f"}, - {file = "pyobjc_framework_GameplayKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:86e320c79707ab7a3de2f23d0d32bd151b685865f43d13fb58daa2963b4da5cc"}, - {file = "pyobjc_framework_GameplayKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:93a1e62c2875d7705d1aa70115f646258ecffc4d4702ed940a5214dc0ea580f5"}, + {file = "pyobjc-framework-GameplayKit-10.2.tar.gz", hash = "sha256:068ee6f3586f4033d25ed3b0451eab8f388b2970be1dfbe39be01accca7a9b2e"}, + {file = "pyobjc_framework_GameplayKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c9e87b8221a74599c813640b823f3a2546aa6076b04087f26fd3ecc8c78cbe01"}, + {file = "pyobjc_framework_GameplayKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a1f81c969347d63a1200818ae12350ad39353e85842f34040b9d997e55f7ec89"}, + {file = "pyobjc_framework_GameplayKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f438c4b98e1d00dec84fedc8796761063e99814f913151441bc7147ac8b23068"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-SpriteKit = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-SpriteKit = ">=10.2" [[package]] name = "pyobjc-framework-healthkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework HealthKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-HealthKit-10.1.tar.gz", hash = "sha256:9479c467514c506f9083889f11da6b8f34d705f716ffe9cbbb5a3157000d24de"}, - {file = "pyobjc_framework_HealthKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b32171f6d4ee6fa37718f5b299c6b866a4ae395ff8764ccc040b9d1263a3e74f"}, - {file = "pyobjc_framework_HealthKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a628c777c02df6c5dbbc5f26576f52239dab79ac1afe5ca53d40d561d55adb52"}, - {file = "pyobjc_framework_HealthKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d44c5ace78dce1f0c76b96010d9446b90a9474946a25bfb33d373a152e22524"}, + {file = "pyobjc-framework-HealthKit-10.2.tar.gz", hash = "sha256:abcc4e6bd0e11eace7257887958b6cc5332f8aad4efa6b94e930425016540789"}, + {file = "pyobjc_framework_HealthKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:093687705413b88efe47097f09c7be84b6ccbb7ec0f9b943b4ad19fe9fbdc01c"}, + {file = "pyobjc_framework_HealthKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1fb83b08ed28b9adc9a8a2379dbf5f7515e01009160a86847e1a5f71b491a49c"}, + {file = "pyobjc_framework_HealthKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b84d3857c54076a63feea7072ecf98d925f68f96413ca40164d04b2fd865a4dc"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-imagecapturecore" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ImageCaptureCore on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ImageCaptureCore-10.1.tar.gz", hash = "sha256:29b85ee9af77bba7e1ea9191bf84edad39d07681b9bd267c8f5057db3b0cdd64"}, - {file = "pyobjc_framework_ImageCaptureCore-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8d2dbc09aed984f7d92e7b835e87608d356f5f4b6dd03e84258963391791ae5"}, - {file = "pyobjc_framework_ImageCaptureCore-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5eef95798d340000ddfb9c59c9468b75bb4cd389d311fd27078c3f4a4a3af29a"}, - {file = "pyobjc_framework_ImageCaptureCore-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:832cbe0d957935553183586556d2036cfcc9aae593defe71e6a0726e5c63abf6"}, + {file = "pyobjc-framework-ImageCaptureCore-10.2.tar.gz", hash = "sha256:68f1f96982282e786c9c387c177c3b14202d560d68000136562eba1ed3f45a6e"}, + {file = "pyobjc_framework_ImageCaptureCore-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:69c19e235de32bc707a622fd2865fa53f6e7692b52851d559ea0c23664ee7665"}, + {file = "pyobjc_framework_ImageCaptureCore-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3bdbae9adf6456b4b4e2847135e5da214516545638dd715f01573ec6b6324af6"}, + {file = "pyobjc_framework_ImageCaptureCore-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:46b90bc950646b69b416949bb50ee7d2189b42b7aa77692e01d7c1b4062ddc19"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-inputmethodkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework InputMethodKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-InputMethodKit-10.1.tar.gz", hash = "sha256:b995f43a8859016474098c894c966718afe9fbcc18996ce3c6bebfc6a64cfad7"}, - {file = "pyobjc_framework_InputMethodKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5288d12d1a2a6da9261c0cadbee03f31c80a0a3bb77645b4e7c2836864f54533"}, - {file = "pyobjc_framework_InputMethodKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e04ac004ac848492242fda193e63322abce87ecdef081f1b7268cac7f2af8ad"}, - {file = "pyobjc_framework_InputMethodKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:538d5955a8ab3a9c7a7286c72dba87634ba0babe7cd0a4cec335100df8789c01"}, + {file = "pyobjc-framework-InputMethodKit-10.2.tar.gz", hash = "sha256:294cf2c50cdbb4cdc8f06946924a01faf45a7356ef86652d73c1f310fc1ce99f"}, + {file = "pyobjc_framework_InputMethodKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f8bcb156dcd1dc77826f720ff70f9a12c72ad45e97d4faa7ca88e85fc2d7843a"}, + {file = "pyobjc_framework_InputMethodKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d96a18dd92dc19f631ed50c524355ab29f79975e081f516ad3cea2d902a277e7"}, + {file = "pyobjc_framework_InputMethodKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:fdea1320a3cf6e409ab8f602b90b167110f7ca58f44f95a52f188c6f59f08753"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-installerplugins" -version = "10.1" +version = "10.2" description = "Wrappers for the framework InstallerPlugins on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-InstallerPlugins-10.1.tar.gz", hash = "sha256:4c9f8b46d43f1277aad3bea648f84754e9f48251a6fb385ad8119c1b44dffe9b"}, - {file = "pyobjc_framework_InstallerPlugins-10.1-py2.py3-none-any.whl", hash = "sha256:195e7d559421bf36479b085bf74d56f8549fff715596fc21e0e0c95989a3149a"}, + {file = "pyobjc-framework-InstallerPlugins-10.2.tar.gz", hash = "sha256:001e9ec6489e49fc22bbec1ef050518213292e8d56239ed004f98ed038b164e2"}, + {file = "pyobjc_framework_InstallerPlugins-10.2-py2.py3-none-any.whl", hash = "sha256:754b8fdf462b6e568f30249255af50f9bd3ac90edacfe6e02d0fe77f276c049b"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-instantmessage" -version = "10.1" +version = "10.2" description = "Wrappers for the framework InstantMessage on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-InstantMessage-10.1.tar.gz", hash = "sha256:8e8e7e2c64a3a6b0aa67cace58f7cea1971bb93de57be40b7ba285e305fab0b5"}, - {file = "pyobjc_framework_InstantMessage-10.1-py2.py3-none-any.whl", hash = "sha256:c03a9a99faaa14ff0a477114b691d628117422a15995523deb25ff2d1d07a36d"}, + {file = "pyobjc-framework-InstantMessage-10.2.tar.gz", hash = "sha256:4aa7627697fa57120594477f1f287bc41836ec7a4107215d3060c26416cf72c9"}, + {file = "pyobjc_framework_InstantMessage-10.2-py2.py3-none-any.whl", hash = "sha256:65db5cb1f163700a6cb915506f8f7ae2f28d8d3f6464f7b122b0535b1694859a"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-intents" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Intents on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Intents-10.1.tar.gz", hash = "sha256:85a84a5912b8d8a876767ca8fa220dc24bf1c075ed81b58c386d25c835cec804"}, - {file = "pyobjc_framework_Intents-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:64a3cef4af536de1153937d99a4cb8d0568ca20ee5c74458dca4f270b01a3c1a"}, - {file = "pyobjc_framework_Intents-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:89f49f82245d4facb329dd65434a602506246e6585f544ab78b0ab4bd151f4f7"}, - {file = "pyobjc_framework_Intents-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:bc6f93d151c4474150b6c76fe43067d2d0d06446851d66df3bb9968682a2d225"}, + {file = "pyobjc-framework-Intents-10.2.tar.gz", hash = "sha256:ec27d5d19212fcec180ff04e2bc617fee0a018e2eaf29b2590c5512da167aa6a"}, + {file = "pyobjc_framework_Intents-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6a4e2ba2b5319c15ceeabdfd06f258789174e7e31011a24eab489d685066ed69"}, + {file = "pyobjc_framework_Intents-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9a3c08ec0dd199305989786e6e3c68d27f40b9eae3050bbf0207f053190f3513"}, + {file = "pyobjc_framework_Intents-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:3dc9233522564ea8850a02961398a591446e0a0a0e63cd42cf7820daa0242f6a"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-intentsui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Intents on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-IntentsUI-10.1.tar.gz", hash = "sha256:01948fbd8f956a79d3c2e27f75bc9954ad12cb4113982f58654122cfa8095ebb"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e829659751ff47e3b85980075897ddebbf62d5644478c1bb2ff1dcdc116b8897"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0d6ac451433ec0602c661b32216cd3c44b1c99b9f41781b3af79b7941118552"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1806e6189cf09c0b031594ad445da1a93c30c399298c6fce2369a49bac7eade4"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33518f549b6c501d7c6c36542154ae5d2255d7223804470e14cd76b325676a48"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:91498d3cf4098fe412ea66c01b080919906dd23d53653d49addc7a26c50e570f"}, - {file = "pyobjc_framework_IntentsUI-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c73626bfad3f098eed4a446cee90154dec39d9a9c0775532980c5266bc91a4c"}, + {file = "pyobjc-framework-IntentsUI-10.2.tar.gz", hash = "sha256:4b9ca6f868b6cb7945ef4c285e73d220433efc35dfcad6b4a356bfce55e96c09"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ec579d0f25cba0e1225f7690f52ed092bef5e01962fbe83ffbb70ec39861674"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:91331fec42522596500bd0a580c633b7b84831c6316b2ec7458425d60b37da9e"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:81f9d337473b3cb51f2aa4aa98156d6e294778d24fe011f41f0123b2676d824c"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1c52fa06e8d65a003e384afcc1322051f2fbbfeac2c91ab852b407c552fd5652"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:c514ecef1277ff00c07f78f7890e3a6cbe3c8fe44184f2f6da1a7b4b32851605"}, + {file = "pyobjc_framework_IntentsUI-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:22c40c11d5de5a866a5db2b4ba57e9663e79180c323928709eced30c5c03ac81"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Intents = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Intents = ">=10.2" [[package]] name = "pyobjc-framework-iobluetooth" -version = "10.1" +version = "10.2" description = "Wrappers for the framework IOBluetooth on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-IOBluetooth-10.1.tar.gz", hash = "sha256:9a30554f1c9229ba120b2626d420fb44059e4aa7013c11f36ab9637dc3aba21f"}, - {file = "pyobjc_framework_IOBluetooth-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5fd71294464b9d891d3a7ebb674bcc462feb6fbdf33ebd08c1411ef104460f7f"}, - {file = "pyobjc_framework_IOBluetooth-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:88e44f1bb3495c3104d9b0a73b2155e4326366c5f08a6e31ef431ab17f342b24"}, - {file = "pyobjc_framework_IOBluetooth-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:15c1a049e1431996188352784defe54a37181da38a7e5a378fcda77fdc007aea"}, + {file = "pyobjc-framework-IOBluetooth-10.2.tar.gz", hash = "sha256:8c4d6a82d0f550c84dce72188369adb9347ad6ee1c8adef996ee1a8c376c51ee"}, + {file = "pyobjc_framework_IOBluetooth-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:15e8a35431740d3e4ee484d4af01afef0b6b8aee2bdfe7b6dbe6cf7c7cc563fa"}, + {file = "pyobjc_framework_IOBluetooth-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:03ee5ecc3a2d2f6a0b4de9b36bc1c56f820624e8176abca0014c9ef3c86b0cd0"}, + {file = "pyobjc_framework_IOBluetooth-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b91c0b370047b386e9b333ba3c12ac121089fa94291c721e8b1ad6945b5763dd"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-iobluetoothui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework IOBluetoothUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-IOBluetoothUI-10.1.tar.gz", hash = "sha256:979c0d9638c0f31e62afe90d8089e61a912d08e0db893a47d3e423b9b23e0db2"}, - {file = "pyobjc_framework_IOBluetoothUI-10.1-py2.py3-none-any.whl", hash = "sha256:809eeb98ce71d0d4a7538fb77f14d1e7cd2c2b91c10605fb8c0d69dbac205de5"}, + {file = "pyobjc-framework-IOBluetoothUI-10.2.tar.gz", hash = "sha256:ed9f4cb62eeda769b3f530ce396fd332f82441c5d22b9cf7b58058670c262d10"}, + {file = "pyobjc_framework_IOBluetoothUI-10.2-py2.py3-none-any.whl", hash = "sha256:f833efa3b1636f7a6cf8b5b2d25fc566757c2c7c06ee7945023aeb992493d96e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-IOBluetooth = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-IOBluetooth = ">=10.2" [[package]] name = "pyobjc-framework-iosurface" -version = "10.1" +version = "10.2" description = "Wrappers for the framework IOSurface on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-IOSurface-10.1.tar.gz", hash = "sha256:e41c635c5e259019df243da8910675db10480a36d0c316539a8ab3fa0d941000"}, - {file = "pyobjc_framework_IOSurface-10.1-py2.py3-none-any.whl", hash = "sha256:46239320148b82c1f2364d5468999b48fa9c94fc404aff6c5451d23896ece694"}, + {file = "pyobjc-framework-IOSurface-10.2.tar.gz", hash = "sha256:f1412c2f029aa1d60add57abefe63ea4116b990892ef7530ae27a974efafdb42"}, + {file = "pyobjc_framework_IOSurface-10.2-py2.py3-none-any.whl", hash = "sha256:b571335a2150e865828d3e52e2a742531499c88dd85215c14d07e68e9bed70a7"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-ituneslibrary" -version = "10.1" +version = "10.2" description = "Wrappers for the framework iTunesLibrary on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-iTunesLibrary-10.1.tar.gz", hash = "sha256:18766b2fb016d33cde8ec2c81b05ddfb77d65cb8c92e16864d0c288edd02e812"}, - {file = "pyobjc_framework_iTunesLibrary-10.1-py2.py3-none-any.whl", hash = "sha256:043a2ede182f41a3ca70be50bf95f18641e2945f0077797ff2bb42a3e1984e37"}, + {file = "pyobjc-framework-iTunesLibrary-10.2.tar.gz", hash = "sha256:c60d1dc9eabb28b036b766b89ea7d18198e21deb8925fc5a5753777c905ecddf"}, + {file = "pyobjc_framework_iTunesLibrary-10.2-py2.py3-none-any.whl", hash = "sha256:4e6cf6073a902f77e0b0c33d2d52e3ab3f0c869cb339b7685b5e7f079df8ef4e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-kernelmanagement" -version = "10.1" +version = "10.2" description = "Wrappers for the framework KernelManagement on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-KernelManagement-10.1.tar.gz", hash = "sha256:da8ac0e6a2de33b823e07ce0462a64340cfebd04f24426b1022374933bbd8d0a"}, - {file = "pyobjc_framework_KernelManagement-10.1-py2.py3-none-any.whl", hash = "sha256:923ff2bbab35a92b9becd9762348f6f690fa463ef07a0e5c4a2b8eb1d3e096af"}, + {file = "pyobjc-framework-KernelManagement-10.2.tar.gz", hash = "sha256:effd1d3230c8a3b8628e7fd315f0aac10fbf1ea99f2ed923999cb1ab787c317a"}, + {file = "pyobjc_framework_KernelManagement-10.2-py2.py3-none-any.whl", hash = "sha256:d8dca9dc1f756bfa894a32f56857ecefb4d188aec590433ee302529261dffb68"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-latentsemanticmapping" -version = "10.1" +version = "10.2" description = "Wrappers for the framework LatentSemanticMapping on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-LatentSemanticMapping-10.1.tar.gz", hash = "sha256:46e95532c71083d1e63bcfa4b89a56fcf860288f8fb04fc0313e4c40685d1916"}, - {file = "pyobjc_framework_LatentSemanticMapping-10.1-py2.py3-none-any.whl", hash = "sha256:f0b14a1a2a6d6b25b902a2cc5949f0145926f0b0a3132d17210b1a580dc7f0f5"}, + {file = "pyobjc-framework-LatentSemanticMapping-10.2.tar.gz", hash = "sha256:eb3ddd5e04c39b0151a64bd356f7de3c66062257e3802e8abea7a882e972ff21"}, + {file = "pyobjc_framework_LatentSemanticMapping-10.2-py2.py3-none-any.whl", hash = "sha256:dadd4352b9af681dd85d04712a6cf1d2c574acbf0b8178c35f42231ec8c5a6d1"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-launchservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework LaunchServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-LaunchServices-10.1.tar.gz", hash = "sha256:c0ef72f7cee77556c81e620ae8c511e73bdea4f644a233c8a5e3a333f5cd3d7d"}, - {file = "pyobjc_framework_LaunchServices-10.1-py2.py3-none-any.whl", hash = "sha256:b792a863427a2c59c884952737041e25ef05bdb541471ce94fb26a05b48abbbc"}, + {file = "pyobjc-framework-LaunchServices-10.2.tar.gz", hash = "sha256:d9f78d702dea13a363de8a7c1c382e1ca872993980c164781cb2758ee49353d2"}, + {file = "pyobjc_framework_LaunchServices-10.2-py2.py3-none-any.whl", hash = "sha256:15b7c96e3059550c218ed5cb5de11dddc7aae21c67c0808b130a5d49b8f4cc0f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-CoreServices = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-CoreServices = ">=10.2" [[package]] name = "pyobjc-framework-libdispatch" -version = "10.1" +version = "10.2" description = "Wrappers for libdispatch on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-libdispatch-10.1.tar.gz", hash = "sha256:444ca20e348cbdd2963523b89661d67743a6c87a57caf9e5d546665baf384a5b"}, - {file = "pyobjc_framework_libdispatch-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da0fa1e63b7e72010c69341bcd2f523ade827c7f30e0ef5c901a2536f43a1262"}, - {file = "pyobjc_framework_libdispatch-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bd72ff7f399079eaf8135503c3658b3ce967076a9e3fdcd155c8a589134e476a"}, - {file = "pyobjc_framework_libdispatch-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ec061cba47247a5fd5788c3b9d5eba30936df3328f91fea63a565d09c53a0a02"}, - {file = "pyobjc_framework_libdispatch-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c71c8c9dca56b0e89ac7c4aff4b53bc74f64a2290e48c31cc77d87771c5203bd"}, - {file = "pyobjc_framework_libdispatch-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:b24a76fe2de4422685323e4f533b7bfd11a27edf06094c0f730f3f243f94a8bd"}, - {file = "pyobjc_framework_libdispatch-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:606954514e5747b05f9c608614f1affa44512888d18805452fade5d9b7938c14"}, + {file = "pyobjc-framework-libdispatch-10.2.tar.gz", hash = "sha256:ae17602efbe628fa0432bcf436ee8137d2239a70669faefad420cd527e3ad567"}, + {file = "pyobjc_framework_libdispatch-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:955d3e3e5ee74f6707ab06cc76ad3fae27e78c180dea13f1b85e2659f9135889"}, + {file = "pyobjc_framework_libdispatch-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:011736d708067d9b21a4722bae0ed776cbf84c8625fc81648de26228ca093f6b"}, + {file = "pyobjc_framework_libdispatch-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:28c2a2ab2b4d2930f7c7865ad96c1157ad50ac93c58ffff64d889f769917a280"}, + {file = "pyobjc_framework_libdispatch-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6cb0879e1f6773ad0bbeb82d495ad0d76d8c24b196a314ac9a6eab8eed1736e0"}, + {file = "pyobjc_framework_libdispatch-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:aa921cd469a1c2e20d8ba9118989fe4e827cbb98e947fd11ae0392f36db3afcc"}, + {file = "pyobjc_framework_libdispatch-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6f3d57d24f81878d1b5dcb00a13f85465ede5b91589394f4f1b9dcf312f3bd99"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-libxpc" -version = "10.1" +version = "10.2" description = "Wrappers for xpc on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-libxpc-10.1.tar.gz", hash = "sha256:8e768bb3052b30ef3938c41c9b9a52ad9d454c105d2011f5247f9ffb151e3702"}, - {file = "pyobjc_framework_libxpc-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5a3efe43b370fdc4d166ddfd8d1f74b5c3ae5f9b273e5738253c3d9a2bebf27"}, - {file = "pyobjc_framework_libxpc-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dc16190cbcaf8639f4783058ec63b1aa5d03e3586311f171177b9275ed5725d8"}, - {file = "pyobjc_framework_libxpc-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3f0756945995da4cb503dc9ca31b0633b7044722b08348a240ebe6f594d43c0c"}, - {file = "pyobjc_framework_libxpc-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d5a7f06f437c6a23c469299a3a15b62f8b4661563499b0f04d9fe8ea5e75a95"}, - {file = "pyobjc_framework_libxpc-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9341237ffaedb3169037a666564615fefd921e190e6ec3e951dc75384169a320"}, - {file = "pyobjc_framework_libxpc-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:57eaa7242ef4afe3e8d1fbe48f259613322549353250400c8d508afff251dde4"}, + {file = "pyobjc-framework-libxpc-10.2.tar.gz", hash = "sha256:04deac1f9dbd1c19c10d175846017f8e8e51d2b52a2674482638d6b289e883a6"}, + {file = "pyobjc_framework_libxpc-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b57089f792d51ad687c9933dd2d3669cd5e6f84d1f9213738ecc5833dba9aa8c"}, + {file = "pyobjc_framework_libxpc-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e31cb4f7fdb76defc53fe0b56c3f1db953c1dcf3519093835527f270c37315c3"}, + {file = "pyobjc_framework_libxpc-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:978cc2a9cc668e0c4aef13af81cec6129e7b98877b44c952232c0083a8fd352e"}, + {file = "pyobjc_framework_libxpc-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5dd057a556398b48982fdae84f8e08ee9b69b6e5918b6782bd842ef9ad97820d"}, + {file = "pyobjc_framework_libxpc-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:df394dc08eab33430f565a2252906f27cd4f7c41fd431f75b4ae35d3a76f4eab"}, + {file = "pyobjc_framework_libxpc-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fd3608a32ebe65253c24b7590ad96977135aa847dd188e4c2168f0da9e74e47"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-linkpresentation" -version = "10.1" +version = "10.2" description = "Wrappers for the framework LinkPresentation on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-LinkPresentation-10.1.tar.gz", hash = "sha256:d35f9436f6a72c0877479083118f57a42c0d01879df41ee832378bebef37e93c"}, - {file = "pyobjc_framework_LinkPresentation-10.1-py2.py3-none-any.whl", hash = "sha256:077c28c038b1aac0e5cd158cbf8b80863627f1254f0a1884440fabf95d46d62f"}, + {file = "pyobjc-framework-LinkPresentation-10.2.tar.gz", hash = "sha256:4ccae5f593b58dfe9cb422645e0ccf5adab906ec008d3e20eb710cd62bbb4717"}, + {file = "pyobjc_framework_LinkPresentation-10.2-py2.py3-none-any.whl", hash = "sha256:1cada96d3eb03e51e1bbb7e7c10b9c08c80fd098132541b4e992234fe43cfa37"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-localauthentication" -version = "10.1" +version = "10.2" description = "Wrappers for the framework LocalAuthentication on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-LocalAuthentication-10.1.tar.gz", hash = "sha256:e2b06bf7af1b6f8ba08bd59e1a3616732d801284362dd5482181b0b1488eca2d"}, - {file = "pyobjc_framework_LocalAuthentication-10.1-py2.py3-none-any.whl", hash = "sha256:3df6ac268f79f28e5b5e76b4fd6e095bdc9a200e1908f24cc33e805fa789f716"}, + {file = "pyobjc-framework-LocalAuthentication-10.2.tar.gz", hash = "sha256:26e899e8b4a90632958eb323abbc06d7b55c64d894d4530a9cc92d49dc115a7e"}, + {file = "pyobjc_framework_LocalAuthentication-10.2-py2.py3-none-any.whl", hash = "sha256:442f6cae70300f29c9133ed7f2e01c294976b9aae55fe180c64983d5dee62254"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Security = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Security = ">=10.2" [[package]] name = "pyobjc-framework-localauthenticationembeddedui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework LocalAuthenticationEmbeddedUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-LocalAuthenticationEmbeddedUI-10.1.tar.gz", hash = "sha256:5a201e26c7710f8e8a6507dbb861baa545dc5abcbe0f3f6a19b2e270562c7bec"}, - {file = "pyobjc_framework_LocalAuthenticationEmbeddedUI-10.1-py2.py3-none-any.whl", hash = "sha256:a8e8101ca74441a862ffb8e2309fe382789c759d0951fb7b7b4e46652b4cb068"}, + {file = "pyobjc-framework-LocalAuthenticationEmbeddedUI-10.2.tar.gz", hash = "sha256:52acdef34ea38d1381a95de15b19c9543a607aeff11db603371d0224917a8830"}, + {file = "pyobjc_framework_LocalAuthenticationEmbeddedUI-10.2-py2.py3-none-any.whl", hash = "sha256:eafbbc321082ff012cdb14e38abae7ced94c6d962cb64af43d6d515da976e175"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-LocalAuthentication = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-LocalAuthentication = ">=10.2" [[package]] name = "pyobjc-framework-mailkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MailKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MailKit-10.1.tar.gz", hash = "sha256:a4589b13361a49ff0b3e9be43cd6f935a35acfc7a9f0da8b5db64283401da181"}, - {file = "pyobjc_framework_MailKit-10.1-py2.py3-none-any.whl", hash = "sha256:498d743e56d876d6d128970e6c0674470d9a4bcf9c021f0b115aa0c6ade1f5ae"}, + {file = "pyobjc-framework-MailKit-10.2.tar.gz", hash = "sha256:8d8fceff5498df0cfa630b7088814f8daa8a25794a36d4b57cfde8c2c14cdc70"}, + {file = "pyobjc_framework_MailKit-10.2-py2.py3-none-any.whl", hash = "sha256:d8bc9e6649e7e500d2d4d4ab288304846d9bfa06952ebeee621fe095dc2f51eb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-mapkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MapKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MapKit-10.1.tar.gz", hash = "sha256:4e5b295ce1e94ed38888a0c4e3a5a92004e63e6d2ba9a86b5a277bbe658ddf05"}, - {file = "pyobjc_framework_MapKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:7628e7d8e4181f06fc3138b7426593d09fe3d49a056e7e3d5853f7bbcc62b240"}, - {file = "pyobjc_framework_MapKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d5d78c56b2806148f7b4a2975e580bc039f1898ca8953041405683ba6c22f19b"}, - {file = "pyobjc_framework_MapKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b9c942b3a705021561de2a4e1590c58212131c2c7dc721290f68371558a42f35"}, + {file = "pyobjc-framework-MapKit-10.2.tar.gz", hash = "sha256:35dfe7aa5ec9e51abc47d6ceb0f83d3c2b5876258591a568e85e2db8218427c4"}, + {file = "pyobjc_framework_MapKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ce322299b04eef212706185764771041a1220f7a611606e33f95ac355d913238"}, + {file = "pyobjc_framework_MapKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:339a8c8181047fc9eb612eb47c51f017423a6b074e2a4838cd6b06e36af6c160"}, + {file = "pyobjc_framework_MapKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:85a110693198798234d3edbd3b606d9d9c9b4817e4ed70d2b2e18357422783c6"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreLocation = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreLocation = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-mediaaccessibility" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MediaAccessibility on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MediaAccessibility-10.1.tar.gz", hash = "sha256:f487d83f948c12679c1ce06caabaedade1f4aee1f35163f835213c251a4639c7"}, - {file = "pyobjc_framework_MediaAccessibility-10.1-py2.py3-none-any.whl", hash = "sha256:2301cc554396efe449b079f99a0b5812e8e3dc364195dfcd2cc2b8a9c8915f11"}, + {file = "pyobjc-framework-MediaAccessibility-10.2.tar.gz", hash = "sha256:acce0baf11270c9276a219f5a0dfb6d8241e01ac775144bfe3a83e088dcd1308"}, + {file = "pyobjc_framework_MediaAccessibility-10.2-py2.py3-none-any.whl", hash = "sha256:55dbf7519028fadf3ac6cb1ef185156f6df649655075a015cf87cee370255e82"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-medialibrary" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MediaLibrary on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MediaLibrary-10.1.tar.gz", hash = "sha256:cd4815cb270aa2f28acdad8185a4b9d4b76a6177f70e8ed62a610484f4bd44a9"}, - {file = "pyobjc_framework_MediaLibrary-10.1-py2.py3-none-any.whl", hash = "sha256:420d5006c624aaaf583058666fd5900a5619ff1f230e99cdd3acb76c12351a37"}, + {file = "pyobjc-framework-MediaLibrary-10.2.tar.gz", hash = "sha256:b3e1bd3e70f0013bbaccd0b43727a0f16ecf23f7d708ca81b8474faaa1f8e8fc"}, + {file = "pyobjc_framework_MediaLibrary-10.2-py2.py3-none-any.whl", hash = "sha256:98b9687f1399365889529c337d99d7f19edf3a94beb05884cf15a29f4fc178af"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-mediaplayer" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MediaPlayer on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MediaPlayer-10.1.tar.gz", hash = "sha256:394acea4fb61f8c4605494c7c64c52a105760aa2ec7e2c34db484e576ed10ad6"}, - {file = "pyobjc_framework_MediaPlayer-10.1-py2.py3-none-any.whl", hash = "sha256:10e25a8682cd0d1d8fc0041f0a34e8acf785b541d8c1ebe493c2d17caeef5648"}, + {file = "pyobjc-framework-MediaPlayer-10.2.tar.gz", hash = "sha256:4b6d296b084e01fb6e5c782b7b6308077db09f4051f50b0a6c3298ffbd1f1d70"}, + {file = "pyobjc_framework_MediaPlayer-10.2-py2.py3-none-any.whl", hash = "sha256:c501ea19380bfbf6b04fbe909fcfe9a78c5ff2a9b58dae87be259066b1ae3521"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-AVFoundation = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-AVFoundation = ">=10.2" [[package]] name = "pyobjc-framework-mediatoolbox" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MediaToolbox on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MediaToolbox-10.1.tar.gz", hash = "sha256:56906cd90e1f969656db1fecd5874c6345e160044f54596c288fb0ffdb35cdc5"}, - {file = "pyobjc_framework_MediaToolbox-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:23b02872d910481a75db8eeb9c053a16b9a3cff1e030ca29d855ba8291c9501a"}, - {file = "pyobjc_framework_MediaToolbox-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c96557db9540ed18748f47d4cd0b2ba7273acb756bf7e91d8b2a943211850614"}, - {file = "pyobjc_framework_MediaToolbox-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:17ee7f045f39e3f11945bf951dfb4238c695ca49938e8b43c78fe12a8eb05628"}, + {file = "pyobjc-framework-MediaToolbox-10.2.tar.gz", hash = "sha256:614ec0a28c810395274aa1d5348a447f67bae4629a3a8372d14162f38e2fc597"}, + {file = "pyobjc_framework_MediaToolbox-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ca7443bca94dfd9863d5290d2680247b7d577cf031dcfc854c414e5fdd9cdb03"}, + {file = "pyobjc_framework_MediaToolbox-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c34dca15560507286eb9ef045d6234ac1db1e50f22c63397662155a7f01ea9ac"}, + {file = "pyobjc_framework_MediaToolbox-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:696d6cadbb643f98750f5a791663ca264f0a0f4db2aeec7c8cf59c02face1683"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-metal" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Metal on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Metal-10.1.tar.gz", hash = "sha256:bde76fe5d285c9c875d411a7cf6cdd7617559eabf4fb9a588f90762a0634148c"}, - {file = "pyobjc_framework_Metal-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:0701fe5e5aaa5471843fa0d5fe8fe3279313ff83c8bf5230ab6e11f7cba79a78"}, - {file = "pyobjc_framework_Metal-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5f542aaab62b9803e7e644b86dd82718aa9f1bcfc11cb4a666a59f248b3ae2e0"}, - {file = "pyobjc_framework_Metal-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:90ba5118ebf56a152e2404336ad7732dc60f252cd2414d34c9b32c07897f4512"}, + {file = "pyobjc-framework-Metal-10.2.tar.gz", hash = "sha256:652050cf9f5627dba36b31ad134e56c49040d0dcfaf93a7026018ef17330a01e"}, + {file = "pyobjc_framework_Metal-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c68e4025c52e8c8b0fa584abeb058debe49ac3174e8c421408bf873e5951fd02"}, + {file = "pyobjc_framework_Metal-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:49f333f41556f08e28750bb4e09a7053ac55434f4a29a3e228ed4fd9bae8f57d"}, + {file = "pyobjc_framework_Metal-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:0cb39a4f4a70f45f88f79c3641b00b6db0c9b9ed90bee21840a725a8d7c7eaca"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-metalfx" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MetalFX on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MetalFX-10.1.tar.gz", hash = "sha256:64c96595c2489e41d93a1c75d1eace70619d973e5c9e90e7cfca29c934fc5d06"}, - {file = "pyobjc_framework_MetalFX-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:3d456581a76fde824a9109f9dfdd3fc4819e81ae27527b23d2855656ed0ab6ed"}, - {file = "pyobjc_framework_MetalFX-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a3fd4384c83c0818484a3a90120131114a0866b2004309cda24ce873e4ff1e50"}, - {file = "pyobjc_framework_MetalFX-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:76a9ef5abf114c1e2d60b1e971619183f87918eafeb0719a281d1475c88592ad"}, + {file = "pyobjc-framework-MetalFX-10.2.tar.gz", hash = "sha256:d98a0fd1f0d2d3ea54efa768e6817a8773566c820ae7a3a23497e1c492e11da7"}, + {file = "pyobjc_framework_MetalFX-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:e7f1b50316db47ffb1e9505726dfe5bf552f32188d21b6ef979078fec9f58077"}, + {file = "pyobjc_framework_MetalFX-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:526687ac36b71b9822613bf552bff99930ee2620414b0b932f5e0d327d62809e"}, + {file = "pyobjc_framework_MetalFX-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a8c78a8f9c3ee59cb5ba96e4db56c3ab8cc78860f9d42ca5732168d8691cb17b"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Metal = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Metal = ">=10.2" [[package]] name = "pyobjc-framework-metalkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MetalKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MetalKit-10.1.tar.gz", hash = "sha256:da0357868824e6ec506ff92d18d729f8462c4c5ca8f26ecc86e8c031d78fa80d"}, - {file = "pyobjc_framework_MetalKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8723c6b009bf0ce7eb77aa7bdc54f1ee6d0450a3bc2f8ce85523170e92a62152"}, - {file = "pyobjc_framework_MetalKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e94303a78a883e3aa53115c4ebb8329989fcf36be353e908252bba3ba3dc807d"}, - {file = "pyobjc_framework_MetalKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:184922a11f273e604f2c5af2e14ce1f4ef2dce0f5c09aadda857c5a5ca6acab1"}, + {file = "pyobjc-framework-MetalKit-10.2.tar.gz", hash = "sha256:42fc61371d49c2b86828d2a668b7badb2418c0ecce7595fce790830607bd8040"}, + {file = "pyobjc_framework_MetalKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:abcdabdad3d9810730c67f493b70139254f7438ebba0149b5dcd848384a08a85"}, + {file = "pyobjc_framework_MetalKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7990b05194919d187a6af8be7fe51007ab666cfdb3512b6fb022da9049d9957d"}, + {file = "pyobjc_framework_MetalKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:c26c2e2965ae6547edecbc8e250117401c26f62f9a55e351eca42f2e557721e7"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Metal = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Metal = ">=10.2" [[package]] name = "pyobjc-framework-metalperformanceshaders" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MetalPerformanceShaders on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MetalPerformanceShaders-10.1.tar.gz", hash = "sha256:335a49c69ac95e412c581592a148a32c0fcf434097e50da378f21fe09be13738"}, - {file = "pyobjc_framework_MetalPerformanceShaders-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a410b6dce52f7a2adebdb66891bfc33939ffe24bd75691fc30c1f7539521df86"}, - {file = "pyobjc_framework_MetalPerformanceShaders-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7218e89bccadc451f5ba040d84b049fe8b4a4bf7d9a4fdfb20fe6851e433cd49"}, - {file = "pyobjc_framework_MetalPerformanceShaders-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:9452e07d38c7a199c2eebb1280227285f918b97d3d597940e1e6e6471636b44a"}, + {file = "pyobjc-framework-MetalPerformanceShaders-10.2.tar.gz", hash = "sha256:66e6f671279b1f7edbaed1bea8ab1eb57f617e000c1e871c190b60ad60c1d727"}, + {file = "pyobjc_framework_MetalPerformanceShaders-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a65c201921fffb992955aa143ffcb36be3e7c5aee86334941d3214428f0c7ad8"}, + {file = "pyobjc_framework_MetalPerformanceShaders-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9fd437d0b1a83a3bdc866727ba17a00b49ee239205b2d14b617f5ca4f566c4f7"}, + {file = "pyobjc_framework_MetalPerformanceShaders-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:0f862a65ffc0159e6b9ad46115b8d7ecbce5f56fe920c709b943982d4a70d63c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Metal = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Metal = ">=10.2" [[package]] name = "pyobjc-framework-metalperformanceshadersgraph" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MetalPerformanceShadersGraph on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MetalPerformanceShadersGraph-10.1.tar.gz", hash = "sha256:f587a0728e5240669d23a649f50bb25c10577f9775ba4f2576b19423575464a0"}, - {file = "pyobjc_framework_MetalPerformanceShadersGraph-10.1-py2.py3-none-any.whl", hash = "sha256:467e84983c5ded8cfaea8cb425872d5069eda8c4cc1f803ca3afaed0e184c763"}, + {file = "pyobjc-framework-MetalPerformanceShadersGraph-10.2.tar.gz", hash = "sha256:4fffad1c37e700fc38b2ca8eb006d7532b3b5cb700580ce7dfd31af35e0fb6e8"}, + {file = "pyobjc_framework_MetalPerformanceShadersGraph-10.2-py2.py3-none-any.whl", hash = "sha256:7fedd831f9fc58708f6b01888abd42a2f08151c86db47280fe47be0f709811bf"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-MetalPerformanceShaders = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-MetalPerformanceShaders = ">=10.2" [[package]] name = "pyobjc-framework-metrickit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MetricKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MetricKit-10.1.tar.gz", hash = "sha256:6887cec4b7aa489ec16af2f77f7c447bc0a0493456fe1c4910d95a5b3e587fcd"}, - {file = "pyobjc_framework_MetricKit-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02c8775000effbb00f6dde0a493b9ae955e54be4f9e72c4d0f2350d0864b46ac"}, - {file = "pyobjc_framework_MetricKit-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:49f6d9d9c46eb6605799fe0d898945cb62fc5c2d2fea1f7e51950765bbf7b03b"}, - {file = "pyobjc_framework_MetricKit-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6494dac683181dd1ca55b2fc912f693f51483a4e468a3fac05543539a643ca40"}, - {file = "pyobjc_framework_MetricKit-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cb7b318a2e2f4bb841a5427ab53448c827de0f2617123b804c41e6d595581321"}, - {file = "pyobjc_framework_MetricKit-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:5484980ef21e68389ed452f8a4d357f00dabf8711cb5268efe683f758441f23f"}, - {file = "pyobjc_framework_MetricKit-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7dc5a4da156e7f8724969ae329c8bae4fab58c2d7376ae96f62e2d646cc1175c"}, + {file = "pyobjc-framework-MetricKit-10.2.tar.gz", hash = "sha256:14cb02fd8fc338f6f15df5fd14c95419871b768cc8f5f71b1e0e99fde46b4712"}, + {file = "pyobjc_framework_MetricKit-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:585a494a5126c5481afc34ac5bfdc28a1a2b7044d8b0e3427fbd5313e72c59fb"}, + {file = "pyobjc_framework_MetricKit-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b330ccffa45f4ccf2fc23c73112bf3b652515eb025fddeb3e2c81ca25f1a168"}, + {file = "pyobjc_framework_MetricKit-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fc336ff6db376bff4cab0bd7db962aae1ff11f4584026cd5c4d3f66283018ce7"}, + {file = "pyobjc_framework_MetricKit-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1403302d753686b49aa0d6fc0a4c05e6ead18aa1b9de9668322fd0e81c51f"}, + {file = "pyobjc_framework_MetricKit-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:82b01a838203000c262f9f52420b1387850505f0a7b742b29a73cc8c6a9e0c25"}, + {file = "pyobjc_framework_MetricKit-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:79971789bff04540200bd443ec3c6ae13f83eea827d2dab0f33bc9c6e6af9ab0"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-mlcompute" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MLCompute on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MLCompute-10.1.tar.gz", hash = "sha256:02e947ddb90c236acb2cb34f41838e6c78cb070886ddfb98bb71a8f02f991fd6"}, - {file = "pyobjc_framework_MLCompute-10.1-py2.py3-none-any.whl", hash = "sha256:25ed4d3002bd33c039f4ad9bf05b4830d53f67282a8399df7c65bd1430a01183"}, + {file = "pyobjc-framework-MLCompute-10.2.tar.gz", hash = "sha256:6f5bff2317b2ae45c092a94a05e7831d0dc7a002fc68b03648abbac5a2ce33a3"}, + {file = "pyobjc_framework_MLCompute-10.2-py2.py3-none-any.whl", hash = "sha256:a191abf1c6aef061b4eab1aa8d4cf886fd6c98e53f6fedcd738ddd904571b933"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-modelio" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ModelIO on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ModelIO-10.1.tar.gz", hash = "sha256:75fe5405165264a5059c16bfd492593e3becba50811a47dedbfc699ff73d4bfb"}, - {file = "pyobjc_framework_ModelIO-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6911dfa7821e1b97cf48b593d3ccd6c9f2401ed1715a677df3cdfdfeec7dad14"}, - {file = "pyobjc_framework_ModelIO-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e1a1f3b276999032ff13b1f985ae06a95b5ffc9c53771b10ea3496a70e809d58"}, - {file = "pyobjc_framework_ModelIO-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8c6d43cca1c952858b2f31cab7b9ef01daae5aa1322240895d2e965cc72230cd"}, + {file = "pyobjc-framework-ModelIO-10.2.tar.gz", hash = "sha256:8ae1444375260a346d1c77838f84e2c04dfabaf2769b2970a3588becb670431e"}, + {file = "pyobjc_framework_ModelIO-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:6d226b059a4c99669ec3dc03c1dde9b0daeba392a198cdb36398394396512a26"}, + {file = "pyobjc_framework_ModelIO-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c2fff57596d54b95507a1c180a6df877e28e561e5e71941619d70ac67d5bec4d"}, + {file = "pyobjc_framework_ModelIO-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e6b119d66cefde55ce63e406c4fd12d626fb017ee88d9e01fdd25434f6ddc831"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-multipeerconnectivity" -version = "10.1" +version = "10.2" description = "Wrappers for the framework MultipeerConnectivity on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-MultipeerConnectivity-10.1.tar.gz", hash = "sha256:ab83e57953bb3f3476c77ed863e1138ab58a0711a77a1a11924b9d22e90f116b"}, - {file = "pyobjc_framework_MultipeerConnectivity-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:e5770351b75484bbb4f6b0f0a20e0a0197a0b192a35228b087bc06f149242b0f"}, - {file = "pyobjc_framework_MultipeerConnectivity-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a06db4ee86ee85bd085659a965f1448b27bf0018f1842ae3fb6ec1c195b5352c"}, - {file = "pyobjc_framework_MultipeerConnectivity-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:becab88974b1669f5ca9c76dddb5591d4ed9acb4176980d763e22d298b6ba83d"}, + {file = "pyobjc-framework-MultipeerConnectivity-10.2.tar.gz", hash = "sha256:e3c1e5f39715621786f4ad5ecffa2cc9445a218e5ab3e94295c16fbcb754ee5a"}, + {file = "pyobjc_framework_MultipeerConnectivity-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ce68b7b5030e95e78bc94e898adb09f1e3f30c738e7140101146c52c64ff5493"}, + {file = "pyobjc_framework_MultipeerConnectivity-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f158aaaabcfd0d1e6d77585ec24797dbedf6bde640675b26dcfb4e2093d3a0ce"}, + {file = "pyobjc_framework_MultipeerConnectivity-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:0e02f9ecdbf2c4aacd5ab8cd019415584bed7fa1656d525c8f841466d6e58993"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-naturallanguage" -version = "10.1" +version = "10.2" description = "Wrappers for the framework NaturalLanguage on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-NaturalLanguage-10.1.tar.gz", hash = "sha256:b017a75d7275606f1732fef891198e916743871ca7663ddbb1ffae7d4d93a855"}, - {file = "pyobjc_framework_NaturalLanguage-10.1-py2.py3-none-any.whl", hash = "sha256:02bb4df955ecf329cf6da77ca6952777e5b2a10aee67452ea6314ec632cbc475"}, + {file = "pyobjc-framework-NaturalLanguage-10.2.tar.gz", hash = "sha256:eba7de67bea4a6a071e04e79c8a4de0547c25a09635fe3d4ee6cd58fb6aeaf65"}, + {file = "pyobjc_framework_NaturalLanguage-10.2-py2.py3-none-any.whl", hash = "sha256:0165735973a720f09bd5a2333f32e16aac52332fb595425480d7a2215472d4fb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-netfs" -version = "10.1" +version = "10.2" description = "Wrappers for the framework NetFS on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-NetFS-10.1.tar.gz", hash = "sha256:0bd9c58a0939df29729c0ab5c5fe3e7eb7fc066a15bd885ddbbbfc6d6b1524b6"}, - {file = "pyobjc_framework_NetFS-10.1-py2.py3-none-any.whl", hash = "sha256:a317c30a367af22f94858ca73cfe38a0dc4b63d0783f93532cb33780cd98a942"}, + {file = "pyobjc-framework-NetFS-10.2.tar.gz", hash = "sha256:05de46b15d19abecbb9e7d04745ca27dba9ec121f16ea7bafc9dc87a12c0e828"}, + {file = "pyobjc_framework_NetFS-10.2-py2.py3-none-any.whl", hash = "sha256:e7a84497be6114ea2e47776efda640d9d8becaaa07214d712a204b5d446e3d95"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-network" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Network on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Network-10.1.tar.gz", hash = "sha256:39c02fdcac4e487e14296f5d60458b9a0cd58c2a830591a7cfacc0bca191e03f"}, - {file = "pyobjc_framework_Network-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:5a31831cd9949efbc82bcea854ea3c22dcb5dc85072f909710cde666efd5cfb6"}, - {file = "pyobjc_framework_Network-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6704cbbf5f50d73208e7c9d92a1212f581280430da2606e07e88669120c82a36"}, - {file = "pyobjc_framework_Network-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:fe52bac9aa16429f7a138aad4cbb1e95a2be5c052c1cfda7e8c4dd16d1147dec"}, + {file = "pyobjc-framework-Network-10.2.tar.gz", hash = "sha256:b39bc26f89cf9fc56cc9c4a99099aef68c388d45b62dc1ec16772ee290b225d4"}, + {file = "pyobjc_framework_Network-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:4f465400cd4402b7495a27de4c9099bcc127afa4d1cb587f75b987750c0ea032"}, + {file = "pyobjc_framework_Network-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:39966aa35d17b00973fa85e334b6360311cfd1a097d26d79b5957bc7cd7fad4a"}, + {file = "pyobjc_framework_Network-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:5542660d0c7183dc4599bd20763ed3b59772cf17211ca3720a4175f886a8eada"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-networkextension" -version = "10.1" +version = "10.2" description = "Wrappers for the framework NetworkExtension on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-NetworkExtension-10.1.tar.gz", hash = "sha256:f49a3bd117ca40a1ea8ae751aca630f7b7e7d7305aa5dfa969beb07299eb2784"}, - {file = "pyobjc_framework_NetworkExtension-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfc5a7b402c8daced465c6b18683930a2ece91e98134cc1801657ad0a9256b1e"}, - {file = "pyobjc_framework_NetworkExtension-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dfd808295c3b68a2f225410a67645b184187848be86abc2e6ba90db27e5c470f"}, - {file = "pyobjc_framework_NetworkExtension-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a925cfdabb4d882e8b9c3524a729c3b683e7a7ca18e291509625d3e63d3840cb"}, + {file = "pyobjc-framework-NetworkExtension-10.2.tar.gz", hash = "sha256:14f237bd96a822c55374584e99f2d79581b2d60570f34e4863800f934a44b82d"}, + {file = "pyobjc_framework_NetworkExtension-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:280dc76901628b2c9750766bb2424a29de3f1f49b41e5f29634701cfe0ab0524"}, + {file = "pyobjc_framework_NetworkExtension-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ce6cfdff6f65f512137ee382ba04ee2b52e0fb51deacb651e385daf5349d28b7"}, + {file = "pyobjc_framework_NetworkExtension-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ed2cf32a802ec872466c743013ce9ef17757e89e21a49cbeeeffddfaefb89fc4"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-notificationcenter" -version = "10.1" +version = "10.2" description = "Wrappers for the framework NotificationCenter on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-NotificationCenter-10.1.tar.gz", hash = "sha256:697e29da4fdd5899e5db5bda7bdb5afc97f4a6e4d959caf2316aef3b300c5575"}, - {file = "pyobjc_framework_NotificationCenter-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9078ba52e1cfa77c797a9aed972c182acfcc79cc2eb083c7b06ba76738b5f6d"}, - {file = "pyobjc_framework_NotificationCenter-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:25bf6f521f99ccb057d0df063242d5d28223672525706317134caa887ffd6b07"}, - {file = "pyobjc_framework_NotificationCenter-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:7a6876f4b25023562ddf2558fba5e52d72a7ce3ec41c8e96533779d25e2b7722"}, + {file = "pyobjc-framework-NotificationCenter-10.2.tar.gz", hash = "sha256:3771c7a8b8e839d07c7cb51eef2e83666254bdd88bd873b0ba7e385245cda684"}, + {file = "pyobjc_framework_NotificationCenter-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f982ce1d0916f9ba3322ebbffd9b936b5b9aeb6d8ec21bd2c3c5245c467c1a12"}, + {file = "pyobjc_framework_NotificationCenter-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:dd1d8364d2212a671b2224ab6bf7785ba5b2aae46610ec46ae35d27c4d55cb15"}, + {file = "pyobjc_framework_NotificationCenter-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:1e8aaaef40b6c0deaffd979b3741d1f9de7d804995b7b92fa88ba7839615230e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-opendirectory" -version = "10.1" +version = "10.2" description = "Wrappers for the framework OpenDirectory on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-OpenDirectory-10.1.tar.gz", hash = "sha256:5d25c254876378966ce58e0de9e3d3594ca25922773d6526235b5e2f2c4103e1"}, - {file = "pyobjc_framework_OpenDirectory-10.1-py2.py3-none-any.whl", hash = "sha256:83601f3b5694b1087616566019c300aa38b2a15b59d215e96c5dae18430e8c96"}, + {file = "pyobjc-framework-OpenDirectory-10.2.tar.gz", hash = "sha256:ecca3346275e1ee7be812e428da7f243e37258d8152708a2baa246001b7f5996"}, + {file = "pyobjc_framework_OpenDirectory-10.2-py2.py3-none-any.whl", hash = "sha256:7996985a746f4cceee72233eb5671983e9ee9c9bce3fa9c2fd03d65e766a4efd"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-osakit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework OSAKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-OSAKit-10.1.tar.gz", hash = "sha256:59ad344fed2ddbc24c5dad3345f596cd6ecb73e4c97a05051e3680709f66a42f"}, - {file = "pyobjc_framework_OSAKit-10.1-py2.py3-none-any.whl", hash = "sha256:af34b4dccc17a772d80c283c9356bdb5a5a300bd54c2557c26671aca4f2f86cb"}, + {file = "pyobjc-framework-OSAKit-10.2.tar.gz", hash = "sha256:6efba4a1733e9ab0bf0e7b4f2eb3e0c84b2a4af1b0b4bbc3a310ae041ccaf92d"}, + {file = "pyobjc_framework_OSAKit-10.2-py2.py3-none-any.whl", hash = "sha256:fbad23e47e31d795a005c18a20d84bff68d90d6dd0f87b6a343e46f87c00034a"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-oslog" -version = "10.1" +version = "10.2" description = "Wrappers for the framework OSLog on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-OSLog-10.1.tar.gz", hash = "sha256:bfce0067351115ae273489768f93692dcda88bd5b54f28bb741c08855c114dfe"}, - {file = "pyobjc_framework_OSLog-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:57b2920c5c9393fb4fe9e1d5d87eabead32ebe821853d06d577bdb5503327a49"}, - {file = "pyobjc_framework_OSLog-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e94a3ce153fe72f7fe463e468d94e3657db54b133aaf5a313fb31b6b52ed60f2"}, - {file = "pyobjc_framework_OSLog-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:09e64565e4a293f3a9d486e1376f2c9651d5cec500b2c2245de9ae0baecfb29e"}, + {file = "pyobjc-framework-OSLog-10.2.tar.gz", hash = "sha256:2377637a0de7dd60f610caab4bcd7efa165d23dba4ac896fd542f1fab2fc588a"}, + {file = "pyobjc_framework_OSLog-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ef1ddc15f98243be9b03f4f4bcb839318333fb135842085ba40499a58c8bd342"}, + {file = "pyobjc_framework_OSLog-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7958957503310ec8df90a0a036ae8a075b90610c0b797769ad117bf635b0caa6"}, + {file = "pyobjc_framework_OSLog-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:67796f02b77c1cc893b3f112f88c58714b1e16a38b59bc52748c25798db71c29"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreMedia = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-passkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PassKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PassKit-10.1.tar.gz", hash = "sha256:bc19a46fad004137f207a5a9643d3f9a3602ea3f1d75c57841de986019a3c805"}, - {file = "pyobjc_framework_PassKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:011e2f32bc465b634d171a2500e6a153b479b807a50659cc164883bbeec74e59"}, - {file = "pyobjc_framework_PassKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:791f7d4317164130e8232e75e40ba565633a01bc5777dc3d0ba0a8b5f4aeab92"}, - {file = "pyobjc_framework_PassKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:58115c31a2e8b8a57ca048de408444cc4ba94da386656e0eeeac919b157f03a4"}, + {file = "pyobjc-framework-PassKit-10.2.tar.gz", hash = "sha256:0c879d632f0f0bf586161a7abbbba3dad9ba9894a3edbce06f4160491c2c134c"}, + {file = "pyobjc_framework_PassKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:15891c8c1e23081961d652946d4750fd3cd1308efc953a1c77713394726798a6"}, + {file = "pyobjc_framework_PassKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d68061729743be30c66f7eb3cb649850ef12a24b1d1896233036a390e7d69aa7"}, + {file = "pyobjc_framework_PassKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:7290369b34be3317463a32c9e78a0ed734db4793414851a9e73295413cf17317"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-pencilkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PencilKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PencilKit-10.1.tar.gz", hash = "sha256:712654dc9373014aa5472b10ba269d95f455c722ebb7504caa04dfae209ed63a"}, - {file = "pyobjc_framework_PencilKit-10.1-py2.py3-none-any.whl", hash = "sha256:baf856d274653d74d66099ae81005ddb3923f7128d36d2f87100481cbb8b2b27"}, + {file = "pyobjc-framework-PencilKit-10.2.tar.gz", hash = "sha256:2338ea384b9a9e67a7f34c300a898ccb997bcff9a2a27e5f9bf7642760c016a0"}, + {file = "pyobjc_framework_PencilKit-10.2-py2.py3-none-any.whl", hash = "sha256:d3e605f104548f26c708957ab7939a64147c422c35d45c4ff4c8d01b5c248c4d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-phase" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PHASE on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PHASE-10.1.tar.gz", hash = "sha256:b7e0ef3567359a4f8ab3e5f8319f2201e775e3db6d7498409701664568c8c7c6"}, - {file = "pyobjc_framework_PHASE-10.1-py2.py3-none-any.whl", hash = "sha256:329cd6dd040a7ef8091dda9d8e57d9613bc9c8edf3cfd3af549f5cd9d64a0941"}, + {file = "pyobjc-framework-PHASE-10.2.tar.gz", hash = "sha256:047ba5b7a869ed93c3c7af2cf7e3ffc83299038275d47c8229e7c09006785402"}, + {file = "pyobjc_framework_PHASE-10.2-py2.py3-none-any.whl", hash = "sha256:f29cd40e5be860758d8444e761d43f313915e2750b8b03b8a080dd86260f6f91"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-AVFoundation = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-AVFoundation = ">=10.2" [[package]] name = "pyobjc-framework-photos" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Photos on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Photos-10.1.tar.gz", hash = "sha256:eb0e83d01c8eb0652fac8382e68fd9643b7530f6580c2a51846444cae09ec094"}, - {file = "pyobjc_framework_Photos-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:d91ead1ec33e05bf9e42b7df3f8fe7e3d4cf2814482f6878060c259453491d65"}, - {file = "pyobjc_framework_Photos-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:f8415346689213b30488eb023d699c0512fcddeb7e1e4aa833860c312dddf780"}, - {file = "pyobjc_framework_Photos-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:61174248e07025d4696b6164346b43147250d03ae8378f70a458c0583e003656"}, + {file = "pyobjc-framework-Photos-10.2.tar.gz", hash = "sha256:ba05d1208158e6de6d14782c182991c0d157254be7254b8d3bb0a9a53bf113fb"}, + {file = "pyobjc_framework_Photos-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:4f2c2aa73f3ac331a84ee1f7b5e0edc26471776b2de2190640f041e3c1cc8ef3"}, + {file = "pyobjc_framework_Photos-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:17d69ce116a7f7db1d78ed12a8a81bec1b580735ad40611c0037d8c2977b2eb8"}, + {file = "pyobjc_framework_Photos-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e53d0759c26c7eac4ebfc7bd0018dfd7e3be8ab88a042684ee45e9184e0ac90e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-photosui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PhotosUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PhotosUI-10.1.tar.gz", hash = "sha256:4b90755c6c62a0668782cf05d92fca6277485f2cb3473981760c0dc0e40de1d8"}, - {file = "pyobjc_framework_PhotosUI-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:206641f2f7f3169fecc0014b9b93c89b5503841014e911d4686684de137c79f9"}, - {file = "pyobjc_framework_PhotosUI-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:02c1861bcce433294b00f6c614559addc87fcf57aaa1ede2b6dfea50a3795378"}, - {file = "pyobjc_framework_PhotosUI-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:8df716fb2e9994bfc2d716d6930defb3e3911a0337788ef36eea0c2eb0f899ad"}, + {file = "pyobjc-framework-PhotosUI-10.2.tar.gz", hash = "sha256:d0bbcae82b4cc652bb60d3221c557cc19be62ff430575ec8e6d233beb936f73b"}, + {file = "pyobjc_framework_PhotosUI-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a27607419652b45053e0be5ede2780b48e6a8dded2b365ded1732e80dafacea0"}, + {file = "pyobjc_framework_PhotosUI-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7eddf0343fae6c327a3dc941d0d7b216f5d186edb2e511d7c54668f6ff2be701"}, + {file = "pyobjc_framework_PhotosUI-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:d6715ac72c7967761c33502f6cd552534ec0f727f009f22a2c273dc12076d52d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-preferencepanes" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PreferencePanes on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PreferencePanes-10.1.tar.gz", hash = "sha256:3a26cd8959dac30203410eb432a361caf2a0b8552c74edd3d7406d722ecc1014"}, - {file = "pyobjc_framework_PreferencePanes-10.1-py2.py3-none-any.whl", hash = "sha256:9b16c93d7f684cbe097932c8260a0b6460ad9fc68230648981340b7e3ee7053e"}, + {file = "pyobjc-framework-PreferencePanes-10.2.tar.gz", hash = "sha256:f1fba8727d172a3e9b58d764695702f7752dfb585d0378e588915f3d8363728c"}, + {file = "pyobjc_framework_PreferencePanes-10.2-py2.py3-none-any.whl", hash = "sha256:4da63d42bc2f2de547b6c817236e902ad6155efa05e5305daa38be830b70a19d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-pubsub" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PubSub on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PubSub-10.1.tar.gz", hash = "sha256:7992344ae82d9566d300b3d2c92ff9fa9a28e060bd42d0988df351f5fb729156"}, - {file = "pyobjc_framework_PubSub-10.1-py2.py3-none-any.whl", hash = "sha256:af0b1ed0328f06d7d96390a4b95bfb4a790d5b38142825a222923f908dc46db9"}, + {file = "pyobjc-framework-PubSub-10.2.tar.gz", hash = "sha256:68ca9701b29c5e87f7837490cad3dab0b6cd539dfaff3ffe84b1f3f1bf4dc764"}, + {file = "pyobjc_framework_PubSub-10.2-py2.py3-none-any.whl", hash = "sha256:b44f7f87de3f92ce9655344c476672f8f7a912f86ab7a615fec30cebbe7a8827"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-pushkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework PushKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-PushKit-10.1.tar.gz", hash = "sha256:12798ad9ae87f7e78690d2bce2ea46f0714d30dd938f5b288717660120a00795"}, - {file = "pyobjc_framework_PushKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:99edcd057d5cc7e015fe6b464b83f07c843fba878f5b0636ff30cd6377ec2915"}, - {file = "pyobjc_framework_PushKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:986216b9021ed6aff3a528c2b6a3885426e8acac9a744397ede998d2e7a83d06"}, - {file = "pyobjc_framework_PushKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:cf27a49a3b9eadde0bc518b54f7b38fd5d0e1c2203350d1286527b6177afa3c3"}, + {file = "pyobjc-framework-PushKit-10.2.tar.gz", hash = "sha256:e30fc4926a9fcd3427701e48a8908f72e546720e52b1e0f457ba2fa017974917"}, + {file = "pyobjc_framework_PushKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:1015e4473a8eac7eba09902807b8d8edd47c536e3a50a0b3fe7ab7211e454ad8"}, + {file = "pyobjc_framework_PushKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6f68b2630f84dc6d94046f7676d415e5342b2bb3f0368f3b9e81d0c5744c219b"}, + {file = "pyobjc_framework_PushKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:5fe75738ea08c05e42460a58acbf0a8af67a3df26ca2a7bddd48d801b00772ed"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-quartz" -version = "10.1" +version = "10.2" description = "Wrappers for the Quartz frameworks on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Quartz-10.1.tar.gz", hash = "sha256:b7439c0a3be9590d261cd2d340ba8dd24a75877b0be3ebce56e022a19cc05738"}, - {file = "pyobjc_framework_Quartz-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:69db14ac9814839471e3cf5a8d81fb5edd1b762739ad806d3cf244836dac0154"}, - {file = "pyobjc_framework_Quartz-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ddcd18e96511e618ce43e288a043e25524c131f5e6d58775db7aaf15553d849"}, - {file = "pyobjc_framework_Quartz-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c4257a2fb5580e5ebe927a66cf36a11749685a4681a30f90e954a3f08894cb62"}, - {file = "pyobjc_framework_Quartz-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28315ca6e04a08ae9e4eaf35b364ee77e081605d5865021018217626097c5e80"}, - {file = "pyobjc_framework_Quartz-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9cb859a2fd7e15f2de85c16b028148dea06002d1a4142922b3441d3802fab372"}, - {file = "pyobjc_framework_Quartz-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:993c71009e6374e57205e6aeaa577b7af2df245a5d1d2feff0f88ca0fa7b8626"}, + {file = "pyobjc-framework-Quartz-10.2.tar.gz", hash = "sha256:9b947e081f5bd6cd01c99ab5d62c36500d2d6e8d3b87421c1cbb7f9c885555eb"}, + {file = "pyobjc_framework_Quartz-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bc0ab739259a717d9d13a739434991b54eb8963ad7c27f9f6d04d68531fb479b"}, + {file = "pyobjc_framework_Quartz-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a74d00e933c1e1a1820839323dc5cf252bee8bb98e2a298d961f7ae7905ce71"}, + {file = "pyobjc_framework_Quartz-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3e8e33246d966c2bd7f5ee2cf3b431582fa434a6ec2b6dbe580045ebf1f55be5"}, + {file = "pyobjc_framework_Quartz-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c6ca490eff1be0dd8dc7726edde79c97e21ec1afcf55f75962a79e27b4eb2961"}, + {file = "pyobjc_framework_Quartz-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d3d54d9fa50de09ee8994248151def58f30b4738eb20755b0bdd5ee1e1f5883d"}, + {file = "pyobjc_framework_Quartz-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:520c8031b2389110f80070b078dde1968caaecb10921f8070046c26132ac9286"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-quicklookthumbnailing" -version = "10.1" +version = "10.2" description = "Wrappers for the framework QuickLookThumbnailing on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-QuickLookThumbnailing-10.1.tar.gz", hash = "sha256:b6c4ea3701cb18abaffcceb65adc9dcfd6bb28811af7a99148c71e71d538a3a6"}, - {file = "pyobjc_framework_QuickLookThumbnailing-10.1-py2.py3-none-any.whl", hash = "sha256:984e4e92727caa5b2ebbe8c91fcde6acc416f15dd8e7aef94cb3999c4a7028ec"}, + {file = "pyobjc-framework-QuickLookThumbnailing-10.2.tar.gz", hash = "sha256:91497a4dc601c99ccc11ad7976ff729b57f724d9eff071bc24c519940d129dca"}, + {file = "pyobjc_framework_QuickLookThumbnailing-10.2-py2.py3-none-any.whl", hash = "sha256:34349ff0b07b39ecfe5757eb80341a45f9d4426558b93946225f8b4fa2781c4c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-replaykit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ReplayKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ReplayKit-10.1.tar.gz", hash = "sha256:c74d092afd8da7448e3b96a28d9cde09ad11269b345a5df21ce971c87671e421"}, - {file = "pyobjc_framework_ReplayKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:592cd22d78a92691d3dce98cd526e95fbb692142541a62c99d989c8941ec9f55"}, - {file = "pyobjc_framework_ReplayKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:05358af8daef82de6fa40fb5e04639d0f29d3f22f34b0901d5a224f8d2a7da69"}, - {file = "pyobjc_framework_ReplayKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:771af451363b7c81c920a1290f673501762da6f691f54920d0866028098390dd"}, + {file = "pyobjc-framework-ReplayKit-10.2.tar.gz", hash = "sha256:12544028e59ef25ea5c96ebd451cee70d1833d6b5991d3a1b324c6d81ecfb49e"}, + {file = "pyobjc_framework_ReplayKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e34b006879ed2e86df044e3dd36482d78e6297c954aeda29f60f4b9006c8114"}, + {file = "pyobjc_framework_ReplayKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:a6e7ae17d41a381d379d10bd240e1681fc83664b89495999a4dd8d0f42d4b542"}, + {file = "pyobjc_framework_ReplayKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:3c57b4019563aaae3c37a250d6c064cbcb5c0d3b227b5b4f1e18bf4a1effcf0e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-safariservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SafariServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SafariServices-10.1.tar.gz", hash = "sha256:5a9105d3aea43cd214583acd06609f56ed704ce816cb103916324e8ed8388fce"}, - {file = "pyobjc_framework_SafariServices-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f672434748e7d9b303535969bcb03d99cdbf79162292ad439c0347455f38f1db"}, - {file = "pyobjc_framework_SafariServices-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:64d37455a8bd541bd799604ee9e41120cc7c9c19f26776b6d8e16f1902738b70"}, - {file = "pyobjc_framework_SafariServices-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a5aa2fb6333ec0929f6b9689992b76eb6442e5ef4bad8b5a72c7796f24898868"}, + {file = "pyobjc-framework-SafariServices-10.2.tar.gz", hash = "sha256:723de09afb718b05d03cbbed42f90d36356294b038ca6422c88d50240047b067"}, + {file = "pyobjc_framework_SafariServices-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:2cd4b4210bd3c05d74d41e5bf2760e841289927601184f0e6ca3ef85019aa5dd"}, + {file = "pyobjc_framework_SafariServices-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6c8aa0becaa7d4ce0d0d1ada4e14e1eae2bf8e5be7ef49cc1861a41d3a4eeade"}, + {file = "pyobjc_framework_SafariServices-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:aecc109b096b3e995b896bfb97c09ef156600788e2a46c498bb4e2e355faa2bc"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-safetykit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SafetyKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SafetyKit-10.1.tar.gz", hash = "sha256:f1ac7201d32129c9c1a200724a5d3e75c6da8793f9c8a628be206cdebcd548e5"}, - {file = "pyobjc_framework_SafetyKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:3499fd9d85c8c93ae7be2949c1b2e91e0f74b9a0d39be9c66440c40195ef4633"}, - {file = "pyobjc_framework_SafetyKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ab7d47dbcdeafb56f0c2c6e1be847e74840038c19fecbbaf883e68cd44511eb9"}, - {file = "pyobjc_framework_SafetyKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:5c68ab2994c21bd32540595ec92922b0234e48fbb6998fcb22bacee46286e999"}, + {file = "pyobjc-framework-SafetyKit-10.2.tar.gz", hash = "sha256:b5822cda3b1dc0209fa58027551fa17457763275902c7d42fc23d5b13de9ee67"}, + {file = "pyobjc_framework_SafetyKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:947d42faf40b4ddd71bce75b8b913b7b67e0640fffa508562f4e502ca99426d4"}, + {file = "pyobjc_framework_SafetyKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65feaff614eeacceb8c405030ddd79f8eda2366d2a73f44ea595f48f7969bcf0"}, + {file = "pyobjc_framework_SafetyKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a6c3201dfb649523fa2f7569ca1274d1322527e210ee19d7c2395d0e3d18e0a2"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-scenekit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SceneKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SceneKit-10.1.tar.gz", hash = "sha256:f6565f3dba3bacf6099677ef713f9c95bcb9d8c4ea755c1866d113f95f110fc9"}, - {file = "pyobjc_framework_SceneKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:70d3a7f78238255bf62fab33a3e9ac20e13ec228eafd1aa0ef579b3792e5d9b9"}, - {file = "pyobjc_framework_SceneKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1bbdee819b638530c53271a4f302357cf8c829dbfc6e40b062335c900816bb01"}, - {file = "pyobjc_framework_SceneKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e179e37613814661be86c8316dd92497012cec48bb4febdc3d432ac5e7594a3f"}, + {file = "pyobjc-framework-SceneKit-10.2.tar.gz", hash = "sha256:53d2ffac43684bb7834ae570d3537bd15f2a7711b77cc9e8b7b81f63a697ba03"}, + {file = "pyobjc_framework_SceneKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac80bf8c4cf957add63a0bd2f1811097fb62eafb4fc26192f4087cd7853e85fd"}, + {file = "pyobjc_framework_SceneKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:86c3d23b63b0bb4d8fea370cb08aac778bc3fdb64b639b8b9ea87dacc54fd1cf"}, + {file = "pyobjc_framework_SceneKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:00676f4e11f3069545b07357e51781054ecf4785ed24ea8747515e018db1618c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-screencapturekit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ScreenCaptureKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ScreenCaptureKit-10.1.tar.gz", hash = "sha256:a00d85c97bf0cdd454d57181c371f372b8549c4edd949e2b66f42782f426f855"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bc05248b9ae9ed4aa474b4e54927216046c284a4c6c27d30db9df659887b7b1d"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:98eaec608bd9858a265541b14d6708bcc0b8c8276c2a5b41b80d828c0c2a8c64"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ff8657865f6280a942d175b87933ff0f1b6064e672a7f1efb5e66d864b435c27"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:30615c2a9f0a04cca41afe0cee21e3179f72f055e9cac94fe1e4f31fcccb0919"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:2cbd9957e9823615a494b2fd6815688eb0ad2eed7df007b25e3f7d83261653a9"}, - {file = "pyobjc_framework_ScreenCaptureKit-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a3b732bad05c973844ea3b25ccabf0d41b4c3eec4f7b5d78650337685cb43142"}, + {file = "pyobjc-framework-ScreenCaptureKit-10.2.tar.gz", hash = "sha256:86f64377be94db1b95e77ca53301ed94c0a7a82c0251c9e960bcae24b6a5841b"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e15b0af8a1155b7bc975ccd54192c5feae2706a8e17da6effa4273a3302d4dce"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bdcc687d022b8b6264dca74c1f72897c91528b0c701d76f1466faeead8030a11"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f53caee8edca7868449f2cce60574cedea4299c324fa692c944824a627b7b8a4"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4cdd6add328e2318550df325210c83d1de68774a634d3914da2bfbd1cb7d929f"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:e51c6c632b1c6ff773cfcf7d3e2b349693e06d52259b8c8485cfaa6c6cd602b3"}, + {file = "pyobjc_framework_ScreenCaptureKit-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b63d9dc8635e7a3e59163a4abc13a9014de702729a55d290a22518702f4679fc"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreMedia = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" [[package]] name = "pyobjc-framework-screensaver" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ScreenSaver on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ScreenSaver-10.1.tar.gz", hash = "sha256:d1b890c7cae9e5c43582fe834aebcb6a1ecf52467a8ed7a28ba9d873bbf582d5"}, - {file = "pyobjc_framework_ScreenSaver-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b464de6398ef3a700c4ac19ed92b25cf2d30900b574533a659967446fddede3b"}, - {file = "pyobjc_framework_ScreenSaver-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:cc8f81b2073920ca84d8e83435b95731e798ad422e0a3d67b09feb208a3920c6"}, - {file = "pyobjc_framework_ScreenSaver-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:96868cd9dc6613144821bb4db50ca68efa3ae8e07c31a626ce02d78b4eeaaeff"}, + {file = "pyobjc-framework-ScreenSaver-10.2.tar.gz", hash = "sha256:00c6a312467abb516fd2f19e3166c4609eed939edc0f2c888ccd8c9f0fdd30f1"}, + {file = "pyobjc_framework_ScreenSaver-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:830b2fc85ff7d48824eb6f12100915c2aa480a1a408b53c30f6b81906dc8b1ea"}, + {file = "pyobjc_framework_ScreenSaver-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1cb8a31bd2a0597727553d0459c91803bf02c52ffb5ac94aa5ad484ddc46d88d"}, + {file = "pyobjc_framework_ScreenSaver-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ca00a5c4cd89450e629962bfafe6a4a25b7bae93eb3fdd3ecb314c6c5755cbcf"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-screentime" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ScreenTime on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ScreenTime-10.1.tar.gz", hash = "sha256:6221e0f5122042b280212a6555f72d94020c2fd62319c4562cdfc7b58960dd07"}, - {file = "pyobjc_framework_ScreenTime-10.1-py2.py3-none-any.whl", hash = "sha256:734e090debb954a890a564869f2af20b55b9f7b7875d360795c9875279d09bd9"}, + {file = "pyobjc-framework-ScreenTime-10.2.tar.gz", hash = "sha256:fd516f0dd7c16f15ab6ed3eeb8180460136f72b7eaa3d6e849d4a462438bfdf2"}, + {file = "pyobjc_framework_ScreenTime-10.2-py2.py3-none-any.whl", hash = "sha256:43afabfd0fd61eed91f11aba3de95091a4f05d7c7e63341f493026e5ff7b90e4"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-scriptingbridge" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ScriptingBridge on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ScriptingBridge-10.1.tar.gz", hash = "sha256:7dce35a25d1f3b125e4b68a07c7f9eaa33fc9f00dde32356d0f7f73eb09429a3"}, - {file = "pyobjc_framework_ScriptingBridge-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:15e60d3783d7611f4d35e6b2905921a01162cfa04eb1a6426135585c84806d19"}, - {file = "pyobjc_framework_ScriptingBridge-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:30c0aac8623d0e96442801219004c32d527d4b4bbbf5c271517d73c5eeae85a3"}, - {file = "pyobjc_framework_ScriptingBridge-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:ca0dc8ccb443f5a3ab9afb500d6c730723faf38c5880a243a65b4e44be64fa55"}, + {file = "pyobjc-framework-ScriptingBridge-10.2.tar.gz", hash = "sha256:c02d88b4a4d48d54ce2260f5c7e1757e74cd91281352cdd32492a4c7ee4b0e7c"}, + {file = "pyobjc_framework_ScriptingBridge-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:466ad2d483edadf97dc38629c393902a790141547e145e83f6bd34351d10f4c9"}, + {file = "pyobjc_framework_ScriptingBridge-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1e3e0c19afd0f8189ebee5c57ab2b0c177dddccc9b56811c665ec6848007ac6a"}, + {file = "pyobjc_framework_ScriptingBridge-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:560dff883edd251f1e0bf86dde681c1e19845399720fd2434734c91120eafdd0"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-searchkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SearchKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SearchKit-10.1.tar.gz", hash = "sha256:75234ee6e8490cf792453bf9a9854d7b5f1cebd65e81903d5ce0ecc3e65fc277"}, - {file = "pyobjc_framework_SearchKit-10.1-py2.py3-none-any.whl", hash = "sha256:2e42e7cacb0a7f9b327d1c770e52fe13dfaaac377cb4e413b609e478993552e0"}, + {file = "pyobjc-framework-SearchKit-10.2.tar.gz", hash = "sha256:c1e16457e727c5282b620d20b2d764352947cd4509966475a874f2750a9c5d11"}, + {file = "pyobjc_framework_SearchKit-10.2-py2.py3-none-any.whl", hash = "sha256:ddd9e2f207ae578f04ec2358fdf485f26978d6de4909640b58486a8a9e4e639c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-CoreServices = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-CoreServices = ">=10.2" [[package]] name = "pyobjc-framework-security" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Security on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Security-10.1.tar.gz", hash = "sha256:33becccea5488a4044792034d8cf4faf1913f8ca9ba912dceeaa54db311bd284"}, - {file = "pyobjc_framework_Security-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:72955f4faf503e6a41076fcaa3ec138eb1cc794f483db77104acf2ee480f8a04"}, - {file = "pyobjc_framework_Security-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b02075026d78feda8c1af9462199c2cde65b87e4adde65b90ca6965f06cb422"}, - {file = "pyobjc_framework_Security-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1d19785d8531a6cdcdbb4c545b560f63306ff947592e7fad27811f87ee64854c"}, - {file = "pyobjc_framework_Security-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:569a9243d4044e3e433335ded891dc357880787df647de8220659f022a03f467"}, - {file = "pyobjc_framework_Security-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d8b8c402c395ac3868727f04e98b2ded675534de1349df8f5813b3c483b50a2c"}, - {file = "pyobjc_framework_Security-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:aaca360a28b6333a8a93b091426daa5ffd22006bbb1122d3d6a78d33177f612a"}, + {file = "pyobjc-framework-Security-10.2.tar.gz", hash = "sha256:20ec8ebb41506037d54b40606590b90f66a89adceeddd9a40674b0c7ea7c8c82"}, + {file = "pyobjc_framework_Security-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5a9c1bf88db62ebe1186dbecb40c6fdf8dab2d614012b5da8e9b90ee3bd8575e"}, + {file = "pyobjc_framework_Security-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9119f8bad7bead85e5b57c8538d319ef19eb5159500a0e3677c11ddbb774a17a"}, + {file = "pyobjc_framework_Security-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:317add1dcbc6866ce2e9389ef5a2a46db82e042aca6e5fad9aa5ce17782493fe"}, + {file = "pyobjc_framework_Security-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:75f061f0d03c3099d01b7818409eb602b882f6a31b4381bbf289f10ce1cf7753"}, + {file = "pyobjc_framework_Security-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d99aeba0e3a7ee95bf5582b06885a5d6f8115ff3a2e47506562514117022f170"}, + {file = "pyobjc_framework_Security-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:186a97497209acdb8d56aa7bbd56ab8021663fff2fb83f0d0e1b4e1f57ac5bbb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-securityfoundation" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SecurityFoundation on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SecurityFoundation-10.1.tar.gz", hash = "sha256:11def85a7a4ea490fa24df79d01ea137f378534fedf1da248068ddf137f38c7e"}, - {file = "pyobjc_framework_SecurityFoundation-10.1-py2.py3-none-any.whl", hash = "sha256:bbd67737afec25f2e3d41c8c2e7b4a6f9aae4231242e215b82a950eef6432ce0"}, + {file = "pyobjc-framework-SecurityFoundation-10.2.tar.gz", hash = "sha256:ed612afab0f70e24b29f2e2b3a31cfefb1ad17244b5c147e7bcad8dfc7e60bd1"}, + {file = "pyobjc_framework_SecurityFoundation-10.2-py2.py3-none-any.whl", hash = "sha256:296f7f9ff96a35c19e4aef7621a567c0efe584aafd20ac25a2839dd96bf46a04"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Security = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Security = ">=10.2" [[package]] name = "pyobjc-framework-securityinterface" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SecurityInterface on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SecurityInterface-10.1.tar.gz", hash = "sha256:444a0dc7d50390750c28185b6496ee913011ac886d9e634bfc9a0856372d0a94"}, - {file = "pyobjc_framework_SecurityInterface-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c0e52408e25845a960b0fe339c274650fd211f9fee5944c643d9ba16861e45ac"}, - {file = "pyobjc_framework_SecurityInterface-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:bef4a63d31808531f5806006945d1f9b5650221e4adc973302387ab7b2e1b349"}, - {file = "pyobjc_framework_SecurityInterface-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:479e555df16ff7f79bf7622ab3341b0ef176fbd85ef3f7301931a57d2def682f"}, + {file = "pyobjc-framework-SecurityInterface-10.2.tar.gz", hash = "sha256:43930539fed05e74f3c692f5ee7848681e7e65c44387af300447514fe8e23ab6"}, + {file = "pyobjc_framework_SecurityInterface-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:70f2cb61261e84fb366f43a9a44fb19a19188cf650d3cf3f3e6ee3a16a73e62d"}, + {file = "pyobjc_framework_SecurityInterface-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:52a18a18af6d47f7fbdfeef898a038ff3ab7537a694c591ddcf8f895b9e55cce"}, + {file = "pyobjc_framework_SecurityInterface-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b2472e3714cc17b22e5bb0173887aac77c80ccc2188ec2c40d2b906bd2490f6b"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Security = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Security = ">=10.2" [[package]] name = "pyobjc-framework-sensitivecontentanalysis" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SensitiveContentAnalysis on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SensitiveContentAnalysis-10.1.tar.gz", hash = "sha256:435906a3fcc6cba50cd7c5bfd693368c6042c17c5f64bcd560a3761d947425de"}, - {file = "pyobjc_framework_SensitiveContentAnalysis-10.1-py2.py3-none-any.whl", hash = "sha256:472c0fb0f1ad9c370cbc7cf636bb5888cbcf0ee8c9ecb9c5f6de25e2587771e5"}, + {file = "pyobjc-framework-SensitiveContentAnalysis-10.2.tar.gz", hash = "sha256:ef111cb8a85bc86e47954cdb01e3ccb654aba64a3d855f17a0c786361859aef8"}, + {file = "pyobjc_framework_SensitiveContentAnalysis-10.2-py2.py3-none-any.whl", hash = "sha256:3c875856837e217c9eba68e5c2b4f5b862dee1bb64513b463a7af8c3e67e5a50"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-servicemanagement" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ServiceManagement on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ServiceManagement-10.1.tar.gz", hash = "sha256:ebe38b80ed74112fdd356e19165c365f6281baad83818774a0da6d790fd13044"}, - {file = "pyobjc_framework_ServiceManagement-10.1-py2.py3-none-any.whl", hash = "sha256:d05289948558cf4c7fbc101946f6ccadcc33826b2056c14d5494a8ae7f136936"}, + {file = "pyobjc-framework-ServiceManagement-10.2.tar.gz", hash = "sha256:62413cd911932cc16262710a3853061fdae341ed95e1aa0426b4ff0011d18c0c"}, + {file = "pyobjc_framework_ServiceManagement-10.2-py2.py3-none-any.whl", hash = "sha256:e5a1c1746788d0e125cc87cbe0749b2b824fb7a08bc4344c06c9ac6007859187"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-sharedwithyou" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SharedWithYou on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SharedWithYou-10.1.tar.gz", hash = "sha256:bcac8ffa2642589a416c62ff436148586db9c41f92419a0164b1e9d6f6c73e38"}, - {file = "pyobjc_framework_SharedWithYou-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:05fceedcd7b6e8753cb8dc5f09a947686dd454c304965c959bc101cfd7349fcd"}, - {file = "pyobjc_framework_SharedWithYou-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6f4f9fb6d335b54eb0a02b277ca8a2cb87962a579bafdc9df5f94c8af1063ee4"}, - {file = "pyobjc_framework_SharedWithYou-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:a1c7c688c15117f1c6ea638e83285ce1b2fbd9d8c76ee405e43b24fa4fea766d"}, + {file = "pyobjc-framework-SharedWithYou-10.2.tar.gz", hash = "sha256:bc13756ef20af488cd3022c036a11a0f7572e1b286e9eb7d31c61a8cb7655c70"}, + {file = "pyobjc_framework_SharedWithYou-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:b69169db01c78bef3178b8795fb5e2a9eccfa4c26b7de008e23a5aa6f0c709f0"}, + {file = "pyobjc_framework_SharedWithYou-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e4ec724f103b0904893212d473c68c462f8fbe46a470b0c9f88cb8330969a94e"}, + {file = "pyobjc_framework_SharedWithYou-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:04b477d42a6edd25c187fc61422ce62156fd5d8670b7007ff3f1a10723b1b4b8"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-SharedWithYouCore = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-SharedWithYouCore = ">=10.2" [[package]] name = "pyobjc-framework-sharedwithyoucore" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SharedWithYouCore on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SharedWithYouCore-10.1.tar.gz", hash = "sha256:2b4f62b0df4bd44198f6d3a3aae4d054592261d36fc2af71f9dd81744aa99815"}, - {file = "pyobjc_framework_SharedWithYouCore-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a7f41415a3ca40d4ee18955155a4141e0d2d55e713b513aa567305ae54716cb7"}, - {file = "pyobjc_framework_SharedWithYouCore-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc133f07a71cb828073dc671cb1e8ffa5bde714b376a8eba0a8110ac41927ae9"}, - {file = "pyobjc_framework_SharedWithYouCore-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:d7169a2492ed4fd7d45ad0eafbecebffec0b22f08e756f2e251eda62cd5ba42a"}, + {file = "pyobjc-framework-SharedWithYouCore-10.2.tar.gz", hash = "sha256:cc8faa9f549f6c931be33cf99f49b8cde11db52cb542e3797c3a27f98e5e9a2a"}, + {file = "pyobjc_framework_SharedWithYouCore-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:275b50a6b9205b1c0a08632c2ede98293b26df28d6c35bc34714ec9d5a7065d6"}, + {file = "pyobjc_framework_SharedWithYouCore-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:55aaac1bea38e566e70084cbe348b2af0f5cda782c8da54c6bbbd70345a50b27"}, + {file = "pyobjc_framework_SharedWithYouCore-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b118ba79e7bb2fab26369927316b90aa952795976a29e7dc49dcb47a87f7924c"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-shazamkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ShazamKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ShazamKit-10.1.tar.gz", hash = "sha256:d091c5104adda8d54e65463862550e59f86646fdafcdcd234c9a7a2624584f1d"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6670ed380dacc6aa86f571a18d9e321bd075da11bf144cba2802b19bb0868a21"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d4efd57dac3f50621cc23be38cefbd6c80b4b55f0339312b4f2a340cd6ffde9b"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:07e58fc6b70bf961f230044cf46324ab4239864955299957e231ba7cda8fafa9"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be2da82d9a58c2605a1a17a88fbc389931b8fd8ad7d60926755b50316fe5e04f"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:e500c6794f2b7cea57dea6f64c1fc9e067a14ddb9446e9d7739dcb57683b5a8a"}, - {file = "pyobjc_framework_ShazamKit-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4289a1109148a1a314c6bae9b33e90eca6d18a06a767b431cdff1178024f3310"}, + {file = "pyobjc-framework-ShazamKit-10.2.tar.gz", hash = "sha256:f3359be7a0ffe0084d047b8813dd9e9b5339a0970baecad89cbe85513e838e74"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a33d2ad28cc7731e67906eccf324c441383ba741399c88e993b5375e734509ba"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:13976c21722389e81d9e10ab419dfb0904f48cec639f0932aada0f039d78dac3"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:380992e9da3000ebefe45b50f65ed3bf88ba87574c4a6486a29553cfbfc04c22"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e8494bfcf6ceb8b59e1bf2678073e00155f6dd2afbec01eaefd2128d3a4f5c76"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:71cb7db481c791a52d261b924063431b72c4c288afd14a00cf7106274596a1c3"}, + {file = "pyobjc_framework_ShazamKit-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0a537e1f86f47ddde742fd0491173c669e6cda6b9edddbe72e56a148a40111f8"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-social" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Social on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Social-10.1.tar.gz", hash = "sha256:50757d982c712090e93b6ee4bd97ed3f6acfe7005f981f060433e94b7aca818b"}, - {file = "pyobjc_framework_Social-10.1-py2.py3-none-any.whl", hash = "sha256:81363d9d06c9c8ede16d96ec1d3cdba6deef195ef54cc64618e58c7fc1f574df"}, + {file = "pyobjc-framework-Social-10.2.tar.gz", hash = "sha256:34995cd0c0f6c4adbe7bfa9049463058c7a8676d34d3d5b9de37f87416f22a0a"}, + {file = "pyobjc_framework_Social-10.2-py2.py3-none-any.whl", hash = "sha256:76ed463e3a77c58e5b527c37eb8b2dd60658dd736ba243cfa24b4704580b58c4"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-soundanalysis" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SoundAnalysis on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SoundAnalysis-10.1.tar.gz", hash = "sha256:42e0ae24f11ef8cf097c71e5b2378eaba26f66cb39959fec4ca79812bc0ed417"}, - {file = "pyobjc_framework_SoundAnalysis-10.1-py2.py3-none-any.whl", hash = "sha256:a33bc8a1ecee11387beb9db06aaf9c362f7dc171d60da913277ac482d67beabb"}, + {file = "pyobjc-framework-SoundAnalysis-10.2.tar.gz", hash = "sha256:960434f16a130da4fe5cd86ceac832b7eb17831a1e739472f7636aceea65e018"}, + {file = "pyobjc_framework_SoundAnalysis-10.2-py2.py3-none-any.whl", hash = "sha256:a09b49acca76a3c161b937002e5d034cf32c33d033677a8143d446eb53ca941d"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-speech" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Speech on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Speech-10.1.tar.gz", hash = "sha256:a9eddebd4e4bcdb9c165129bea510c5e9f1353528a8211cc38c22711792bf30d"}, - {file = "pyobjc_framework_Speech-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:0cc26aca43d738d25f615def32eb8ce27675fc616584c009e57f6b82dec75cc5"}, - {file = "pyobjc_framework_Speech-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9a448c58149f5bbf0128f2c6492ea281b51f50bdc4f0ecd52bea43c80f7e2063"}, - {file = "pyobjc_framework_Speech-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:76a528fc587c8eb86cdba61bf6b94ddb7e3fb38a41f1a46217e2ce7fc21d6c26"}, + {file = "pyobjc-framework-Speech-10.2.tar.gz", hash = "sha256:4cb3445ff31a3f8d50492d420941723e07967b4fc4fc46c336403d8ca245c086"}, + {file = "pyobjc_framework_Speech-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:175195f945d89d2382c0f6052b798ef3ee41384b8bfa4954c16add126dc181f6"}, + {file = "pyobjc_framework_Speech-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c65cbda4b8d357b80d41695b1b505a759d3be8b63bca9dd7675053876878577"}, + {file = "pyobjc_framework_Speech-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b139f64cc3636f1cfdc78a4071068d34e9ea70283201fd7a821e41d5bbbcf306"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-spritekit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SpriteKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SpriteKit-10.1.tar.gz", hash = "sha256:998be1d6c7fd5cc66bd54bae37c45cf3394df7bc689b5d0c813f0449c8eee53f"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:23f6657e48f7d8cb434bcf6a76b2c336eb29be69ade933f88299465a0c83cb3b"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b5556d8469b20fe35a0ec5f9e493c30ebc531bce3be4e48fc99cb87338ba5cfb"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:aa51855f7bfed3dc1bcda95b140d71c4dc1e21c3480216df19f6fddc7dc7ce39"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2210920a4f9a39dc3bea9287e012cdfb740a0748faa6ab13bf8a58d07da913cc"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:66df1436d17bf0c17432d2d66ebeef8efee012240297e5aabc1118b014947375"}, - {file = "pyobjc_framework_SpriteKit-10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5564ed8648afba01f9877062204ed03d3fef8a980b6b4155c69d3662e4732947"}, + {file = "pyobjc-framework-SpriteKit-10.2.tar.gz", hash = "sha256:31b3e639a617c456574df8f3ce18275eff613cf49e98ea8df974cda05d13a7fc"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7b312677a70a7fe684af8726a39837e935fd6660f0271246885934f60d773506"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a8e015451fa701c7d9b383a95315809208145790d8e68a542def9fb10d6c2ce2"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:803138edacb0c5bbc40bfeb964c70521259a7fb9c0dd31a79824b36be3942f59"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ae44f20076286dd0d600f9b4c8c31f144abe1f44dbd37ca96ecdba98732bfb4a"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:9f5b65ac9fd0a40e28673a15c6c7785208402c02422a1e150f713b2c82681b51"}, + {file = "pyobjc_framework_SpriteKit-10.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a8f2e140ad818d6891f654369853f9439d0f280302bf5750c28df8a4fcc019ec"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-storekit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework StoreKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-StoreKit-10.1.tar.gz", hash = "sha256:4e91d77d1b9745eca6730ddf6cde964e2bd956fafad303591f671ebd1d4de64b"}, - {file = "pyobjc_framework_StoreKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:456641cbe97eab4bb68dccec6f8bf3bc435adaa0b2ae6a7a4a3da0adc84a9405"}, - {file = "pyobjc_framework_StoreKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:356966d260bd1e19c7cdba7551b3e477078d3d4b0df04b7f38013dd044913727"}, - {file = "pyobjc_framework_StoreKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:652657006d3c8fefcdbb662f8f33ef6ee8e01ba30a0b4d6e2fcd2e4046951766"}, + {file = "pyobjc-framework-StoreKit-10.2.tar.gz", hash = "sha256:44cf0b5fe605b9e5dc6aed2ae9e09d807d04d5f2eaf78afb8c04e3f109a0d680"}, + {file = "pyobjc_framework_StoreKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9e511ebf2d954f10999c2a46e5ecffee0235e0c35eda24c8fcfdb433768935d"}, + {file = "pyobjc_framework_StoreKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e22a701666a787d4df9f45bf1507cf41e45357b22c55ad79c608b24a506981e1"}, + {file = "pyobjc_framework_StoreKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:44c0a65bd39e64e276d8a7b991d93b59b149b3b886cadddb6a38253d48b123e5"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-symbols" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Symbols on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Symbols-10.1.tar.gz", hash = "sha256:63f5345fa90b31ea017c01ffd39e6e0289ef0258c6af7941263083d2289f5d3d"}, - {file = "pyobjc_framework_Symbols-10.1-py2.py3-none-any.whl", hash = "sha256:88b48102ba33ac3d8bc5c047cc892ab21e8e102c3b25b4186b77c5d1f5c1bc40"}, + {file = "pyobjc-framework-Symbols-10.2.tar.gz", hash = "sha256:b1874e79fdcaf65deaadda35a3c9dbd24eb92d7dc8aa4db5d7f14f2b06d8a312"}, + {file = "pyobjc_framework_Symbols-10.2-py2.py3-none-any.whl", hash = "sha256:3b5fa1e162acb04eab092e0e1dbe686e2fb61cf648850953e15314edb56fb05f"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-syncservices" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SyncServices on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SyncServices-10.1.tar.gz", hash = "sha256:644d394b84468fa6178b5aa609771252ca416ca2be2bac5501222b3c5151846d"}, - {file = "pyobjc_framework_SyncServices-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:edf7d5de135ec44b8ecf260265cb7bd9bf938d3fcc2204282aea674a86918c60"}, - {file = "pyobjc_framework_SyncServices-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:53ef6096359d182952fdb40734f17302edf35757578c0c52314f703322d855cb"}, - {file = "pyobjc_framework_SyncServices-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:b9d7ec3f784fc89847ad136bb3d67d159310a2e072a724d4ffddccf0ee5dec2b"}, + {file = "pyobjc-framework-SyncServices-10.2.tar.gz", hash = "sha256:1c76073484924201336e6aab40f10358573bc640a92ed4066b8062c748957576"}, + {file = "pyobjc_framework_SyncServices-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf40e4194bd42bb447212037876ca3e90e0e5a7aa21e59a6987f300209a83fb7"}, + {file = "pyobjc_framework_SyncServices-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:4e438c0cf74aecb95c2a86db9c39236fee3edf0a91814255e2aff18bf24e7e82"}, + {file = "pyobjc_framework_SyncServices-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:dffc9ddf9235176c1f1575095beae97d6d2ffa9cffe9c195f815c46f69070787"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreData = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreData = ">=10.2" [[package]] name = "pyobjc-framework-systemconfiguration" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SystemConfiguration on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SystemConfiguration-10.1.tar.gz", hash = "sha256:7e125872d4b54c8d04f15d83e7f7f706c18bd87960b3873c797e6a71b95030b0"}, - {file = "pyobjc_framework_SystemConfiguration-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ab80e4272937643de8569a711e5adee8afca2bf071b6cfc6b7fc4143010d258"}, - {file = "pyobjc_framework_SystemConfiguration-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:431c32557bde3dad18fb245bf1e5ce80963f28caa4d2691b5a82e6db2b5efc2f"}, - {file = "pyobjc_framework_SystemConfiguration-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:7e8ae510b11ceca8800bc7b4b0c7735cf26de803771199d6c2d8f24fbb5467df"}, + {file = "pyobjc-framework-SystemConfiguration-10.2.tar.gz", hash = "sha256:e9ec946ca56514a68e28040c55c79ba105c9a70b56698635767250e629c37e49"}, + {file = "pyobjc_framework_SystemConfiguration-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:d25ff4b8525f087fc004ece9518b38d365ef6bbc06e4c0f847d70cb72ca961df"}, + {file = "pyobjc_framework_SystemConfiguration-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2fc0a9d1c1c6a5d5b9d9289ee8e5de0d4ef8cb4c9bc03e8a33513217580a307b"}, + {file = "pyobjc_framework_SystemConfiguration-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:d33ebea6881c2e4b9ddd03f8def7495dc884b7e53fe3d6e1340d9f9cc7441878"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-systemextensions" -version = "10.1" +version = "10.2" description = "Wrappers for the framework SystemExtensions on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-SystemExtensions-10.1.tar.gz", hash = "sha256:3eb7ad8f1a6901294b02cd6d6581bd6960a48fcfd82475f5970d1c909f12670d"}, - {file = "pyobjc_framework_SystemExtensions-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8dc306dd07f9ff071759bb2237b7f7fddd0d2624966bdb0801dc5a70b026f431"}, - {file = "pyobjc_framework_SystemExtensions-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c76c6d7dbf253abe11ebfa83bbbfa7f2fc4c700db052771075c26dabbd5ee1e9"}, - {file = "pyobjc_framework_SystemExtensions-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:2586323fbe9382edebd7ca5dfe50b432c842b7ef45ef26444edcb7238bcf006f"}, + {file = "pyobjc-framework-SystemExtensions-10.2.tar.gz", hash = "sha256:883c41cb257fb2b5baadafa4213dc0f0fffc97edb35ebaf6ed95a185a786eb85"}, + {file = "pyobjc_framework_SystemExtensions-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:8a85c71121abe33a83742b84d046684e30e5400c5d2bbb4bca4322c4e9d5506b"}, + {file = "pyobjc_framework_SystemExtensions-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3374105ebc3992e8898b46ba85e860ac1f2f24985c640834bf2b9da26a8f40a7"}, + {file = "pyobjc_framework_SystemExtensions-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:5b699c94a05a7253d803fb75b6ea5c67d2c59eb906deceb7f3d0a44f42b5d7a8"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-threadnetwork" -version = "10.1" +version = "10.2" description = "Wrappers for the framework ThreadNetwork on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-ThreadNetwork-10.1.tar.gz", hash = "sha256:72694dce8b10937f4d8fef67d14e15fa65ba590dec8298df439fd0cc953a83fa"}, - {file = "pyobjc_framework_ThreadNetwork-10.1-py2.py3-none-any.whl", hash = "sha256:720d4a14619598431a22be2a720bf877f996d65cee430b96c5d7ec833b676b68"}, + {file = "pyobjc-framework-ThreadNetwork-10.2.tar.gz", hash = "sha256:864ebabdb187cef16e1fba0f5439a73b1ed9a4e66b888f7954b12150c323c0f8"}, + {file = "pyobjc_framework_ThreadNetwork-10.2-py2.py3-none-any.whl", hash = "sha256:f7ad31b4a67f9ed00097a21c7bbd48ffa4ce2c22174a52ac508beedf7cb2aa9e"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-uniformtypeidentifiers" -version = "10.1" +version = "10.2" description = "Wrappers for the framework UniformTypeIdentifiers on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-UniformTypeIdentifiers-10.1.tar.gz", hash = "sha256:e8a6e8d4c3c6d8213d18fab44704055a5fca91e0a74891b4f1bfe6574cd51d97"}, - {file = "pyobjc_framework_UniformTypeIdentifiers-10.1-py2.py3-none-any.whl", hash = "sha256:4c867b298956d74398d2b6354bd932dc109431d9726c8ea2fc9c83e6946a2a7d"}, + {file = "pyobjc-framework-UniformTypeIdentifiers-10.2.tar.gz", hash = "sha256:4d3e7add89766fe7abc6fd6e29387e92d7b38343b37d365607c9d287c5e758f6"}, + {file = "pyobjc_framework_UniformTypeIdentifiers-10.2-py2.py3-none-any.whl", hash = "sha256:25b72005063a88c5e67bf91d1355973f4bbf3dd7c1b3fb8eb00503020a837b33"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-usernotifications" -version = "10.1" +version = "10.2" description = "Wrappers for the framework UserNotifications on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-UserNotifications-10.1.tar.gz", hash = "sha256:eca638b04b60d5d8f5efecafc1fd021a1b55d4a6d1ebd22e65771eddb3dd478f"}, - {file = "pyobjc_framework_UserNotifications-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a44b89659eae1015da9148fc24f931108ff7a05ba61509bfab34af50806beb0c"}, - {file = "pyobjc_framework_UserNotifications-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:00aa84f29bcbe8f302d20c96ef51fb48af519d83e0b72d22bd075ea1af86629f"}, - {file = "pyobjc_framework_UserNotifications-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:fe9170b5c4da8e75288ada553cc821b9e3fc1279eb56fa9e3d4278b35a26c5ce"}, + {file = "pyobjc-framework-UserNotifications-10.2.tar.gz", hash = "sha256:3a1b7d77c95dff109f904451525752ece3c38f38cfa0825fd01735388c2b0264"}, + {file = "pyobjc_framework_UserNotifications-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:f4ce290d1874d8b4ec36b2fae9181fa230e6ce0dced3aeb0fd0d88b7cda6a75a"}, + {file = "pyobjc_framework_UserNotifications-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8bc0c9599d7bbf35bb79eb661d537d6ea506859d2f1332ae2ee34b140bd937ef"}, + {file = "pyobjc_framework_UserNotifications-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:12d1ea6683af36813e3bdbdb065c28d71d01dfed7ea4deedeb3585e55179cbbb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-usernotificationsui" -version = "10.1" +version = "10.2" description = "Wrappers for the framework UserNotificationsUI on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-UserNotificationsUI-10.1.tar.gz", hash = "sha256:09df08f47a7e605642a6c6846e365cab8b8631a7f87b41a65c35c52e484b9f8a"}, - {file = "pyobjc_framework_UserNotificationsUI-10.1-py2.py3-none-any.whl", hash = "sha256:6640c6d04f459b6927096696dac98ce5fcb702a507a757d6d1b909b341bb8a0d"}, + {file = "pyobjc-framework-UserNotificationsUI-10.2.tar.gz", hash = "sha256:f476d4a9f5b0746beda3d06ed6eb8a1b072372e644c707e675f4e11703528a81"}, + {file = "pyobjc_framework_UserNotificationsUI-10.2-py2.py3-none-any.whl", hash = "sha256:b0909b11655a7ae14e54ba6f80f1c6d34d46de5e8b565d0a51c22f87604ad3d3"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-UserNotifications = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-UserNotifications = ">=10.2" [[package]] name = "pyobjc-framework-videosubscriberaccount" -version = "10.1" +version = "10.2" description = "Wrappers for the framework VideoSubscriberAccount on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-VideoSubscriberAccount-10.1.tar.gz", hash = "sha256:6410c68ea37a4ba4667b8c71fbfd3c011bf6ecdb9f1d6adf3c9a35584b7c8804"}, - {file = "pyobjc_framework_VideoSubscriberAccount-10.1-py2.py3-none-any.whl", hash = "sha256:f32716070f849989e3ff052effb54f951b89a538208651426848d9d924ac1625"}, + {file = "pyobjc-framework-VideoSubscriberAccount-10.2.tar.gz", hash = "sha256:26ea7fe843ba316eea90c488ed3ff46651b94b51b6e3bd87db2ff93f9fa8e496"}, + {file = "pyobjc_framework_VideoSubscriberAccount-10.2-py2.py3-none-any.whl", hash = "sha256:300c9f419821aab400ab9798bed9fc659984f19eb8577934e6faae0428b89096"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-videotoolbox" -version = "10.1" +version = "10.2" description = "Wrappers for the framework VideoToolbox on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-VideoToolbox-10.1.tar.gz", hash = "sha256:56c9d4b74965fe79f050884ffa560ff71ffe709c24923d3d0b34459fb626eb11"}, - {file = "pyobjc_framework_VideoToolbox-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a4115690b8ed4266e52a4d200c870e68dd03119993280020a1a4d6a9d4764fcf"}, - {file = "pyobjc_framework_VideoToolbox-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:64874d253c2996216c6d56e03e848cf845c3f0eac84d06ba97d83871dbf19490"}, - {file = "pyobjc_framework_VideoToolbox-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:977b2981532442c4c99fff75ffcc2b5a4b0f8108abcabdafcda2addf8b2ffa21"}, + {file = "pyobjc-framework-VideoToolbox-10.2.tar.gz", hash = "sha256:347259a8e920dbc3dd1fada5ab0d829485cef3165166fa65f78c23ada4f9b80a"}, + {file = "pyobjc_framework_VideoToolbox-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb8147d673defdb02526b80b1584369f94b94721016950bb12425b2309b92c88"}, + {file = "pyobjc_framework_VideoToolbox-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6527180eede44301c21790baa7e1a5f5429893e3995e61640f3941c3b6fb08f9"}, + {file = "pyobjc_framework_VideoToolbox-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:de55d7629a9659439901a16d6074e9fc9b229e93a555097a1c92e0df6cfb5cdb"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreMedia = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreMedia = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-virtualization" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Virtualization on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Virtualization-10.1.tar.gz", hash = "sha256:48f2484a7627caa246f55daf203927f10600e615e620a2d9ca22e483ed0bb9b4"}, - {file = "pyobjc_framework_Virtualization-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:a434c40038c0c1acd31805795f28f959ea231252dc3ab34ed5a268c21227682c"}, - {file = "pyobjc_framework_Virtualization-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:8ad3e40ec5970e881f92af337354be68c1f2512690545a2da826684daeaa3535"}, - {file = "pyobjc_framework_Virtualization-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:2aba907617075394718bc8883c650197e21b2ea0d284ca51811229386114040a"}, + {file = "pyobjc-framework-Virtualization-10.2.tar.gz", hash = "sha256:49eb8d0ec3017c2194620f0698e95ccf20b8b706c73ab3b1b50902c57f0f86ff"}, + {file = "pyobjc_framework_Virtualization-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:492daa384cf3117749ff35127f81313bd1ea9bbd09385c2a882b82ca4ca0797e"}, + {file = "pyobjc_framework_Virtualization-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:1bea91b57d419d91e76865f9621ba4762793e05f7a694cefe73206f3a19b4eda"}, + {file = "pyobjc_framework_Virtualization-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:c1198bcd31e4711c6a0c6816c77483361217a1ed2f0ad69608f9ba5633efc144"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyobjc-framework-vision" -version = "10.1" +version = "10.2" description = "Wrappers for the framework Vision on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-Vision-10.1.tar.gz", hash = "sha256:ff50fb7577be8d8862a076a6cde5ebdc9ef07d9045e2158faaf0f04b5b051208"}, - {file = "pyobjc_framework_Vision-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:c6330d8b22f75f1e7d9a5456f3e2c7299d05d575b2e9b2f1e50230b18f17abed"}, - {file = "pyobjc_framework_Vision-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:91b4d740b6943f6b228915ece2e027555f28ccf49c8d063a580b8f9e5af56fd0"}, - {file = "pyobjc_framework_Vision-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:bb2d7334b4b725c5e5346a8cce2a0064259a09e90ec189b0c776304d5fc01e49"}, + {file = "pyobjc-framework-Vision-10.2.tar.gz", hash = "sha256:722e0a6da64738b5fc3c763a102445cad5892c0af94597637e89455099da397e"}, + {file = "pyobjc_framework_Vision-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:42b7383c317c2076edcb44f7ad8ed4a6e675250a3fd20e87eef8e0e4233b1b58"}, + {file = "pyobjc_framework_Vision-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5e3adb56fca35d41a4bb113f3eadbe45e9667d8e3edf64908da3d6b130e14a8c"}, + {file = "pyobjc_framework_Vision-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:e424d106052112897c8aa882d8334ac984e12509f9a473a285827ba47bfbcc9a"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" -pyobjc-framework-CoreML = ">=10.1" -pyobjc-framework-Quartz = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" +pyobjc-framework-CoreML = ">=10.2" +pyobjc-framework-Quartz = ">=10.2" [[package]] name = "pyobjc-framework-webkit" -version = "10.1" +version = "10.2" description = "Wrappers for the framework WebKit on macOS" optional = false python-versions = ">=3.8" files = [ - {file = "pyobjc-framework-WebKit-10.1.tar.gz", hash = "sha256:311974b626facee73cab5a7e53da4cc8966cbe60b606ba11fd0f3547e0ba1762"}, - {file = "pyobjc_framework_WebKit-10.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:ad9e1bd2fa9885818e1228c60e0d95100df69252f230ea8bb451fae73fcace61"}, - {file = "pyobjc_framework_WebKit-10.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c901fc6977b3298de789002a76a34c353ed38faedfc5ba63ef94a149ec9e5b02"}, - {file = "pyobjc_framework_WebKit-10.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f2d45dfc2c41792a5a983263d5b06c4fe70bf2f24943e2bf3097e4c9449a4516"}, + {file = "pyobjc-framework-WebKit-10.2.tar.gz", hash = "sha256:3717104dbc901a1bd46d97886c5adb6eb32798ff4451c4544e04740e41706083"}, + {file = "pyobjc_framework_WebKit-10.2-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:0d128a9e053b3dfaa71857eba6e6aadfbde88347382e1e58e288b5e410b71226"}, + {file = "pyobjc_framework_WebKit-10.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:d20344d55c3cb4aa27314e096f59db5cefa70539112d8c1658f2a2076df58612"}, + {file = "pyobjc_framework_WebKit-10.2-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:f7dcf2e51964406cc2440e556c855d087c4706289c5f53464e8ffb0fba37adda"}, ] [package.dependencies] -pyobjc-core = ">=10.1" -pyobjc-framework-Cocoa = ">=10.1" +pyobjc-core = ">=10.2" +pyobjc-framework-Cocoa = ">=10.2" [[package]] name = "pyopencl" @@ -6294,13 +6316,13 @@ test = ["Mako", "pytest (>=7.0.0)"] [[package]] name = "pyopenssl" -version = "24.0.0" +version = "24.1.0" description = "Python wrapper module around the OpenSSL library" optional = false python-versions = ">=3.7" files = [ - {file = "pyOpenSSL-24.0.0-py3-none-any.whl", hash = "sha256:ba07553fb6fd6a7a2259adb9b84e12302a9a8a75c44046e8bb5d3e5ee887e3c3"}, - {file = "pyOpenSSL-24.0.0.tar.gz", hash = "sha256:6aa33039a93fffa4563e655b61d11364d01264be8ccb49906101e02a334530bf"}, + {file = "pyOpenSSL-24.1.0-py3-none-any.whl", hash = "sha256:17ed5be5936449c5418d1cd269a1a9e9081bc54c17aed272b45856a3d3dc86ad"}, + {file = "pyOpenSSL-24.1.0.tar.gz", hash = "sha256:cabed4bfaa5df9f1a16c0ef64a0cb65318b5cd077a7eda7d6970131ca2f41a6f"}, ] [package.dependencies] @@ -6308,17 +6330,17 @@ cryptography = ">=41.0.5,<43" [package.extras] docs = ["sphinx (!=5.2.0,!=5.2.0.post0,!=7.2.5)", "sphinx-rtd-theme"] -test = ["flaky", "pretend", "pytest (>=3.0.1)"] +test = ["pretend", "pytest (>=3.0.1)", "pytest-rerunfailures"] [[package]] name = "pyparsing" -version = "3.1.1" +version = "3.1.2" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, - {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, ] [package.extras] @@ -6469,23 +6491,23 @@ cp2110 = ["hidapi"] [[package]] name = "pytest" -version = "8.0.2" +version = "8.1.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, - {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, + {file = "pytest-8.1.1-py3-none-any.whl", hash = "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7"}, + {file = "pytest-8.1.1.tar.gz", hash = "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.3.0,<2.0" +pluggy = ">=1.4,<2.0" [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" @@ -6536,13 +6558,13 @@ pytest = "*" [[package]] name = "pytest-subtests" -version = "0.11.0" +version = "0.12.1" description = "unittest subTest() support and subtests fixture" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-subtests-0.11.0.tar.gz", hash = "sha256:51865c88457545f51fb72011942f0a3c6901ee9e24cbfb6d1b9dc1348bafbe37"}, - {file = "pytest_subtests-0.11.0-py3-none-any.whl", hash = "sha256:453389984952eec85ab0ce0c4f026337153df79587048271c7fd0f49119c07e4"}, + {file = "pytest-subtests-0.12.1.tar.gz", hash = "sha256:d6605dcb88647e0b7c1889d027f8ef1c17d7a2c60927ebfdc09c7b0d8120476d"}, + {file = "pytest_subtests-0.12.1-py3-none-any.whl", hash = "sha256:100d9f7eb966fc98efba7026c802812ae327e8b5b37181fb260a2ea93226495c"}, ] [package.dependencies] @@ -6551,17 +6573,17 @@ pytest = ">=7.0" [[package]] name = "pytest-timeout" -version = "2.2.0" +version = "2.3.1" description = "pytest plugin to abort hanging tests" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, - {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, + {file = "pytest-timeout-2.3.1.tar.gz", hash = "sha256:12397729125c6ecbdaca01035b9e5239d4db97352320af155b3f5de1ba5165d9"}, + {file = "pytest_timeout-2.3.1-py3-none-any.whl", hash = "sha256:68188cb703edfc6a18fad98dc25a3c61e9f24d644b0b70f33af545219fc7813e"}, ] [package.dependencies] -pytest = ">=5.0.0" +pytest = ">=7.0.0" [[package]] name = "pytest-xdist" @@ -6585,13 +6607,13 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -6925,28 +6947,28 @@ docs = ["furo (==2023.9.10)", "pyenchant (==3.2.2)", "sphinx (==7.1.2)", "sphinx [[package]] name = "ruff" -version = "0.2.2" +version = "0.3.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"}, - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"}, - {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"}, - {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"}, - {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"}, - {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"}, + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:973a0e388b7bc2e9148c7f9be8b8c6ae7471b9be37e1cc732f8f44a6f6d7720d"}, + {file = "ruff-0.3.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfa60d23269d6e2031129b053fdb4e5a7b0637fc6c9c0586737b962b2f834493"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eca7ff7a47043cf6ce5c7f45f603b09121a7cc047447744b029d1b719278eb5"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7d3f6762217c1da954de24b4a1a70515630d29f71e268ec5000afe81377642d"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b24c19e8598916d9c6f5a5437671f55ee93c212a2c4c569605dc3842b6820386"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5a6cbf216b69c7090f0fe4669501a27326c34e119068c1494f35aaf4cc683778"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352e95ead6964974b234e16ba8a66dad102ec7bf8ac064a23f95371d8b198aab"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d6ab88c81c4040a817aa432484e838aaddf8bfd7ca70e4e615482757acb64f8"}, + {file = "ruff-0.3.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79bca3a03a759cc773fca69e0bdeac8abd1c13c31b798d5bb3c9da4a03144a9f"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2700a804d5336bcffe063fd789ca2c7b02b552d2e323a336700abb8ae9e6a3f8"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd66469f1a18fdb9d32e22b79f486223052ddf057dc56dea0caaf1a47bdfaf4e"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:45817af234605525cdf6317005923bf532514e1ea3d9270acf61ca2440691376"}, + {file = "ruff-0.3.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0da458989ce0159555ef224d5b7c24d3d2e4bf4c300b85467b08c3261c6bc6a8"}, + {file = "ruff-0.3.3-py3-none-win32.whl", hash = "sha256:f2831ec6a580a97f1ea82ea1eda0401c3cdf512cf2045fa3c85e8ef109e87de0"}, + {file = "ruff-0.3.3-py3-none-win_amd64.whl", hash = "sha256:be90bcae57c24d9f9d023b12d627e958eb55f595428bafcb7fec0791ad25ddfc"}, + {file = "ruff-0.3.3-py3-none-win_arm64.whl", hash = "sha256:0171aab5fecdc54383993389710a3d1227f2da124d76a2784a7098e818f92d61"}, + {file = "ruff-0.3.3.tar.gz", hash = "sha256:38671be06f57a2f8aba957d9f701ea889aa5736be806f18c0cd03d6ff0cbca8d"}, ] [[package]] @@ -6993,18 +7015,15 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", [[package]] name = "scons" -version = "4.6.0.post1" +version = "4.7.0" description = "Open Source next-generation build tool." optional = false python-versions = ">=3.6" files = [ - {file = "SCons-4.6.0.post1-py3-none-any.whl", hash = "sha256:9e0527b7a924e7af2b312c1f8961ef2776847bdc46a4d886af5a75f301da7ce3"}, - {file = "SCons-4.6.0.post1.tar.gz", hash = "sha256:d467a34546f5366a32e4d4419611d0138dd680210f24aa8491ebe9e4b83456cf"}, + {file = "SCons-4.7.0-py3-none-any.whl", hash = "sha256:93308e564966760a63a4c1e016b2cc15d07bb40db67b1c907732da0b9e9f8959"}, + {file = "SCons-4.7.0.tar.gz", hash = "sha256:d8b617f6610a73e46509de70dcf82f76861b79762ff602d546f4e80918ec81f3"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "seaborn" version = "0.13.2" @@ -7028,13 +7047,13 @@ stats = ["scipy (>=1.7)", "statsmodels (>=0.12)"] [[package]] name = "sentry-sdk" -version = "1.40.5" +version = "1.42.0" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.5.tar.gz", hash = "sha256:d2dca2392cc5c9a2cc9bb874dd7978ebb759682fe4fe889ee7e970ee8dd1c61e"}, - {file = "sentry_sdk-1.40.5-py2.py3-none-any.whl", hash = "sha256:d188b407c9bacbe2a50a824e1f8fb99ee1aeb309133310488c570cb6d7056643"}, + {file = "sentry-sdk-1.42.0.tar.gz", hash = "sha256:4a8364b8f7edbf47f95f7163e48334c96100d9c098f0ae6606e2e18183c223e6"}, + {file = "sentry_sdk-1.42.0-py2.py3-none-any.whl", hash = "sha256:a654ee7e497a3f5f6368b36d4f04baeab1fe92b3105f7f6965d6ef0de35a9ba4"}, ] [package.dependencies] @@ -7058,6 +7077,7 @@ grpcio = ["grpcio (>=1.21.1)"] httpx = ["httpx (>=0.16.0)"] huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] pure-eval = ["asttokens", "executing", "pure-eval"] @@ -7173,18 +7193,18 @@ test = ["pytest"] [[package]] name = "setuptools" -version = "69.1.1" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -7543,23 +7563,23 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] [[package]] name = "timezonefinder" -version = "6.4.0" +version = "6.5.0" description = "python package for finding the timezone of any point on earth (coordinates) offline" optional = false -python-versions = ">=3.9,<4" +python-versions = ">=3.8,<4" files = [ - {file = "timezonefinder-6.4.0-cp310-cp310-manylinux_2_35_x86_64.whl", hash = "sha256:b4d4cefcdfcd46ffc04858d12cb23b58faca06dad05f68b6b704421be9fc70bc"}, - {file = "timezonefinder-6.4.0.tar.gz", hash = "sha256:7d82ebbc822d5fa012dbfbde510999afce0d7d1482794838e6c4daf6cc327f97"}, + {file = "timezonefinder-6.5.0-cp38-cp38-manylinux_2_35_x86_64.whl", hash = "sha256:3c70e1ea468ecac11272aa0a727450fd7cf43039ae2a2c62f7900a0a42efb6d6"}, + {file = "timezonefinder-6.5.0.tar.gz", hash = "sha256:7afdb1516927e7766deb6da80c8bd66734a44ba3d898038fe73aef1e9cd39bb0"}, ] [package.dependencies] cffi = ">=1.15.1,<2" h3 = ">=3.7.6,<4" -numpy = ">=1.18,<2" +numpy = {version = ">=1.23,<2", markers = "python_version >= \"3.9\""} setuptools = ">=65.5" [package.extras] -numba = ["numba (>=0.59,<1)"] +numba = ["numba (>=0.56,<1)", "numba (>=0.59,<1)"] pytz = ["pytz (>=2022.7.1)"] [[package]] @@ -7595,13 +7615,13 @@ telegram = ["requests"] [[package]] name = "types-requests" -version = "2.31.0.20240218" +version = "2.31.0.20240311" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240218.tar.gz", hash = "sha256:f1721dba8385958f504a5386240b92de4734e047a08a40751c1654d1ac3349c5"}, - {file = "types_requests-2.31.0.20240218-py3-none-any.whl", hash = "sha256:a82807ec6ddce8f00fe0e949da6d6bc1fbf1715420218a9640d695f70a9e5a9b"}, + {file = "types-requests-2.31.0.20240311.tar.gz", hash = "sha256:b1c1b66abfb7fa79aae09097a811c4aa97130eb8831c60e47aee4ca344731ca5"}, + {file = "types_requests-2.31.0.20240311-py3-none-any.whl", hash = "sha256:47872893d65a38e282ee9f277a4ee50d1b28bd592040df7d1fdaffdf3779937d"}, ] [package.dependencies] @@ -7814,18 +7834,18 @@ multidict = ">=4.0" [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" diff --git a/release/build_release.sh b/release/build_release.sh index fc15cf6cdf..08f8a5a185 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -94,7 +94,7 @@ cp -pR -n --parents $TEST_FILES $BUILD_DIR/ cd $BUILD_DIR RELEASE=1 selfdrive/test/test_onroad.py #selfdrive/manager/test/test_manager.py -selfdrive/car/tests/test_car_interfaces.py +#selfdrive/car/tests/test_car_interfaces.py rm -rf $TEST_FILES if [ ! -z "$RELEASE_BRANCH" ]; then diff --git a/release/files_common b/release/files_common index 4286c46c90..94af70eff2 100644 --- a/release/files_common +++ b/release/files_common @@ -82,7 +82,6 @@ selfdrive/boardd/panda.h selfdrive/boardd/spi.cc selfdrive/boardd/panda_comms.h selfdrive/boardd/panda_comms.cc -selfdrive/boardd/set_time.py selfdrive/boardd/pandad.py selfdrive/boardd/tests/test_boardd_loopback.py @@ -183,6 +182,7 @@ system/hardware/pc/hardware.py system/ubloxd/.gitignore system/ubloxd/SConscript +system/ubloxd/pigeond.py system/ubloxd/generated/* system/ubloxd/*.h system/ubloxd/*.cc @@ -242,7 +242,6 @@ system/sensord/SConscript system/sensord/sensors_qcom2.cc system/sensord/sensors/*.cc system/sensord/sensors/*.h -system/sensord/pigeond.py system/webrtc/__init__.py system/webrtc/webrtcd.py diff --git a/release/verify.sh b/release/verify.sh deleted file mode 100755 index ec5266bd81..0000000000 --- a/release/verify.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -RED="\033[0;31m" -GREEN="\033[0;32m" -CLEAR="\033[0m" - -BRANCHES="devel release3" -for b in $BRANCHES; do - if git diff --quiet origin/$b origin/$b-staging && [ "$(git rev-parse origin/$b)" = "$(git rev-parse origin/$b-staging)" ]; then - printf "%-10s $GREEN ok $CLEAR\n" "$b" - else - printf "%-10s $RED mismatch $CLEAR\n" "$b" - fi -done diff --git a/scripts/count_cars.py b/scripts/count_cars.py index 8c0892bb82..28057ddb04 100755 --- a/scripts/count_cars.py +++ b/scripts/count_cars.py @@ -2,10 +2,10 @@ from collections import Counter from pprint import pprint -from openpilot.selfdrive.car.docs import get_all_car_info +from openpilot.selfdrive.car.docs import get_all_car_docs if __name__ == "__main__": - cars = get_all_car_info() + cars = get_all_car_docs() make_count = Counter(l.make for l in cars) print("\n", "*" * 20, len(cars), "total", "*" * 20, "\n") pprint(make_count) diff --git a/scripts/launch_corolla.sh b/scripts/launch_corolla.sh index 146fbacf0a..4e5bca6ce5 100755 --- a/scripts/launch_corolla.sh +++ b/scripts/launch_corolla.sh @@ -2,6 +2,6 @@ DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -export FINGERPRINT="TOYOTA COROLLA TSS2 2019" +export FINGERPRINT="TOYOTA_COROLLA_TSS2" export SKIP_FW_QUERY="1" $DIR/../launch_openpilot.sh diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index 9f901498b7..d228af572c 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -32,12 +32,13 @@ from cereal import log from cereal.services import SERVICE_LIST from openpilot.common.api import Api from openpilot.common.file_helpers import CallbackReader +from openpilot.common.git import get_commit, get_normalized_origin, get_short_branch from openpilot.common.params import Params from openpilot.common.realtime import set_core_affinity from openpilot.system.hardware import HARDWARE, PC from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_commit, get_normalized_origin, get_short_branch, get_version +from openpilot.system.version import get_version from openpilot.system.hardware.hw import Paths diff --git a/selfdrive/athena/manage_athenad.py b/selfdrive/athena/manage_athenad.py index 486e426911..3065bed5c7 100755 --- a/selfdrive/athena/manage_athenad.py +++ b/selfdrive/athena/manage_athenad.py @@ -7,7 +7,8 @@ from openpilot.common.params import Params from openpilot.selfdrive.manager.process import launcher from openpilot.common.swaglog import cloudlog from openpilot.system.hardware import HARDWARE -from openpilot.system.version import get_version, get_normalized_origin, get_short_branch, get_commit, is_dirty +from openpilot.common.git import get_commit, get_normalized_origin, get_short_branch +from openpilot.system.version import get_version, is_dirty ATHENA_MGR_PID_PARAM = "AthenadPid" diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index b2b59d3752..c4db1eab40 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -49,12 +49,6 @@ std::atomic ignition(false); ExitHandler do_exit; -static std::string get_time_str(const struct tm &time) { - char s[30] = {'\0'}; - std::strftime(s, std::size(s), "%Y-%m-%d %H:%M:%S", &time); - return s; -} - bool check_all_connected(const std::vector &pandas) { for (const auto& panda : pandas) { if (!panda->connected()) { @@ -65,36 +59,6 @@ bool check_all_connected(const std::vector &pandas) { return true; } -enum class SyncTimeDir { TO_PANDA, FROM_PANDA }; - -void sync_time(Panda *panda, SyncTimeDir dir) { - if (!panda->has_rtc) return; - - setenv("TZ", "UTC", 1); - struct tm sys_time = util::get_time(); - struct tm rtc_time = panda->get_rtc(); - - if (dir == SyncTimeDir::TO_PANDA) { - if (util::time_valid(sys_time)) { - // Write time to RTC if it looks reasonable - double seconds = difftime(mktime(&rtc_time), mktime(&sys_time)); - if (std::abs(seconds) > 1.1) { - panda->set_rtc(sys_time); - LOGW("Updating panda RTC. dt = %.2f System: %s RTC: %s", - seconds, get_time_str(sys_time).c_str(), get_time_str(rtc_time).c_str()); - } - } - } else if (dir == SyncTimeDir::FROM_PANDA) { - LOGW("System time: %s, RTC time: %s", get_time_str(sys_time).c_str(), get_time_str(rtc_time).c_str()); - - if (!util::time_valid(sys_time) && util::time_valid(rtc_time)) { - const struct timeval tv = {mktime(&rtc_time), 0}; - settimeofday(&tv, 0); - LOGE("System time wrong, setting from RTC."); - } - } -} - bool safety_setter_thread(std::vector pandas) { LOGD("Starting safety setter thread"); @@ -195,7 +159,6 @@ Panda *connect(std::string serial="", uint32_t index=0) { throw std::runtime_error("Panda firmware out of date. Run pandad.py to update."); } - sync_time(panda.get(), SyncTimeDir::FROM_PANDA); return panda.release(); } @@ -581,11 +544,6 @@ void peripheral_control_thread(Panda *panda, bool no_fan_control) { panda->set_ir_pwr(ir_pwr); prev_ir_pwr = ir_pwr; } - - // Write to rtc once per minute when no ignition present - if (!ignition && (sm.frame % 120 == 1)) { - sync_time(panda, SyncTimeDir::TO_PANDA); - } } } diff --git a/selfdrive/boardd/panda.cc b/selfdrive/boardd/panda.cc index d738231c7b..95cfe04efd 100644 --- a/selfdrive/boardd/panda.cc +++ b/selfdrive/boardd/panda.cc @@ -25,10 +25,6 @@ Panda::Panda(std::string serial, uint32_t bus_offset) : bus_offset(bus_offset) { } hw_type = get_hw_type(); - has_rtc = (hw_type == cereal::PandaState::PandaType::UNO) || - (hw_type == cereal::PandaState::PandaType::DOS) || - (hw_type == cereal::PandaState::PandaType::TRES); - can_reset_communications(); return; @@ -77,41 +73,6 @@ cereal::PandaState::PandaType Panda::get_hw_type() { return (cereal::PandaState::PandaType)(hw_query[0]); } -void Panda::set_rtc(struct tm sys_time) { - // tm struct has year defined as years since 1900 - handle->control_write(0xa1, (uint16_t)(1900 + sys_time.tm_year), 0); - handle->control_write(0xa2, (uint16_t)(1 + sys_time.tm_mon), 0); - handle->control_write(0xa3, (uint16_t)sys_time.tm_mday, 0); - // handle->control_write(0xa4, (uint16_t)(1 + sys_time.tm_wday), 0); - handle->control_write(0xa5, (uint16_t)sys_time.tm_hour, 0); - handle->control_write(0xa6, (uint16_t)sys_time.tm_min, 0); - handle->control_write(0xa7, (uint16_t)sys_time.tm_sec, 0); -} - -struct tm Panda::get_rtc() { - struct __attribute__((packed)) timestamp_t { - uint16_t year; // Starts at 0 - uint8_t month; - uint8_t day; - uint8_t weekday; - uint8_t hour; - uint8_t minute; - uint8_t second; - } rtc_time = {0}; - - handle->control_read(0xa0, 0, 0, (unsigned char*)&rtc_time, sizeof(rtc_time)); - - struct tm new_time = { 0 }; - new_time.tm_year = rtc_time.year - 1900; // tm struct has year defined as years since 1900 - new_time.tm_mon = rtc_time.month - 1; - new_time.tm_mday = rtc_time.day; - new_time.tm_hour = rtc_time.hour; - new_time.tm_min = rtc_time.minute; - new_time.tm_sec = rtc_time.second; - - return new_time; -} - void Panda::set_fan_speed(uint16_t fan_speed) { handle->control_write(0xb1, fan_speed, 0); } diff --git a/selfdrive/boardd/panda.h b/selfdrive/boardd/panda.h index 9d4b1b2092..f46150dd95 100644 --- a/selfdrive/boardd/panda.h +++ b/selfdrive/boardd/panda.h @@ -50,7 +50,6 @@ public: Panda(std::string serial="", uint32_t bus_offset=0); cereal::PandaState::PandaType hw_type = cereal::PandaState::PandaType::UNKNOWN; - bool has_rtc = false; const uint32_t bus_offset; bool connected(); @@ -64,8 +63,6 @@ public: cereal::PandaState::PandaType get_hw_type(); void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint16_t safety_param=0U); void set_alternative_experience(uint16_t alternative_experience); - void set_rtc(struct tm sys_time); - struct tm get_rtc(); void set_fan_speed(uint16_t fan_speed); uint16_t get_fan_speed(); void set_ir_pwr(uint16_t ir_pwr); diff --git a/selfdrive/boardd/pandad.py b/selfdrive/boardd/pandad.py index 988d1a2409..cf9938ec1d 100755 --- a/selfdrive/boardd/pandad.py +++ b/selfdrive/boardd/pandad.py @@ -10,7 +10,6 @@ from functools import cmp_to_key from panda import Panda, PandaDFU, PandaProtocolMismatch, FW_PATH from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params -from openpilot.selfdrive.boardd.set_time import set_time from openpilot.system.hardware import HARDWARE from openpilot.common.swaglog import cloudlog @@ -154,10 +153,6 @@ def main() -> NoReturn: cloudlog.event("panda.som_reset_triggered", health=health, serial=panda.get_usb_serial()) if first_run: - if panda.is_internal(): - # update time from RTC - set_time(cloudlog) - # reset panda to ensure we're in a good state cloudlog.info(f"Resetting panda {panda.get_usb_serial()}") if panda.is_internal(): diff --git a/selfdrive/boardd/set_time.py b/selfdrive/boardd/set_time.py deleted file mode 100755 index fe17f64e82..0000000000 --- a/selfdrive/boardd/set_time.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -import os -import datetime -from panda import Panda - -from openpilot.common.time import MIN_DATE - -def set_time(logger): - sys_time = datetime.datetime.today() - if sys_time > MIN_DATE: - logger.info("System time valid") - return - - try: - ps = Panda.list() - if len(ps) == 0: - logger.error("Failed to set time, no pandas found") - return - - for s in ps: - with Panda(serial=s) as p: - if not p.is_internal(): - continue - - # Set system time from panda RTC time - panda_time = p.get_datetime() - if panda_time > MIN_DATE: - logger.info(f"adjusting time from '{sys_time}' to '{panda_time}'") - os.system(f"TZ=UTC date -s '{panda_time}'") - break - except Exception: - logger.exception("Failed to fetch time from panda") - -if __name__ == "__main__": - import logging - logging.basicConfig(level=logging.DEBUG) - - set_time(logging) diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index 73ddb02899..9f9f6c2638 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -12,12 +12,12 @@ A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified. -# {{all_car_info | length}} Supported Cars +# {{all_car_docs | length}} Supported Cars |{{Column | map(attribute='value') | join('|') | replace(hardware_col_name, wide_hardware_col_name)}}| |---|---|---|{% for _ in range((Column | length) - 3) %}{{':---:|'}}{% endfor +%} -{% for car_info in all_car_info %} -|{% for column in Column %}{{car_info.get_column(column, star_icon, video_icon, footnote_tag)}}|{% endfor %} +{% for car_docs in all_car_docs %} +|{% for column in Column %}{{car_docs.get_column(column, star_icon, video_icon, footnote_tag)}}|{% endfor %} {% endfor %} diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index 1f784a4ab2..f7d6140640 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -1,7 +1,7 @@ # functions common among cars from collections import defaultdict, namedtuple from dataclasses import dataclass -from enum import IntFlag, ReprEnum +from enum import IntFlag, ReprEnum, EnumType from dataclasses import replace import capnp @@ -9,7 +9,7 @@ import capnp from cereal import car from openpilot.common.numpy_fast import clip, interp from openpilot.common.utils import Freezable -from openpilot.selfdrive.car.docs_definitions import CarInfo +from openpilot.selfdrive.car.docs_definitions import CarDocs # kg of standard extra cargo to count for drive, gas, etc... @@ -179,27 +179,6 @@ def crc8_pedal(data): return crc -def create_gas_interceptor_command(packer, gas_amount, idx): - # Common gas pedal msg generator - enable = gas_amount > 0.001 - - values = { - "ENABLE": enable, - "COUNTER_PEDAL": idx & 0xF, - } - - if enable: - values["GAS_COMMAND"] = gas_amount * 255. - values["GAS_COMMAND2"] = gas_amount * 255. - - dat = packer.make_can_msg("GAS_COMMAND", 0, values)[2] - - checksum = crc8_pedal(dat[:-1]) - values["CHECKSUM_PEDAL"] = checksum - - return packer.make_can_msg("GAS_COMMAND", 0, values) - - def make_can_msg(addr, dat, bus): return [addr, 0, dat, bus] @@ -245,9 +224,6 @@ class CanSignalRateCalculator: return self.rate -CarInfos = CarInfo | list[CarInfo] | None - - @dataclass(frozen=True, kw_only=True) class CarSpecs: mass: float # kg, curb weight @@ -264,14 +240,15 @@ class CarSpecs: @dataclass(order=True) class PlatformConfig(Freezable): - platform_str: str - car_info: CarInfos + car_docs: list[CarDocs] specs: CarSpecs dbc_dict: DbcDict flags: int = 0 + platform_str: str | None = None + def __hash__(self) -> int: return hash(self.platform_str) @@ -283,10 +260,18 @@ class PlatformConfig(Freezable): def __post_init__(self): self.init() - self.freeze() -class Platforms(str, ReprEnum): +class PlatformsType(EnumType): + def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **kwds): + for key in classdict._member_names.keys(): + cfg: PlatformConfig = classdict[key] + cfg.platform_str = key + cfg.freeze() + return super().__new__(metacls, cls, bases, classdict, boundary=boundary, _simple=_simple, **kwds) + + +class Platforms(str, ReprEnum, metaclass=PlatformsType): config: PlatformConfig def __new__(cls, platform_config: PlatformConfig): diff --git a/selfdrive/car/body/fingerprints.py b/selfdrive/car/body/fingerprints.py index 6efaabc137..ab7a5f8d7b 100644 --- a/selfdrive/car/body/fingerprints.py +++ b/selfdrive/car/body/fingerprints.py @@ -8,13 +8,13 @@ Ecu = car.CarParams.Ecu FINGERPRINTS = { - CAR.BODY: [{ + CAR.COMMA_BODY: [{ 513: 8, 516: 8, 514: 3, 515: 4 }], } FW_VERSIONS = { - CAR.BODY: { + CAR.COMMA_BODY: { (Ecu.engine, 0x720, None): [ b'0.0.01', b'0.3.00a', diff --git a/selfdrive/car/body/interface.py b/selfdrive/car/body/interface.py index 4d72d2f604..f797a7ecf8 100644 --- a/selfdrive/car/body/interface.py +++ b/selfdrive/car/body/interface.py @@ -37,6 +37,3 @@ class CarInterface(CarInterfaceBase): self.frame += 1 return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/body/values.py b/selfdrive/car/body/values.py index 46afa857aa..a1195f7cb5 100644 --- a/selfdrive/car/body/values.py +++ b/selfdrive/car/body/values.py @@ -1,6 +1,6 @@ from cereal import car from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarInfo +from openpilot.selfdrive.car.docs_definitions import CarDocs from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -20,9 +20,8 @@ class CarControllerParams: class CAR(Platforms): - BODY = PlatformConfig( - "COMMA BODY", - CarInfo("comma body", package="All"), + COMMA_BODY = PlatformConfig( + [CarDocs("comma body", package="All")], CarSpecs(mass=9, wheelbase=0.406, steerRatio=0.5, centerToFrontRatio=0.44), dbc_dict('comma_body', None), ) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index b16e2e5a47..fd8ecc5020 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -4,8 +4,6 @@ from collections.abc import Callable from cereal import car from openpilot.common.params import Params -from openpilot.common.basedir import BASEDIR -from openpilot.selfdrive.car.values import PLATFORMS from openpilot.system.version import is_comma_remote, is_tested_branch from openpilot.selfdrive.car.interfaces import get_interface_attr from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars @@ -49,17 +47,8 @@ def load_interfaces(brand_names): for brand_name in brand_names: path = f'openpilot.selfdrive.car.{brand_name}' CarInterface = __import__(path + '.interface', fromlist=['CarInterface']).CarInterface - - if os.path.exists(BASEDIR + '/' + path.replace('.', '/') + '/carstate.py'): - CarState = __import__(path + '.carstate', fromlist=['CarState']).CarState - else: - CarState = None - - if os.path.exists(BASEDIR + '/' + path.replace('.', '/') + '/carcontroller.py'): - CarController = __import__(path + '.carcontroller', fromlist=['CarController']).CarController - else: - CarController = None - + CarState = __import__(path + '.carstate', fromlist=['CarState']).CarState + CarController = __import__(path + '.carcontroller', fromlist=['CarController']).CarController for model_name in brand_names[brand_name]: ret[model_name] = (CarInterface, CarController, CarState) return ret @@ -192,9 +181,7 @@ def fingerprint(logcan, sendcan, num_pandas): fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), vin_rx_addr=vin_rx_addr, vin_rx_bus=vin_rx_bus, fingerprints=repr(finger), fw_query_time=fw_query_time, error=True) - car_platform = PLATFORMS.get(car_fingerprint, MOCK.MOCK) - - return car_platform, finger, vin, car_fw, source, exact_match + return car_fingerprint, finger, vin, car_fw, source, exact_match def get_car_interface(CP): @@ -207,7 +194,7 @@ def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1): if candidate is None: cloudlog.event("car doesn't match any fingerprints", fingerprints=repr(fingerprints), error=True) - candidate = "mock" + candidate = "MOCK" CarInterface, _, _ = interfaces[candidate] CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False) diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index eb1cf7e7d5..91b922c596 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -21,10 +21,16 @@ class CarState(CarStateBase): else: self.shifter_values = can_define.dv["GEAR"]["PRNDL"] + self.prev_distance_button = 0 + self.distance_button = 0 + def update(self, cp, cp_cam): ret = car.CarState.new_message() + self.prev_distance_button = self.distance_button + self.distance_button = cp.vl["CRUISE_BUTTONS"]["ACC_Distance_Dec"] + # lock info ret.doorOpen = any([cp.vl["BCM_1"]["DOOR_OPEN_FL"], cp.vl["BCM_1"]["DOOR_OPEN_FR"], diff --git a/selfdrive/car/chrysler/fingerprints.py b/selfdrive/car/chrysler/fingerprints.py index 3444b4cc5b..81533e6629 100644 --- a/selfdrive/car/chrysler/fingerprints.py +++ b/selfdrive/car/chrysler/fingerprints.py @@ -4,7 +4,7 @@ from openpilot.selfdrive.car.chrysler.values import CAR Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.PACIFICA_2017_HYBRID: { + CAR.CHRYSLER_PACIFICA_2017_HYBRID: { (Ecu.combinationMeter, 0x742, None): [ b'68239262AH', b'68239262AI', @@ -33,7 +33,7 @@ FW_VERSIONS = { b'05190226AK', ], }, - CAR.PACIFICA_2018: { + CAR.CHRYSLER_PACIFICA_2018: { (Ecu.combinationMeter, 0x742, None): [ b'68227902AF', b'68227902AG', @@ -90,11 +90,12 @@ FW_VERSIONS = { b'68380571AB', ], }, - CAR.PACIFICA_2020: { + CAR.CHRYSLER_PACIFICA_2020: { (Ecu.combinationMeter, 0x742, None): [ b'68405327AC', b'68436233AB', b'68436233AC', + b'68436234AB', b'68436250AE', b'68529067AA', b'68594993AB', @@ -141,6 +142,7 @@ FW_VERSIONS = { b'68443120AE ', b'68443123AC ', b'68443125AC ', + b'68496650AI ', b'68526752AD ', b'68526752AE ', b'68526754AE ', @@ -160,7 +162,7 @@ FW_VERSIONS = { b'68586231AD', ], }, - CAR.PACIFICA_2018_HYBRID: { + CAR.CHRYSLER_PACIFICA_2018_HYBRID: { (Ecu.combinationMeter, 0x742, None): [ b'68358439AE', b'68358439AG', @@ -187,7 +189,7 @@ FW_VERSIONS = { b'05190226AM', ], }, - CAR.PACIFICA_2019_HYBRID: { + CAR.CHRYSLER_PACIFICA_2019_HYBRID: { (Ecu.combinationMeter, 0x742, None): [ b'68405292AC', b'68434956AC', @@ -362,7 +364,7 @@ FW_VERSIONS = { b'68503664AC', ], }, - CAR.RAM_1500: { + CAR.RAM_1500_5TH_GEN: { (Ecu.combinationMeter, 0x742, None): [ b'68294051AG', b'68294051AI', @@ -379,6 +381,7 @@ FW_VERSIONS = { b'68434859AC', b'68434860AC', b'68453483AC', + b'68453483AD', b'68453487AD', b'68453491AC', b'68453499AD', @@ -404,8 +407,10 @@ FW_VERSIONS = { b'68527383AD', b'68527387AE', b'68527403AC', + b'68527403AD', b'68546047AF', b'68631938AA', + b'68631940AA', b'68631942AA', ], (Ecu.srs, 0x744, None): [ @@ -477,6 +482,7 @@ FW_VERSIONS = { ], (Ecu.engine, 0x7e0, None): [ b'05035699AG ', + b'05035841AC ', b'05036026AB ', b'05036065AE ', b'05036066AE ', @@ -509,11 +515,13 @@ FW_VERSIONS = { b'68455145AE ', b'68455146AC ', b'68467915AC ', + b'68467916AC ', b'68467936AC ', b'68500630AD', b'68500630AE', b'68502719AC ', b'68502722AC ', + b'68502733AC ', b'68502734AF ', b'68502740AF ', b'68502741AF ', @@ -524,6 +532,7 @@ FW_VERSIONS = { b'68586101AA ', b'68586105AB ', b'68629922AC ', + b'68629925AC ', b'68629926AC ', ], (Ecu.transmission, 0x7e1, None): [ @@ -559,7 +568,7 @@ FW_VERSIONS = { b'68629936AC', ], }, - CAR.RAM_HD: { + CAR.RAM_HD_5TH_GEN: { (Ecu.combinationMeter, 0x742, None): [ b'68361606AH', b'68437735AC', diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index eb40bc6f6e..217a1a756c 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 from cereal import car from panda import Panda -from openpilot.selfdrive.car import get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags from openpilot.selfdrive.car.interfaces import CarInterfaceBase +ButtonType = car.CarState.ButtonEvent.Type + class CarInterface(CarInterfaceBase): @staticmethod @@ -27,13 +29,14 @@ class CarInterface(CarInterfaceBase): CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) if candidate not in RAM_CARS: # Newer FW versions standard on the following platforms, or flashed by a dealer onto older platforms have a higher minimum steering speed. - new_eps_platform = candidate in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_GRAND_CHEROKEE_2019, CAR.DODGE_DURANGO) + new_eps_platform = candidate in (CAR.CHRYSLER_PACIFICA_2019_HYBRID, CAR.CHRYSLER_PACIFICA_2020, CAR.JEEP_GRAND_CHEROKEE_2019, CAR.DODGE_DURANGO) new_eps_firmware = any(fw.ecu == 'eps' and fw.fwVersion[:4] >= b"6841" for fw in car_fw) if new_eps_platform or new_eps_firmware: ret.flags |= ChryslerFlags.HIGHER_MIN_STEERING_SPEED.value # Chrysler - if candidate in (CAR.PACIFICA_2017_HYBRID, CAR.PACIFICA_2018, CAR.PACIFICA_2018_HYBRID, CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.DODGE_DURANGO): + if candidate in (CAR.CHRYSLER_PACIFICA_2017_HYBRID, CAR.CHRYSLER_PACIFICA_2018, CAR.CHRYSLER_PACIFICA_2018_HYBRID, \ + CAR.CHRYSLER_PACIFICA_2019_HYBRID, CAR.CHRYSLER_PACIFICA_2020, CAR.DODGE_DURANGO): ret.lateralTuning.init('pid') ret.lateralTuning.pid.kpBP, ret.lateralTuning.pid.kiBP = [[9., 20.], [9., 20.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.15, 0.30], [0.03, 0.05]] @@ -49,14 +52,14 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kf = 0.00006 # Ram - elif candidate == CAR.RAM_1500: + elif candidate == CAR.RAM_1500_5TH_GEN: ret.steerActuatorDelay = 0.2 ret.wheelbase = 3.88 # Older EPS FW allow steer to zero if any(fw.ecu == 'eps' and b"68" < fw.fwVersion[:4] <= b"6831" for fw in car_fw): ret.minSteerSpeed = 0. - elif candidate == CAR.RAM_HD: + elif candidate == CAR.RAM_HD_5TH_GEN: ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, 1.0, False) @@ -76,6 +79,8 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) + ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + # events events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low]) @@ -90,6 +95,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 7dcfa3749e..42ea94cf86 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -4,7 +4,7 @@ from dataclasses import dataclass, field from cereal import car from panda.python import uds from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarHarness, CarInfo, CarParts +from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarParts from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16 Ecu = car.CarParams.Ecu @@ -15,7 +15,7 @@ class ChryslerFlags(IntFlag): HIGHER_MIN_STEERING_SPEED = 1 @dataclass -class ChryslerCarInfo(CarInfo): +class ChryslerCarDocs(CarDocs): package: str = "Adaptive Cruise Control (ACC)" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.fca])) @@ -32,67 +32,57 @@ class ChryslerCarSpecs(CarSpecs): class CAR(Platforms): # Chrysler - PACIFICA_2017_HYBRID = ChryslerPlatformConfig( - "CHRYSLER PACIFICA HYBRID 2017", - ChryslerCarInfo("Chrysler Pacifica Hybrid 2017"), + CHRYSLER_PACIFICA_2017_HYBRID = ChryslerPlatformConfig( + [ChryslerCarDocs("Chrysler Pacifica Hybrid 2017")], ChryslerCarSpecs(mass=2242., wheelbase=3.089, steerRatio=16.2), ) - PACIFICA_2018_HYBRID = ChryslerPlatformConfig( - "CHRYSLER PACIFICA HYBRID 2018", - ChryslerCarInfo("Chrysler Pacifica Hybrid 2018"), - PACIFICA_2017_HYBRID.specs, + CHRYSLER_PACIFICA_2018_HYBRID = ChryslerPlatformConfig( + [ChryslerCarDocs("Chrysler Pacifica Hybrid 2018")], + CHRYSLER_PACIFICA_2017_HYBRID.specs, ) - PACIFICA_2019_HYBRID = ChryslerPlatformConfig( - "CHRYSLER PACIFICA HYBRID 2019", - ChryslerCarInfo("Chrysler Pacifica Hybrid 2019-23"), - PACIFICA_2017_HYBRID.specs, + CHRYSLER_PACIFICA_2019_HYBRID = ChryslerPlatformConfig( + [ChryslerCarDocs("Chrysler Pacifica Hybrid 2019-23")], + CHRYSLER_PACIFICA_2017_HYBRID.specs, ) - PACIFICA_2018 = ChryslerPlatformConfig( - "CHRYSLER PACIFICA 2018", - ChryslerCarInfo("Chrysler Pacifica 2017-18"), - PACIFICA_2017_HYBRID.specs, + CHRYSLER_PACIFICA_2018 = ChryslerPlatformConfig( + [ChryslerCarDocs("Chrysler Pacifica 2017-18")], + CHRYSLER_PACIFICA_2017_HYBRID.specs, ) - PACIFICA_2020 = ChryslerPlatformConfig( - "CHRYSLER PACIFICA 2020", + CHRYSLER_PACIFICA_2020 = ChryslerPlatformConfig( [ - ChryslerCarInfo("Chrysler Pacifica 2019-20"), - ChryslerCarInfo("Chrysler Pacifica 2021-23", package="All"), + ChryslerCarDocs("Chrysler Pacifica 2019-20"), + ChryslerCarDocs("Chrysler Pacifica 2021-23", package="All"), ], - PACIFICA_2017_HYBRID.specs, + CHRYSLER_PACIFICA_2017_HYBRID.specs, ) # Dodge DODGE_DURANGO = ChryslerPlatformConfig( - "DODGE DURANGO 2021", - ChryslerCarInfo("Dodge Durango 2020-21"), - PACIFICA_2017_HYBRID.specs, + [ChryslerCarDocs("Dodge Durango 2020-21")], + CHRYSLER_PACIFICA_2017_HYBRID.specs, ) # Jeep JEEP_GRAND_CHEROKEE = ChryslerPlatformConfig( # includes 2017 Trailhawk - "JEEP GRAND CHEROKEE V6 2018", - ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"), + [ChryslerCarDocs("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk")], ChryslerCarSpecs(mass=1778., wheelbase=2.71, steerRatio=16.7), ) JEEP_GRAND_CHEROKEE_2019 = ChryslerPlatformConfig( # includes 2020 Trailhawk - "JEEP GRAND CHEROKEE 2019", - ChryslerCarInfo("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"), + [ChryslerCarDocs("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4")], JEEP_GRAND_CHEROKEE.specs, ) # Ram - RAM_1500 = ChryslerPlatformConfig( - "RAM 1500 5TH GEN", - ChryslerCarInfo("Ram 1500 2019-24", car_parts=CarParts.common([CarHarness.ram])), + RAM_1500_5TH_GEN = ChryslerPlatformConfig( + [ChryslerCarDocs("Ram 1500 2019-24", car_parts=CarParts.common([CarHarness.ram]))], ChryslerCarSpecs(mass=2493., wheelbase=3.88, steerRatio=16.3, minSteerSpeed=14.5), dbc_dict('chrysler_ram_dt_generated', None), ) - RAM_HD = ChryslerPlatformConfig( - "RAM HD 5TH GEN", + RAM_HD_5TH_GEN = ChryslerPlatformConfig( [ - ChryslerCarInfo("Ram 2500 2020-24", car_parts=CarParts.common([CarHarness.ram])), - ChryslerCarInfo("Ram 3500 2019-22", car_parts=CarParts.common([CarHarness.ram])), + ChryslerCarDocs("Ram 2500 2020-24", car_parts=CarParts.common([CarHarness.ram])), + ChryslerCarDocs("Ram 3500 2019-22", car_parts=CarParts.common([CarHarness.ram])), ], ChryslerCarSpecs(mass=3405., wheelbase=3.785, steerRatio=15.61, minSteerSpeed=16.), dbc_dict('chrysler_ram_hd_generated', None), @@ -119,8 +109,8 @@ class CarControllerParams: STEER_THRESHOLD = 120 -RAM_DT = {CAR.RAM_1500, } -RAM_HD = {CAR.RAM_HD, } +RAM_DT = {CAR.RAM_1500_5TH_GEN, } +RAM_HD = {CAR.RAM_HD_5TH_GEN, } RAM_CARS = RAM_DT | RAM_HD diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py index ce46bd93c2..7bf6a6ad22 100755 --- a/selfdrive/car/docs.py +++ b/selfdrive/car/docs.py @@ -9,7 +9,7 @@ from natsort import natsorted from cereal import car from openpilot.common.basedir import BASEDIR from openpilot.selfdrive.car import gen_empty_fingerprint -from openpilot.selfdrive.car.docs_definitions import CarInfo, Column, CommonFootnote, PartType +from openpilot.selfdrive.car.docs_definitions import CarDocs, Column, CommonFootnote, PartType from openpilot.selfdrive.car.car_helpers import interfaces, get_interface_attr from openpilot.selfdrive.car.values import PLATFORMS @@ -25,46 +25,43 @@ CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md") CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") -def get_all_car_info() -> list[CarInfo]: - all_car_info: list[CarInfo] = [] +def get_all_car_docs() -> list[CarDocs]: + all_car_docs: list[CarDocs] = [] footnotes = get_all_footnotes() for model, platform in PLATFORMS.items(): - car_info = platform.config.car_info + car_docs = platform.config.car_docs # If available, uses experimental longitudinal limits for the docs CP = interfaces[model][0].get_params(platform, fingerprint=gen_empty_fingerprint(), car_fw=[car.CarParams.CarFw(ecu="unknown")], experimental_long=True, docs=True) - if CP.dashcamOnly or car_info is None: + if CP.dashcamOnly or not len(car_docs): continue # A platform can include multiple car models - if not isinstance(car_info, list): - car_info = [car_info,] - - for _car_info in car_info: - if not hasattr(_car_info, "row"): - _car_info.init_make(CP) - _car_info.init(CP, footnotes) - all_car_info.append(_car_info) + for _car_docs in car_docs: + if not hasattr(_car_docs, "row"): + _car_docs.init_make(CP) + _car_docs.init(CP, footnotes) + all_car_docs.append(_car_docs) # Sort cars by make and model + year - sorted_cars: list[CarInfo] = natsorted(all_car_info, key=lambda car: car.name.lower()) + sorted_cars: list[CarDocs] = natsorted(all_car_docs, key=lambda car: car.name.lower()) return sorted_cars -def group_by_make(all_car_info: list[CarInfo]) -> dict[str, list[CarInfo]]: - sorted_car_info = defaultdict(list) - for car_info in all_car_info: - sorted_car_info[car_info.make].append(car_info) - return dict(sorted_car_info) +def group_by_make(all_car_docs: list[CarDocs]) -> dict[str, list[CarDocs]]: + sorted_car_docs = defaultdict(list) + for car_docs in all_car_docs: + sorted_car_docs[car_docs.make].append(car_docs) + return dict(sorted_car_docs) -def generate_cars_md(all_car_info: list[CarInfo], template_fn: str) -> str: +def generate_cars_md(all_car_docs: list[CarDocs], template_fn: str) -> str: with open(template_fn) as f: template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True) footnotes = [fn.value.text for fn in get_all_footnotes()] - cars_md: str = template.render(all_car_info=all_car_info, PartType=PartType, + cars_md: str = template.render(all_car_docs=all_car_docs, PartType=PartType, group_by_make=group_by_make, footnotes=footnotes, Column=Column) return cars_md @@ -79,5 +76,5 @@ if __name__ == "__main__": args = parser.parse_args() with open(args.out, 'w') as f: - f.write(generate_cars_md(get_all_car_info(), args.template)) + f.write(generate_cars_md(get_all_car_docs(), args.template)) print(f"Generated and written to {args.out}") diff --git a/selfdrive/car/docs_definitions.py b/selfdrive/car/docs_definitions.py index 1adf78b1c8..fe717d930e 100644 --- a/selfdrive/car/docs_definitions.py +++ b/selfdrive/car/docs_definitions.py @@ -220,7 +220,7 @@ def split_name(name: str) -> tuple[str, str, str]: @dataclass -class CarInfo: +class CarDocs: # make + model + model years name: str @@ -266,7 +266,7 @@ class CarInfo: # min steer & enable speed columns # TODO: set all the min steer speeds in carParams and remove this if self.min_steer_speed is not None: - assert CP.minSteerSpeed == 0, f"{CP.carFingerprint}: Minimum steer speed set in both CarInfo and CarParams" + assert CP.minSteerSpeed == 0, f"{CP.carFingerprint}: Minimum steer speed set in both CarDocs and CarParams" else: self.min_steer_speed = CP.minSteerSpeed @@ -317,7 +317,7 @@ class CarInfo: return self def init_make(self, CP: car.CarParams): - """CarInfo subclasses can add make-specific logic for harness selection, footnotes, etc.""" + """CarDocs subclasses can add make-specific logic for harness selection, footnotes, etc.""" def get_detail_sentence(self, CP): if not CP.notCar: @@ -346,7 +346,7 @@ class CarInfo: return sentence_builder.format(car_model=f"{self.make} {self.model}", alc=alc, acc=acc) else: - if CP.carFingerprint == "COMMA BODY": + if CP.carFingerprint == "COMMA_BODY": return "The body is a robotics dev kit that can run openpilot. Learn more." else: raise Exception(f"This notCar does not have a detail sentence: {CP.carFingerprint}") diff --git a/selfdrive/car/fingerprints.py b/selfdrive/car/fingerprints.py index 6a7c3c75be..977df6bc9f 100644 --- a/selfdrive/car/fingerprints.py +++ b/selfdrive/car/fingerprints.py @@ -1,4 +1,16 @@ from openpilot.selfdrive.car.interfaces import get_interface_attr +from openpilot.selfdrive.car.body.values import CAR as BODY +from openpilot.selfdrive.car.chrysler.values import CAR as CHRYSLER +from openpilot.selfdrive.car.ford.values import CAR as FORD +from openpilot.selfdrive.car.gm.values import CAR as GM +from openpilot.selfdrive.car.honda.values import CAR as HONDA +from openpilot.selfdrive.car.hyundai.values import CAR as HYUNDAI +from openpilot.selfdrive.car.mazda.values import CAR as MAZDA +from openpilot.selfdrive.car.nissan.values import CAR as NISSAN +from openpilot.selfdrive.car.subaru.values import CAR as SUBARU +from openpilot.selfdrive.car.tesla.values import CAR as TESLA +from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA +from openpilot.selfdrive.car.volkswagen.values import CAR as VW FW_VERSIONS = get_interface_attr('FW_VERSIONS', combine_brands=True, ignore_none=True) _FINGERPRINTS = get_interface_attr('FINGERPRINTS', combine_brands=True, ignore_none=True) @@ -44,3 +56,283 @@ def all_known_cars(): def all_legacy_fingerprint_cars(): """Returns a list of all known car strings, FPv1 only.""" return list(_FINGERPRINTS.keys()) + + +# A dict that maps old platform strings to their latest representations +MIGRATION = { + "ACURA ILX 2016 ACURAWATCH PLUS": HONDA.ACURA_ILX, + "ACURA RDX 2018 ACURAWATCH PLUS": HONDA.ACURA_RDX, + "ACURA RDX 2020 TECH": HONDA.ACURA_RDX_3G, + "AUDI A3": VW.AUDI_A3_MK3, + "HONDA ACCORD 2018 HYBRID TOURING": HONDA.HONDA_ACCORD, + "HONDA ACCORD 1.5T 2018": HONDA.HONDA_ACCORD, + "HONDA ACCORD 2018 LX 1.5T": HONDA.HONDA_ACCORD, + "HONDA ACCORD 2018 SPORT 2T": HONDA.HONDA_ACCORD, + "HONDA ACCORD 2T 2018": HONDA.HONDA_ACCORD, + "HONDA ACCORD HYBRID 2018": HONDA.HONDA_ACCORD, + "HONDA CIVIC 2016 TOURING": HONDA.HONDA_CIVIC, + "HONDA CIVIC HATCHBACK 2017 SEDAN/COUPE 2019": HONDA.HONDA_CIVIC_BOSCH, + "HONDA CIVIC SEDAN 1.6 DIESEL": HONDA.HONDA_CIVIC_BOSCH_DIESEL, + "HONDA CR-V 2016 EXECUTIVE": HONDA.HONDA_CRV_EU, + "HONDA CR-V 2016 TOURING": HONDA.HONDA_CRV, + "HONDA CR-V 2017 EX": HONDA.HONDA_CRV_5G, + "HONDA CR-V 2019 HYBRID": HONDA.HONDA_CRV_HYBRID, + "HONDA FIT 2018 EX": HONDA.HONDA_FIT, + "HONDA HRV 2019 TOURING": HONDA.HONDA_HRV, + "HONDA INSIGHT 2019 TOURING": HONDA.HONDA_INSIGHT, + "HONDA ODYSSEY 2018 EX-L": HONDA.HONDA_ODYSSEY, + "HONDA ODYSSEY 2019 EXCLUSIVE CHN": HONDA.HONDA_ODYSSEY_CHN, + "HONDA PILOT 2017 TOURING": HONDA.HONDA_PILOT, + "HONDA PILOT 2019 ELITE": HONDA.HONDA_PILOT, + "HONDA PILOT 2019": HONDA.HONDA_PILOT, + "HONDA PASSPORT 2021": HONDA.HONDA_PILOT, + "HONDA RIDGELINE 2017 BLACK EDITION": HONDA.HONDA_RIDGELINE, + "HYUNDAI ELANTRA LIMITED ULTIMATE 2017": HYUNDAI.HYUNDAI_ELANTRA, + "HYUNDAI SANTA FE LIMITED 2019": HYUNDAI.HYUNDAI_SANTA_FE, + "HYUNDAI TUCSON DIESEL 2019": HYUNDAI.HYUNDAI_TUCSON, + "KIA OPTIMA 2016": HYUNDAI.KIA_OPTIMA_G4, + "KIA OPTIMA 2019": HYUNDAI.KIA_OPTIMA_G4_FL, + "KIA OPTIMA SX 2019 & 2016": HYUNDAI.KIA_OPTIMA_G4_FL, + "LEXUS CT 200H 2018": TOYOTA.LEXUS_CTH, + "LEXUS ES 300H 2018": TOYOTA.LEXUS_ES, + "LEXUS ES 300H 2019": TOYOTA.LEXUS_ES_TSS2, + "LEXUS IS300 2018": TOYOTA.LEXUS_IS, + "LEXUS NX300 2018": TOYOTA.LEXUS_NX, + "LEXUS NX300H 2018": TOYOTA.LEXUS_NX, + "LEXUS RX 350 2016": TOYOTA.LEXUS_RX, + "LEXUS RX350 2020": TOYOTA.LEXUS_RX_TSS2, + "LEXUS RX450 HYBRID 2020": TOYOTA.LEXUS_RX_TSS2, + "TOYOTA SIENNA XLE 2018": TOYOTA.TOYOTA_SIENNA, + "TOYOTA C-HR HYBRID 2018": TOYOTA.TOYOTA_CHR, + "TOYOTA COROLLA HYBRID TSS2 2019": TOYOTA.TOYOTA_COROLLA_TSS2, + "TOYOTA RAV4 HYBRID 2019": TOYOTA.TOYOTA_RAV4_TSS2, + "LEXUS ES HYBRID 2019": TOYOTA.LEXUS_ES_TSS2, + "LEXUS NX HYBRID 2018": TOYOTA.LEXUS_NX, + "LEXUS NX HYBRID 2020": TOYOTA.LEXUS_NX_TSS2, + "LEXUS RX HYBRID 2020": TOYOTA.LEXUS_RX_TSS2, + "TOYOTA ALPHARD HYBRID 2021": TOYOTA.TOYOTA_ALPHARD_TSS2, + "TOYOTA AVALON HYBRID 2019": TOYOTA.TOYOTA_AVALON_2019, + "TOYOTA AVALON HYBRID 2022": TOYOTA.TOYOTA_AVALON_TSS2, + "TOYOTA CAMRY HYBRID 2018": TOYOTA.TOYOTA_CAMRY, + "TOYOTA CAMRY HYBRID 2021": TOYOTA.TOYOTA_CAMRY_TSS2, + "TOYOTA C-HR HYBRID 2022": TOYOTA.TOYOTA_CHR_TSS2, + "TOYOTA HIGHLANDER HYBRID 2020": TOYOTA.TOYOTA_HIGHLANDER_TSS2, + "TOYOTA RAV4 HYBRID 2022": TOYOTA.TOYOTA_RAV4_TSS2_2022, + "TOYOTA RAV4 HYBRID 2023": TOYOTA.TOYOTA_RAV4_TSS2_2023, + "TOYOTA HIGHLANDER HYBRID 2018": TOYOTA.TOYOTA_HIGHLANDER, + "LEXUS ES HYBRID 2018": TOYOTA.LEXUS_ES, + "LEXUS RX HYBRID 2017": TOYOTA.LEXUS_RX, + "HYUNDAI TUCSON HYBRID 4TH GEN": HYUNDAI.HYUNDAI_TUCSON_4TH_GEN, + "KIA SPORTAGE HYBRID 5TH GEN": HYUNDAI.KIA_SPORTAGE_5TH_GEN, + "KIA SORENTO PLUG-IN HYBRID 4TH GEN": HYUNDAI.KIA_SORENTO_HEV_4TH_GEN, + + # Removal of platform_str, see https://github.com/commaai/openpilot/pull/31868/ + "COMMA BODY": BODY.COMMA_BODY, + "CHRYSLER PACIFICA HYBRID 2017": CHRYSLER.CHRYSLER_PACIFICA_2017_HYBRID, + "CHRYSLER PACIFICA HYBRID 2018": CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID, + "CHRYSLER PACIFICA HYBRID 2019": CHRYSLER.CHRYSLER_PACIFICA_2019_HYBRID, + "CHRYSLER PACIFICA 2018": CHRYSLER.CHRYSLER_PACIFICA_2018, + "CHRYSLER PACIFICA 2020": CHRYSLER.CHRYSLER_PACIFICA_2020, + "DODGE DURANGO 2021": CHRYSLER.DODGE_DURANGO, + "RAM 1500 5TH GEN": CHRYSLER.RAM_1500_5TH_GEN, + "RAM HD 5TH GEN": CHRYSLER.RAM_HD_5TH_GEN, + "FORD BRONCO SPORT 1ST GEN": FORD.FORD_BRONCO_SPORT_MK1, + "FORD ESCAPE 4TH GEN": FORD.FORD_ESCAPE_MK4, + "FORD EXPLORER 6TH GEN": FORD.FORD_EXPLORER_MK6, + "FORD F-150 14TH GEN": FORD.FORD_F_150_MK14, + "FORD F-150 LIGHTNING 1ST GEN": FORD.FORD_F_150_LIGHTNING_MK1, + "FORD FOCUS 4TH GEN": FORD.FORD_FOCUS_MK4, + "FORD MAVERICK 1ST GEN": FORD.FORD_MAVERICK_MK1, + "FORD MUSTANG MACH-E 1ST GEN": FORD.FORD_MUSTANG_MACH_E_MK1, + "HOLDEN ASTRA RS-V BK 2017": GM.HOLDEN_ASTRA, + "CHEVROLET VOLT PREMIER 2017": GM.CHEVROLET_VOLT, + "CADILLAC ATS Premium Performance 2018": GM.CADILLAC_ATS, + "CHEVROLET MALIBU PREMIER 2017": GM.CHEVROLET_MALIBU, + "GMC ACADIA DENALI 2018": GM.GMC_ACADIA, + "BUICK LACROSSE 2017": GM.BUICK_LACROSSE, + "BUICK REGAL ESSENCE 2018": GM.BUICK_REGAL, + "CADILLAC ESCALADE 2017": GM.CADILLAC_ESCALADE, + "CADILLAC ESCALADE ESV 2016": GM.CADILLAC_ESCALADE_ESV, + "CADILLAC ESCALADE ESV 2019": GM.CADILLAC_ESCALADE_ESV_2019, + "CHEVROLET BOLT EUV 2022": GM.CHEVROLET_BOLT_EUV, + "CHEVROLET SILVERADO 1500 2020": GM.CHEVROLET_SILVERADO, + "CHEVROLET EQUINOX 2019": GM.CHEVROLET_EQUINOX, + "CHEVROLET TRAILBLAZER 2021": GM.CHEVROLET_TRAILBLAZER, + "HONDA ACCORD 2018": HONDA.HONDA_ACCORD, + "HONDA CIVIC (BOSCH) 2019": HONDA.HONDA_CIVIC_BOSCH, + "HONDA CIVIC SEDAN 1.6 DIESEL 2019": HONDA.HONDA_CIVIC_BOSCH_DIESEL, + "HONDA CIVIC 2022": HONDA.HONDA_CIVIC_2022, + "HONDA CR-V 2017": HONDA.HONDA_CRV_5G, + "HONDA CR-V HYBRID 2019": HONDA.HONDA_CRV_HYBRID, + "HONDA HR-V 2023": HONDA.HONDA_HRV_3G, + "ACURA RDX 2020": HONDA.ACURA_RDX_3G, + "HONDA INSIGHT 2019": HONDA.HONDA_INSIGHT, + "HONDA E 2020": HONDA.HONDA_E, + "ACURA ILX 2016": HONDA.ACURA_ILX, + "HONDA CR-V 2016": HONDA.HONDA_CRV, + "HONDA CR-V EU 2016": HONDA.HONDA_CRV_EU, + "HONDA FIT 2018": HONDA.HONDA_FIT, + "HONDA FREED 2020": HONDA.HONDA_FREED, + "HONDA HRV 2019": HONDA.HONDA_HRV, + "HONDA ODYSSEY 2018": HONDA.HONDA_ODYSSEY, + "HONDA ODYSSEY CHN 2019": HONDA.HONDA_ODYSSEY_CHN, + "ACURA RDX 2018": HONDA.ACURA_RDX, + "HONDA PILOT 2017": HONDA.HONDA_PILOT, + "HONDA RIDGELINE 2017": HONDA.HONDA_RIDGELINE, + "HONDA CIVIC 2016": HONDA.HONDA_CIVIC, + "HYUNDAI AZERA 6TH GEN": HYUNDAI.HYUNDAI_AZERA_6TH_GEN, + "HYUNDAI AZERA HYBRID 6TH GEN": HYUNDAI.HYUNDAI_AZERA_HEV_6TH_GEN, + "HYUNDAI ELANTRA 2017": HYUNDAI.HYUNDAI_ELANTRA, + "HYUNDAI I30 N LINE 2019 & GT 2018 DCT": HYUNDAI.HYUNDAI_ELANTRA_GT_I30, + "HYUNDAI ELANTRA 2021": HYUNDAI.HYUNDAI_ELANTRA_2021, + "HYUNDAI ELANTRA HYBRID 2021": HYUNDAI.HYUNDAI_ELANTRA_HEV_2021, + "HYUNDAI GENESIS 2015-2016": HYUNDAI.HYUNDAI_GENESIS, + "HYUNDAI IONIQ HYBRID 2017-2019": HYUNDAI.HYUNDAI_IONIQ, + "HYUNDAI IONIQ HYBRID 2020-2022": HYUNDAI.HYUNDAI_IONIQ_HEV_2022, + "HYUNDAI IONIQ ELECTRIC LIMITED 2019": HYUNDAI.HYUNDAI_IONIQ_EV_LTD, + "HYUNDAI IONIQ ELECTRIC 2020": HYUNDAI.HYUNDAI_IONIQ_EV_2020, + "HYUNDAI IONIQ PLUG-IN HYBRID 2019": HYUNDAI.HYUNDAI_IONIQ_PHEV_2019, + "HYUNDAI IONIQ PHEV 2020": HYUNDAI.HYUNDAI_IONIQ_PHEV, + "HYUNDAI KONA 2020": HYUNDAI.HYUNDAI_KONA, + "HYUNDAI KONA ELECTRIC 2019": HYUNDAI.HYUNDAI_KONA_EV, + "HYUNDAI KONA ELECTRIC 2022": HYUNDAI.HYUNDAI_KONA_EV_2022, + "HYUNDAI KONA ELECTRIC 2ND GEN": HYUNDAI.HYUNDAI_KONA_EV_2ND_GEN, + "HYUNDAI KONA HYBRID 2020": HYUNDAI.HYUNDAI_KONA_HEV, + "HYUNDAI SANTA FE 2019": HYUNDAI.HYUNDAI_SANTA_FE, + "HYUNDAI SANTA FE 2022": HYUNDAI.HYUNDAI_SANTA_FE_2022, + "HYUNDAI SANTA FE HYBRID 2022": HYUNDAI.HYUNDAI_SANTA_FE_HEV_2022, + "HYUNDAI SANTA FE PlUG-IN HYBRID 2022": HYUNDAI.HYUNDAI_SANTA_FE_PHEV_2022, + "HYUNDAI SONATA 2020": HYUNDAI.HYUNDAI_SONATA, + "HYUNDAI SONATA 2019": HYUNDAI.HYUNDAI_SONATA_LF, + "HYUNDAI STARIA 4TH GEN": HYUNDAI.HYUNDAI_STARIA_4TH_GEN, + "HYUNDAI TUCSON 2019": HYUNDAI.HYUNDAI_TUCSON, + "HYUNDAI PALISADE 2020": HYUNDAI.HYUNDAI_PALISADE, + "HYUNDAI VELOSTER 2019": HYUNDAI.HYUNDAI_VELOSTER, + "HYUNDAI SONATA HYBRID 2021": HYUNDAI.HYUNDAI_SONATA_HYBRID, + "HYUNDAI IONIQ 5 2022": HYUNDAI.HYUNDAI_IONIQ_5, + "HYUNDAI IONIQ 6 2023": HYUNDAI.HYUNDAI_IONIQ_6, + "HYUNDAI TUCSON 4TH GEN": HYUNDAI.HYUNDAI_TUCSON_4TH_GEN, + "HYUNDAI SANTA CRUZ 1ST GEN": HYUNDAI.HYUNDAI_SANTA_CRUZ_1ST_GEN, + "HYUNDAI CUSTIN 1ST GEN": HYUNDAI.HYUNDAI_CUSTIN_1ST_GEN, + "KIA FORTE E 2018 & GT 2021": HYUNDAI.KIA_FORTE, + "KIA K5 2021": HYUNDAI.KIA_K5_2021, + "KIA K5 HYBRID 2020": HYUNDAI.KIA_K5_HEV_2020, + "KIA K8 HYBRID 1ST GEN": HYUNDAI.KIA_K8_HEV_1ST_GEN, + "KIA NIRO EV 2020": HYUNDAI.KIA_NIRO_EV, + "KIA NIRO EV 2ND GEN": HYUNDAI.KIA_NIRO_EV_2ND_GEN, + "KIA NIRO HYBRID 2019": HYUNDAI.KIA_NIRO_PHEV, + "KIA NIRO PLUG-IN HYBRID 2022": HYUNDAI.KIA_NIRO_PHEV_2022, + "KIA NIRO HYBRID 2021": HYUNDAI.KIA_NIRO_HEV_2021, + "KIA NIRO HYBRID 2ND GEN": HYUNDAI.KIA_NIRO_HEV_2ND_GEN, + "KIA OPTIMA 4TH GEN": HYUNDAI.KIA_OPTIMA_G4, + "KIA OPTIMA 4TH GEN FACELIFT": HYUNDAI.KIA_OPTIMA_G4_FL, + "KIA OPTIMA HYBRID 2017 & SPORTS 2019": HYUNDAI.KIA_OPTIMA_H, + "KIA OPTIMA HYBRID 4TH GEN FACELIFT": HYUNDAI.KIA_OPTIMA_H_G4_FL, + "KIA SELTOS 2021": HYUNDAI.KIA_SELTOS, + "KIA SPORTAGE 5TH GEN": HYUNDAI.KIA_SPORTAGE_5TH_GEN, + "KIA SORENTO GT LINE 2018": HYUNDAI.KIA_SORENTO, + "KIA SORENTO 4TH GEN": HYUNDAI.KIA_SORENTO_4TH_GEN, + "KIA SORENTO HYBRID 4TH GEN": HYUNDAI.KIA_SORENTO_HEV_4TH_GEN, + "KIA STINGER GT2 2018": HYUNDAI.KIA_STINGER, + "KIA STINGER 2022": HYUNDAI.KIA_STINGER_2022, + "KIA CEED INTRO ED 2019": HYUNDAI.KIA_CEED, + "KIA EV6 2022": HYUNDAI.KIA_EV6, + "KIA CARNIVAL 4TH GEN": HYUNDAI.KIA_CARNIVAL_4TH_GEN, + "GENESIS GV60 ELECTRIC 1ST GEN": HYUNDAI.GENESIS_GV60_EV_1ST_GEN, + "GENESIS G70 2018": HYUNDAI.GENESIS_G70, + "GENESIS G70 2020": HYUNDAI.GENESIS_G70_2020, + "GENESIS GV70 1ST GEN": HYUNDAI.GENESIS_GV70_1ST_GEN, + "GENESIS G80 2017": HYUNDAI.GENESIS_G80, + "GENESIS G90 2017": HYUNDAI.GENESIS_G90, + "GENESIS GV80 2023": HYUNDAI.GENESIS_GV80, + "MAZDA CX-5": MAZDA.MAZDA_CX5, + "MAZDA CX-9": MAZDA.MAZDA_CX9, + "MAZDA 3": MAZDA.MAZDA_3, + "MAZDA 6": MAZDA.MAZDA_6, + "MAZDA CX-9 2021": MAZDA.MAZDA_CX9_2021, + "MAZDA CX-5 2022": MAZDA.MAZDA_CX5_2022, + "NISSAN X-TRAIL 2017": NISSAN.NISSAN_XTRAIL, + "NISSAN LEAF 2018": NISSAN.NISSAN_LEAF, + "NISSAN ROGUE 2019": NISSAN.NISSAN_ROGUE, + "NISSAN ALTIMA 2020": NISSAN.NISSAN_ALTIMA, + "SUBARU ASCENT LIMITED 2019": SUBARU.SUBARU_ASCENT, + "SUBARU OUTBACK 6TH GEN": SUBARU.SUBARU_OUTBACK, + "SUBARU LEGACY 7TH GEN": SUBARU.SUBARU_LEGACY, + "SUBARU IMPREZA LIMITED 2019": SUBARU.SUBARU_IMPREZA, + "SUBARU IMPREZA SPORT 2020": SUBARU.SUBARU_IMPREZA_2020, + "SUBARU CROSSTREK HYBRID 2020": SUBARU.SUBARU_CROSSTREK_HYBRID, + "SUBARU FORESTER 2019": SUBARU.SUBARU_FORESTER, + "SUBARU FORESTER HYBRID 2020": SUBARU.SUBARU_FORESTER_HYBRID, + "SUBARU FORESTER 2017 - 2018": SUBARU.SUBARU_FORESTER_PREGLOBAL, + "SUBARU LEGACY 2015 - 2018": SUBARU.SUBARU_LEGACY_PREGLOBAL, + "SUBARU OUTBACK 2015 - 2017": SUBARU.SUBARU_OUTBACK_PREGLOBAL, + "SUBARU OUTBACK 2018 - 2019": SUBARU.SUBARU_OUTBACK_PREGLOBAL_2018, + "SUBARU FORESTER 2022": SUBARU.SUBARU_FORESTER_2022, + "SUBARU OUTBACK 7TH GEN": SUBARU.SUBARU_OUTBACK_2023, + "SUBARU ASCENT 2023": SUBARU.SUBARU_ASCENT_2023, + 'TESLA AP1 MODEL S': TESLA.TESLA_AP1_MODELS, + 'TESLA AP2 MODEL S': TESLA.TESLA_AP2_MODELS, + 'TESLA MODEL S RAVEN': TESLA.TESLA_MODELS_RAVEN, + "TOYOTA ALPHARD 2020": TOYOTA.TOYOTA_ALPHARD_TSS2, + "TOYOTA AVALON 2016": TOYOTA.TOYOTA_AVALON, + "TOYOTA AVALON 2019": TOYOTA.TOYOTA_AVALON_2019, + "TOYOTA AVALON 2022": TOYOTA.TOYOTA_AVALON_TSS2, + "TOYOTA CAMRY 2018": TOYOTA.TOYOTA_CAMRY, + "TOYOTA CAMRY 2021": TOYOTA.TOYOTA_CAMRY_TSS2, + "TOYOTA C-HR 2018": TOYOTA.TOYOTA_CHR, + "TOYOTA C-HR 2021": TOYOTA.TOYOTA_CHR_TSS2, + "TOYOTA COROLLA 2017": TOYOTA.TOYOTA_COROLLA, + "TOYOTA COROLLA TSS2 2019": TOYOTA.TOYOTA_COROLLA_TSS2, + "TOYOTA HIGHLANDER 2017": TOYOTA.TOYOTA_HIGHLANDER, + "TOYOTA HIGHLANDER 2020": TOYOTA.TOYOTA_HIGHLANDER_TSS2, + "TOYOTA PRIUS 2017": TOYOTA.TOYOTA_PRIUS, + "TOYOTA PRIUS v 2017": TOYOTA.TOYOTA_PRIUS_V, + "TOYOTA PRIUS TSS2 2021": TOYOTA.TOYOTA_PRIUS_TSS2, + "TOYOTA RAV4 2017": TOYOTA.TOYOTA_RAV4, + "TOYOTA RAV4 HYBRID 2017": TOYOTA.TOYOTA_RAV4H, + "TOYOTA RAV4 2019": TOYOTA.TOYOTA_RAV4_TSS2, + "TOYOTA RAV4 2022": TOYOTA.TOYOTA_RAV4_TSS2_2022, + "TOYOTA RAV4 2023": TOYOTA.TOYOTA_RAV4_TSS2_2023, + "TOYOTA MIRAI 2021": TOYOTA.TOYOTA_MIRAI, + "TOYOTA SIENNA 2018": TOYOTA.TOYOTA_SIENNA, + "LEXUS CT HYBRID 2018": TOYOTA.LEXUS_CTH, + "LEXUS ES 2018": TOYOTA.LEXUS_ES, + "LEXUS ES 2019": TOYOTA.LEXUS_ES_TSS2, + "LEXUS IS 2018": TOYOTA.LEXUS_IS, + "LEXUS IS 2023": TOYOTA.LEXUS_IS_TSS2, + "LEXUS NX 2018": TOYOTA.LEXUS_NX, + "LEXUS NX 2020": TOYOTA.LEXUS_NX_TSS2, + "LEXUS LC 2024": TOYOTA.LEXUS_LC_TSS2, + "LEXUS RC 2020": TOYOTA.LEXUS_RC, + "LEXUS RX 2016": TOYOTA.LEXUS_RX, + "LEXUS RX 2020": TOYOTA.LEXUS_RX_TSS2, + "LEXUS GS F 2016": TOYOTA.LEXUS_GS_F, + "VOLKSWAGEN ARTEON 1ST GEN": VW.VOLKSWAGEN_ARTEON_MK1, + "VOLKSWAGEN ATLAS 1ST GEN": VW.VOLKSWAGEN_ATLAS_MK1, + "VOLKSWAGEN CADDY 3RD GEN": VW.VOLKSWAGEN_CADDY_MK3, + "VOLKSWAGEN CRAFTER 2ND GEN": VW.VOLKSWAGEN_CRAFTER_MK2, + "VOLKSWAGEN GOLF 7TH GEN": VW.VOLKSWAGEN_GOLF_MK7, + "VOLKSWAGEN JETTA 7TH GEN": VW.VOLKSWAGEN_JETTA_MK7, + "VOLKSWAGEN PASSAT 8TH GEN": VW.VOLKSWAGEN_PASSAT_MK8, + "VOLKSWAGEN PASSAT NMS": VW.VOLKSWAGEN_PASSAT_NMS, + "VOLKSWAGEN POLO 6TH GEN": VW.VOLKSWAGEN_POLO_MK6, + "VOLKSWAGEN SHARAN 2ND GEN": VW.VOLKSWAGEN_SHARAN_MK2, + "VOLKSWAGEN TAOS 1ST GEN": VW.VOLKSWAGEN_TAOS_MK1, + "VOLKSWAGEN T-CROSS 1ST GEN": VW.VOLKSWAGEN_TCROSS_MK1, + "VOLKSWAGEN TIGUAN 2ND GEN": VW.VOLKSWAGEN_TIGUAN_MK2, + "VOLKSWAGEN TOURAN 2ND GEN": VW.VOLKSWAGEN_TOURAN_MK2, + "VOLKSWAGEN TRANSPORTER T6.1": VW.VOLKSWAGEN_TRANSPORTER_T61, + "VOLKSWAGEN T-ROC 1ST GEN": VW.VOLKSWAGEN_TROC_MK1, + "AUDI A3 3RD GEN": VW.AUDI_A3_MK3, + "AUDI Q2 1ST GEN": VW.AUDI_Q2_MK1, + "AUDI Q3 2ND GEN": VW.AUDI_Q3_MK2, + "SEAT ATECA 1ST GEN": VW.SEAT_ATECA_MK1, + "SEAT LEON 3RD GEN": VW.SEAT_LEON_MK3, + "SKODA FABIA 4TH GEN": VW.SKODA_FABIA_MK4, + "SKODA KAMIQ 1ST GEN": VW.SKODA_KAMIQ_MK1, + "SKODA KAROQ 1ST GEN": VW.SKODA_KAROQ_MK1, + "SKODA KODIAQ 1ST GEN": VW.SKODA_KODIAQ_MK1, + "SKODA OCTAVIA 3RD GEN": VW.SKODA_OCTAVIA_MK3, + "SKODA SCALA 1ST GEN": VW.SKODA_SCALA_MK1, + "SKODA SUPERB 3RD GEN": VW.SKODA_SUPERB_MK3, +} diff --git a/selfdrive/car/ford/carcontroller.py b/selfdrive/car/ford/carcontroller.py index 390325a8ec..47082fb56f 100644 --- a/selfdrive/car/ford/carcontroller.py +++ b/selfdrive/car/ford/carcontroller.py @@ -35,6 +35,7 @@ class CarController(CarControllerBase): self.main_on_last = False self.lkas_enabled_last = False self.steer_alert_last = False + self.lead_distance_bars_last = None def update(self, CC, CS, now_nanos): can_sends = [] @@ -73,7 +74,7 @@ class CarController(CarControllerBase): if self.CP.flags & FordFlags.CANFD: # TODO: extended mode mode = 1 if CC.latActive else 0 - counter = (self.frame // CarControllerParams.STEER_STEP) % 0xF + counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10 can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter)) else: can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -apply_curvature, 0.)) @@ -98,15 +99,19 @@ class CarController(CarControllerBase): # send lkas ui msg at 1Hz or if ui state changes if (self.frame % CarControllerParams.LKAS_UI_STEP) == 0 or send_ui: can_sends.append(fordcan.create_lkas_ui_msg(self.packer, self.CAN, main_on, CC.latActive, steer_alert, hud_control, CS.lkas_status_stock_values)) + # send acc ui msg at 5Hz or if ui state changes + if hud_control.leadDistanceBars != self.lead_distance_bars_last: + send_ui = True if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui: can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive, - fcw_alert, CS.out.cruiseState.standstill, hud_control, - CS.acc_tja_status_stock_values)) + fcw_alert, CS.out.cruiseState.standstill, hud_control, + CS.acc_tja_status_stock_values)) self.main_on_last = main_on self.lkas_enabled_last = CC.latActive self.steer_alert_last = steer_alert + self.lead_distance_bars_last = hud_control.leadDistanceBars new_actuators = actuators.copy() new_actuators.curvature = self.apply_curvature_last diff --git a/selfdrive/car/ford/fingerprints.py b/selfdrive/car/ford/fingerprints.py index a5d465849a..32d331b2db 100644 --- a/selfdrive/car/ford/fingerprints.py +++ b/selfdrive/car/ford/fingerprints.py @@ -4,23 +4,26 @@ from openpilot.selfdrive.car.ford.values import CAR Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.BRONCO_SPORT_MK1: { + CAR.FORD_BRONCO_SPORT_MK1: { (Ecu.eps, 0x730, None): [ b'LX6C-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6C-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LX6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.abs, 0x760, None): [ b'LX6C-2D053-RD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6C-2D053-RE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'LX6C-2D053-RF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'LB5T-14D049-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x706, None): [ b'M1PT-14F397-AC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'M1PT-14F397-AD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.ESCAPE_MK4: { + CAR.FORD_ESCAPE_MK4: { (Ecu.eps, 0x730, None): [ b'LX6C-14D003-AF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LX6C-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -43,7 +46,7 @@ FW_VERSIONS = { b'LV4T-14F397-GG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.EXPLORER_MK6: { + CAR.FORD_EXPLORER_MK6: { (Ecu.eps, 0x730, None): [ b'L1MC-14D003-AJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'L1MC-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -71,7 +74,7 @@ FW_VERSIONS = { b'LC5T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.F_150_MK14: { + CAR.FORD_F_150_MK14: { (Ecu.eps, 0x730, None): [ b'ML3V-14D003-BC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], @@ -82,10 +85,11 @@ FW_VERSIONS = { b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdCamera, 0x706, None): [ + b'ML3T-14H102-ABR\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PJ6T-14H102-ABJ\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.F_150_LIGHTNING_MK1: { + CAR.FORD_F_150_LIGHTNING_MK1: { (Ecu.abs, 0x760, None): [ b'PL38-2D053-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], @@ -96,7 +100,7 @@ FW_VERSIONS = { b'ML3T-14D049-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.MUSTANG_MACH_E_MK1: { + CAR.FORD_MUSTANG_MACH_E_MK1: { (Ecu.eps, 0x730, None): [ b'LJ9C-14D003-AM\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'LJ9C-14D003-CC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -111,7 +115,7 @@ FW_VERSIONS = { b'ML3T-14H102-ABS\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.FOCUS_MK4: { + CAR.FORD_FOCUS_MK4: { (Ecu.eps, 0x730, None): [ b'JX6C-14D003-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], @@ -125,7 +129,7 @@ FW_VERSIONS = { b'JX7T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.MAVERICK_MK1: { + CAR.FORD_MAVERICK_MK1: { (Ecu.eps, 0x730, None): [ b'NZ6C-14D003-AL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], @@ -133,6 +137,7 @@ FW_VERSIONS = { b'NZ6C-2D053-AG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PZ6C-2D053-ED\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PZ6C-2D053-EE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PZ6C-2D053-EF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x764, None): [ b'NZ6T-14D049-AA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', diff --git a/selfdrive/car/ford/fordcan.py b/selfdrive/car/ford/fordcan.py index c5ef0900f3..939084c4a0 100644 --- a/selfdrive/car/ford/fordcan.py +++ b/selfdrive/car/ford/fordcan.py @@ -212,7 +212,7 @@ def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw "AccFllwMde_B_Dsply": 1 if hud_control.leadVisible else 0, # Lead indicator "AccStopMde_B_Dsply": 1 if standstill else 0, "AccWarn_D_Dsply": 0, # ACC warning - "AccTGap_D_Dsply": 4, # Fixed time gap in UI + "AccTGap_D_Dsply": hud_control.leadDistanceBars + 1, # Time gap }) # Forwards FCW alert from IPMA diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index ed8b010491..7dca458083 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -71,6 +71,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index add40368be..d1e6686ea0 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -1,10 +1,11 @@ -from dataclasses import dataclass, field +import copy +from dataclasses import dataclass, field, replace from enum import Enum, IntFlag import panda.python.uds as uds from cereal import car from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, dbc_dict, DbcDict, PlatformConfig, Platforms -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column, \ +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \ Device from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 @@ -58,12 +59,14 @@ class Footnote(Enum): @dataclass -class FordCarInfo(CarInfo): +class FordCarDocs(CarDocs): package: str = "Co-Pilot360 Assist+" + hybrid: bool = False + plug_in_hybrid: bool = False def init_make(self, CP: car.CarParams): harness = CarHarness.ford_q4 if CP.flags & FordFlags.CANFD else CarHarness.ford_q3 - if CP.carFingerprint in (CAR.BRONCO_SPORT_MK1, CAR.MAVERICK_MK1, CAR.F_150_MK14, CAR.F_150_LIGHTNING_MK1): + if CP.carFingerprint in (CAR.FORD_BRONCO_SPORT_MK1, CAR.FORD_MAVERICK_MK1, CAR.FORD_F_150_MK14, CAR.FORD_F_150_LIGHTNING_MK1): self.car_parts = CarParts([Device.threex_angled_mount, harness]) else: self.car_parts = CarParts([Device.threex, harness]) @@ -73,6 +76,15 @@ class FordCarInfo(CarInfo): class FordPlatformConfig(PlatformConfig): dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', RADAR.DELPHI_MRR)) + def init(self): + for car_docs in list(self.car_docs): + if car_docs.hybrid: + name = f"{car_docs.make} {car_docs.model} Hybrid {car_docs.years}" + self.car_docs.append(replace(copy.deepcopy(car_docs), name=name)) + if car_docs.plug_in_hybrid: + name = f"{car_docs.make} {car_docs.model} Plug-in Hybrid {car_docs.years}" + self.car_docs.append(replace(copy.deepcopy(car_docs), name=name)) + @dataclass class FordCANFDPlatformConfig(FordPlatformConfig): @@ -84,67 +96,45 @@ class FordCANFDPlatformConfig(FordPlatformConfig): class CAR(Platforms): - BRONCO_SPORT_MK1 = FordPlatformConfig( - "FORD BRONCO SPORT 1ST GEN", - FordCarInfo("Ford Bronco Sport 2021-22"), + FORD_BRONCO_SPORT_MK1 = FordPlatformConfig( + [FordCarDocs("Ford Bronco Sport 2021-23")], CarSpecs(mass=1625, wheelbase=2.67, steerRatio=17.7), ) - ESCAPE_MK4 = FordPlatformConfig( - "FORD ESCAPE 4TH GEN", + FORD_ESCAPE_MK4 = FordPlatformConfig( [ - FordCarInfo("Ford Escape 2020-22"), - FordCarInfo("Ford Escape Hybrid 2020-22"), - FordCarInfo("Ford Escape Plug-in Hybrid 2020-22"), - FordCarInfo("Ford Kuga 2020-22", "Adaptive Cruise Control with Lane Centering"), - FordCarInfo("Ford Kuga Hybrid 2020-22", "Adaptive Cruise Control with Lane Centering"), - FordCarInfo("Ford Kuga Plug-in Hybrid 2020-22", "Adaptive Cruise Control with Lane Centering"), + FordCarDocs("Ford Escape 2020-22", hybrid=True, plug_in_hybrid=True), + FordCarDocs("Ford Kuga 2020-22", "Adaptive Cruise Control with Lane Centering", hybrid=True, plug_in_hybrid=True), ], CarSpecs(mass=1750, wheelbase=2.71, steerRatio=16.7), ) - EXPLORER_MK6 = FordPlatformConfig( - "FORD EXPLORER 6TH GEN", + FORD_EXPLORER_MK6 = FordPlatformConfig( [ - FordCarInfo("Ford Explorer 2020-23"), - FordCarInfo("Ford Explorer Hybrid 2020-23"), # Limited and Platinum only - FordCarInfo("Lincoln Aviator 2020-23", "Co-Pilot360 Plus"), - FordCarInfo("Lincoln Aviator Plug-in Hybrid 2020-23", "Co-Pilot360 Plus"), # Grand Touring only + FordCarDocs("Ford Explorer 2020-23", hybrid=True), # Hybrid: Limited and Platinum only + FordCarDocs("Lincoln Aviator 2020-23", "Co-Pilot360 Plus", plug_in_hybrid=True), # Hybrid: Grand Touring only ], CarSpecs(mass=2050, wheelbase=3.025, steerRatio=16.8), ) - F_150_MK14 = FordCANFDPlatformConfig( - "FORD F-150 14TH GEN", - [ - FordCarInfo("Ford F-150 2023", "Co-Pilot360 Active 2.0"), - FordCarInfo("Ford F-150 Hybrid 2023", "Co-Pilot360 Active 2.0"), - ], + FORD_F_150_MK14 = FordCANFDPlatformConfig( + [FordCarDocs("Ford F-150 2022-23", "Co-Pilot360 Active 2.0", hybrid=True)], CarSpecs(mass=2000, wheelbase=3.69, steerRatio=17.0), ) - F_150_LIGHTNING_MK1 = FordCANFDPlatformConfig( - "FORD F-150 LIGHTNING 1ST GEN", - FordCarInfo("Ford F-150 Lightning 2021-23", "Co-Pilot360 Active 2.0"), + FORD_F_150_LIGHTNING_MK1 = FordCANFDPlatformConfig( + [FordCarDocs("Ford F-150 Lightning 2021-23", "Co-Pilot360 Active 2.0")], CarSpecs(mass=2948, wheelbase=3.70, steerRatio=16.9), ) - FOCUS_MK4 = FordPlatformConfig( - "FORD FOCUS 4TH GEN", - [ - FordCarInfo("Ford Focus 2018", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS]), - FordCarInfo("Ford Focus Hybrid 2018", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS]), # mHEV only - ], + FORD_FOCUS_MK4 = FordPlatformConfig( + [FordCarDocs("Ford Focus 2018", "Adaptive Cruise Control with Lane Centering", footnotes=[Footnote.FOCUS], hybrid=True)], # mHEV only CarSpecs(mass=1350, wheelbase=2.7, steerRatio=15.0), ) - MAVERICK_MK1 = FordPlatformConfig( - "FORD MAVERICK 1ST GEN", + FORD_MAVERICK_MK1 = FordPlatformConfig( [ - FordCarInfo("Ford Maverick 2022", "LARIAT Luxury"), - FordCarInfo("Ford Maverick Hybrid 2022", "LARIAT Luxury"), - FordCarInfo("Ford Maverick 2023", "Co-Pilot360 Assist"), - FordCarInfo("Ford Maverick Hybrid 2023", "Co-Pilot360 Assist"), + FordCarDocs("Ford Maverick 2022", "LARIAT Luxury", hybrid=True), + FordCarDocs("Ford Maverick 2023-24", "Co-Pilot360 Assist", hybrid=True), ], CarSpecs(mass=1650, wheelbase=3.076, steerRatio=17.0), ) - MUSTANG_MACH_E_MK1 = FordCANFDPlatformConfig( - "FORD MUSTANG MACH-E 1ST GEN", - FordCarInfo("Ford Mustang Mach-E 2021-23", "Co-Pilot360 Active 2.0"), + FORD_MUSTANG_MACH_E_MK1 = FordCANFDPlatformConfig( + [FordCarDocs("Ford Mustang Mach-E 2021-23", "Co-Pilot360 Active 2.0")], CarSpecs(mass=2200, wheelbase=2.984, steerRatio=17.0), # TODO: check steer ratio ) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index e010c56536..f8d747029b 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -118,7 +118,7 @@ class CarController(CarControllerBase): # Send dashboard UI commands (ACC status) send_fcw = hud_alert == VisualAlert.fcw can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, CanBus.POWERTRAIN, CC.enabled, - hud_v_cruise * CV.MS_TO_KPH, hud_control.leadVisible, send_fcw)) + hud_v_cruise * CV.MS_TO_KPH, hud_control, send_fcw)) # Radar needs to know current speed and yaw rate (50hz), # and that ADAS is alive (10hz) diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index c3d061de78..a1129c59c8 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -26,11 +26,16 @@ class CarState(CarStateBase): self.cam_lka_steering_cmd_counter = 0 self.buttons_counter = 0 + self.prev_distance_button = 0 + self.distance_button = 0 + def update(self, pt_cp, cam_cp, loopback_cp): ret = car.CarState.new_message() self.prev_cruise_buttons = self.cruise_buttons + self.prev_distance_button = self.distance_button self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"] + self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"] self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"] self.pscm_status = copy.copy(pt_cp.vl["PSCMStatus"]) # This is to avoid a fault where you engage while still moving backwards after shifting to D. diff --git a/selfdrive/car/gm/fingerprints.py b/selfdrive/car/gm/fingerprints.py index 73a205a250..3752fbb8d3 100644 --- a/selfdrive/car/gm/fingerprints.py +++ b/selfdrive/car/gm/fingerprints.py @@ -9,7 +9,7 @@ FINGERPRINTS = { CAR.HOLDEN_ASTRA: [{ 190: 8, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 8, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 8, 398: 8, 401: 8, 413: 8, 417: 8, 419: 8, 422: 1, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 8, 455: 7, 456: 8, 458: 5, 479: 8, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 8, 501: 8, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 647: 5, 707: 8, 715: 8, 723: 8, 753: 5, 761: 7, 806: 1, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1009: 8, 1011: 6, 1017: 8, 1019: 3, 1020: 8, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 8, 1280: 4, 1300: 8, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1908: 7, 1912: 7, 1919: 7 }], - CAR.VOLT: [{ + CAR.CHEVROLET_VOLT: [{ 170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 289: 8, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 647: 3, 707: 8, 711: 6, 715: 8, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 961: 8, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1928: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 }, { @@ -27,31 +27,31 @@ FINGERPRINTS = { CAR.CADILLAC_ATS: [{ 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 368: 3, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 462: 4, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 491: 2, 493: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 528: 5, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 719: 5, 723: 2, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 882: 8, 890: 1, 892: 2, 893: 2, 894: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1241: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1916: 7, 1917: 7, 1918: 7, 1919: 7, 1920: 7, 1930: 7, 2016: 8, 2024: 8 }], - CAR.MALIBU: [{ + CAR.CHEVROLET_MALIBU: [{ 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1930: 7, 2016: 8, 2024: 8 }], - CAR.ACADIA: [{ + CAR.GMC_ACADIA: [{ 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 7, 368: 8, 381: 8, 384: 8, 386: 8, 388: 8, 393: 8, 398: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 458: 8, 460: 4, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 512: 3, 530: 8, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 568: 2, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 801: 8, 803: 8, 804: 3, 805: 8, 832: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1912: 7, 1914: 7, 1918: 7, 1919: 7, 1920: 7, 1930: 7 }, { 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 313: 8, 320: 3, 322: 7, 328: 1, 338: 6, 340: 6, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 393: 8, 398: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1914: 7, 1919: 7, 1920: 7, 1930: 7, 2016: 8, 2024: 8 }], - CAR.ESCALADE: [{ + CAR.CADILLAC_ESCALADE: [{ 170: 8, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 4, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 460: 5, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 719: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1906: 7, 1907: 7, 1912: 7, 1914: 7, 1917: 7, 1918: 7, 1919: 7, 1920: 7, 1930: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8 }], - CAR.ESCALADE_ESV: [{ + CAR.CADILLAC_ESCALADE_ESV: [{ 309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8 }], - CAR.ESCALADE_ESV_2019: [{ + CAR.CADILLAC_ESCALADE_ESV_2019: [{ 715: 8, 840: 5, 717: 5, 869: 4, 880: 6, 289: 8, 454: 8, 842: 5, 460: 5, 463: 3, 801: 8, 170: 8, 190: 6, 241: 6, 201: 8, 417: 7, 211: 2, 419: 1, 398: 8, 426: 7, 487: 8, 442: 8, 451: 8, 452: 8, 453: 6, 479: 3, 311: 8, 500: 6, 647: 6, 193: 8, 707: 8, 197: 8, 209: 7, 199: 4, 455: 7, 313: 8, 481: 7, 485: 8, 489: 8, 249: 8, 393: 7, 407: 7, 413: 8, 422: 4, 431: 8, 501: 8, 499: 3, 810: 8, 508: 8, 381: 8, 462: 4, 532: 6, 562: 8, 386: 8, 761: 7, 573: 1, 554: 3, 719: 5, 560: 8, 1279: 4, 388: 8, 288: 5, 1005: 6, 497: 8, 844: 8, 961: 8, 967: 4, 977: 8, 979: 8, 985: 5, 1001: 8, 1017: 8, 1019: 2, 1020: 8, 1217: 8, 510: 8, 866: 4, 304: 1, 969: 8, 384: 4, 1033: 7, 1009: 8, 1034: 7, 1296: 4, 1930: 7, 1105: 5, 1013: 5, 1225: 7, 1919: 7, 320: 3, 534: 2, 352: 5, 298: 8, 1223: 2, 1233: 8, 608: 8, 1265: 8, 609: 6, 1267: 1, 1417: 8, 610: 6, 1906: 7, 611: 6, 612: 8, 613: 8, 208: 8, 564: 5, 309: 8, 1221: 5, 1280: 4, 1249: 8, 1907: 7, 1257: 6, 1300: 8, 1920: 7, 563: 5, 1322: 6, 1323: 4, 1328: 4, 1917: 7, 328: 1, 1912: 7, 1914: 7, 804: 3, 1918: 7 }], - CAR.BOLT_EUV: [{ + CAR.CHEVROLET_BOLT_EUV: [{ 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 }], - CAR.SILVERADO: [{ + CAR.CHEVROLET_SILVERADO: [{ 190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 }], - CAR.EQUINOX: [{ + CAR.CHEVROLET_EQUINOX: [{ 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 510: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 }, { diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index bd1e29ce3b..e833e77636 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -76,7 +76,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s mode = 0x1 # TODO: Understand this better. Volts and ICE Camera ACC cars are 0x1 when enabled with no brake - if enabled and CP.carFingerprint in (CAR.BOLT_EUV,): + if enabled and CP.carFingerprint in (CAR.CHEVROLET_BOLT_EUV,): mode = 0x9 if apply_brake > 0: @@ -102,17 +102,17 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) -def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, lead_car_in_sight, fcw): +def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, hud_control, fcw): target_speed = min(target_speed_kph, 255) values = { "ACCAlwaysOne": 1, "ACCResumeButton": 0, "ACCSpeedSetpoint": target_speed, - "ACCGapLevel": 3 * enabled, # 3 "far", 0 "inactive" + "ACCGapLevel": hud_control.leadDistanceBars * enabled, # 3 "far", 0 "inactive" "ACCCmdActive": enabled, "ACCAlwaysOne2": 1, - "ACCLeadCar": lead_car_in_sight, + "ACCLeadCar": hud_control.leadVisible, "FCWAlert": 0x3 if fcw else 0 } diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 76f6a6b0a6..358bc9e5ba 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -22,9 +22,9 @@ BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.D NON_LINEAR_TORQUE_PARAMS = { - CAR.BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], - CAR.ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772], - CAR.SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122] + CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], + CAR.GMC_ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772], + CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122] } NEURAL_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/neural_ff_weights.json') @@ -43,7 +43,7 @@ class CarInterface(CarInterfaceBase): return 0.10006696 * sigmoid * (v_ego + 3.12485927) def get_steer_feedforward_function(self): - if self.CP.carFingerprint == CAR.VOLT: + if self.CP.carFingerprint == CAR.CHEVROLET_VOLT: return self.get_steer_feedforward_volt else: return CarInterfaceBase.get_steer_feedforward_default @@ -74,7 +74,7 @@ class CarInterface(CarInterfaceBase): return float(self.neural_ff_model.predict(inputs)) + friction def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType: - if self.CP.carFingerprint == CAR.BOLT_EUV: + if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_EUV: self.neural_ff_model = NanoFFModel(NEURAL_PARAMS_PATH, self.CP.carFingerprint) return self.torque_from_lateral_accel_neural elif self.CP.carFingerprint in NON_LINEAR_TORQUE_PARAMS: @@ -137,7 +137,7 @@ class CarInterface(CarInterfaceBase): # These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars likely still work fine. Once a user confirms each car works and a test route is # added to selfdrive/car/tests/routes.py, we can remove it from this list. - ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL} or \ + ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.CHEVROLET_MALIBU, CAR.BUICK_REGAL} or \ (ret.networkLocation == NetworkLocation.gateway and ret.radarUnavailable) # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. @@ -150,7 +150,7 @@ class CarInterface(CarInterfaceBase): ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz ret.longitudinalActuatorDelayUpperBound = 0.5 # large delay to initially start braking - if candidate == CAR.VOLT: + if candidate == CAR.CHEVROLET_VOLT: ret.lateralTuning.pid.kpBP = [0., 40.] ret.lateralTuning.pid.kpV = [0., 0.17] ret.lateralTuning.pid.kiBP = [0.] @@ -158,7 +158,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_volt() ret.steerActuatorDelay = 0.2 - elif candidate == CAR.ACADIA: + elif candidate == CAR.GMC_ACADIA: ret.minEnableSpeed = -1. # engage speed is decided by pcm ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) @@ -166,14 +166,14 @@ class CarInterface(CarInterfaceBase): elif candidate == CAR.BUICK_LACROSSE: CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate == CAR.ESCALADE: + elif candidate == CAR.CADILLAC_ESCALADE: ret.minEnableSpeed = -1. # engage speed is decided by pcm CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate in (CAR.ESCALADE_ESV, CAR.ESCALADE_ESV_2019): + elif candidate in (CAR.CADILLAC_ESCALADE_ESV, CAR.CADILLAC_ESCALADE_ESV_2019): ret.minEnableSpeed = -1. # engage speed is decided by pcm - if candidate == CAR.ESCALADE_ESV: + if candidate == CAR.CADILLAC_ESCALADE_ESV: ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[10., 41.0], [10., 41.0]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.13, 0.24], [0.01, 0.02]] ret.lateralTuning.pid.kf = 0.000045 @@ -181,11 +181,11 @@ class CarInterface(CarInterfaceBase): ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate == CAR.BOLT_EUV: + elif candidate == CAR.CHEVROLET_BOLT_EUV: ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate == CAR.SILVERADO: + elif candidate == CAR.CHEVROLET_SILVERADO: # On the Bolt, the ECM and camera independently check that you are either above 5 kph or at a stop # with foot on brake to allow engagement, but this platform only has that check in the camera. # TODO: check if this is split by EV/ICE with more platforms in the future @@ -193,10 +193,10 @@ class CarInterface(CarInterfaceBase): ret.minEnableSpeed = -1. CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate == CAR.EQUINOX: + elif candidate == CAR.CHEVROLET_EQUINOX: CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - elif candidate == CAR.TRAILBLAZER: + elif candidate == CAR.CHEVROLET_TRAILBLAZER: ret.steerActuatorDelay = 0.2 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) @@ -208,8 +208,12 @@ class CarInterface(CarInterfaceBase): # Don't add event if transitioning from INIT, unless it's to an actual button if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT: - ret.buttonEvents = create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, - unpressed_btn=CruiseButtons.UNPRESS) + ret.buttonEvents = [ + *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, + unpressed_btn=CruiseButtons.UNPRESS), + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, + {1: ButtonType.gapAdjustCruise}) + ] # The ECM allows enabling on falling edge of set, but only rising edge of resume events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low, @@ -233,6 +237,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/gm/tests/test_gm.py b/selfdrive/car/gm/tests/test_gm.py index 2aea5b231b..9b56cfdf08 100755 --- a/selfdrive/car/gm/tests/test_gm.py +++ b/selfdrive/car/gm/tests/test_gm.py @@ -14,11 +14,11 @@ class TestGMFingerprint(unittest.TestCase): self.assertGreater(len(fingerprints), 0) # Trailblazer is in dashcam - if car_model != CAR.TRAILBLAZER: + if car_model != CAR.CHEVROLET_TRAILBLAZER: self.assertTrue(all(len(finger) for finger in fingerprints)) # The camera can sometimes be communicating on startup - if car_model in CAMERA_ACC_CAR - {CAR.TRAILBLAZER}: + if car_model in CAMERA_ACC_CAR - {CAR.CHEVROLET_TRAILBLAZER}: for finger in fingerprints: for required_addr in (CAMERA_DIAGNOSTIC_ADDRESS, CAMERA_DIAGNOSTIC_ADDRESS + GM_RX_OFFSET): self.assertEqual(finger.get(required_addr), 8, required_addr) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 5401963ee6..46d15431ca 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -3,7 +3,7 @@ from enum import Enum from cereal import car from openpilot.selfdrive.car import dbc_dict, PlatformConfig, DbcDict, Platforms, CarSpecs -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -68,7 +68,7 @@ class Footnote(Enum): @dataclass -class GMCarInfo(CarInfo): +class GMCarDocs(CarDocs): package: str = "Adaptive Cruise Control (ACC)" def init_make(self, CP: car.CarParams): @@ -91,79 +91,65 @@ class GMPlatformConfig(PlatformConfig): class CAR(Platforms): HOLDEN_ASTRA = GMPlatformConfig( - "HOLDEN ASTRA RS-V BK 2017", - GMCarInfo("Holden Astra 2017"), + [GMCarDocs("Holden Astra 2017")], GMCarSpecs(mass=1363, wheelbase=2.662, steerRatio=15.7, centerToFrontRatio=0.4), ) - VOLT = GMPlatformConfig( - "CHEVROLET VOLT PREMIER 2017", - GMCarInfo("Chevrolet Volt 2017-18", min_enable_speed=0, video_link="https://youtu.be/QeMCN_4TFfQ"), + CHEVROLET_VOLT = GMPlatformConfig( + [GMCarDocs("Chevrolet Volt 2017-18", min_enable_speed=0, video_link="https://youtu.be/QeMCN_4TFfQ")], GMCarSpecs(mass=1607, wheelbase=2.69, steerRatio=17.7, centerToFrontRatio=0.45, tireStiffnessFactor=0.469), ) CADILLAC_ATS = GMPlatformConfig( - "CADILLAC ATS Premium Performance 2018", - GMCarInfo("Cadillac ATS Premium Performance 2018"), + [GMCarDocs("Cadillac ATS Premium Performance 2018")], GMCarSpecs(mass=1601, wheelbase=2.78, steerRatio=15.3), ) - MALIBU = GMPlatformConfig( - "CHEVROLET MALIBU PREMIER 2017", - GMCarInfo("Chevrolet Malibu Premier 2017"), + CHEVROLET_MALIBU = GMPlatformConfig( + [GMCarDocs("Chevrolet Malibu Premier 2017")], GMCarSpecs(mass=1496, wheelbase=2.83, steerRatio=15.8, centerToFrontRatio=0.4), ) - ACADIA = GMPlatformConfig( - "GMC ACADIA DENALI 2018", - GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), + GMC_ACADIA = GMPlatformConfig( + [GMCarDocs("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo")], GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4), ) BUICK_LACROSSE = GMPlatformConfig( - "BUICK LACROSSE 2017", - GMCarInfo("Buick LaCrosse 2017-19", "Driver Confidence Package 2"), + [GMCarDocs("Buick LaCrosse 2017-19", "Driver Confidence Package 2")], GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4), ) BUICK_REGAL = GMPlatformConfig( - "BUICK REGAL ESSENCE 2018", - GMCarInfo("Buick Regal Essence 2018"), + [GMCarDocs("Buick Regal Essence 2018")], GMCarSpecs(mass=1714, wheelbase=2.83, steerRatio=14.4, centerToFrontRatio=0.4), ) - ESCALADE = GMPlatformConfig( - "CADILLAC ESCALADE 2017", - GMCarInfo("Cadillac Escalade 2017", "Driver Assist Package"), + CADILLAC_ESCALADE = GMPlatformConfig( + [GMCarDocs("Cadillac Escalade 2017", "Driver Assist Package")], GMCarSpecs(mass=2564, wheelbase=2.95, steerRatio=17.3), ) - ESCALADE_ESV = GMPlatformConfig( - "CADILLAC ESCALADE ESV 2016", - GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), + CADILLAC_ESCALADE_ESV = GMPlatformConfig( + [GMCarDocs("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS")], GMCarSpecs(mass=2739, wheelbase=3.302, steerRatio=17.3, tireStiffnessFactor=1.0), ) - ESCALADE_ESV_2019 = GMPlatformConfig( - "CADILLAC ESCALADE ESV 2019", - GMCarInfo("Cadillac Escalade ESV 2019", "Adaptive Cruise Control (ACC) & LKAS"), - ESCALADE_ESV.specs, + CADILLAC_ESCALADE_ESV_2019 = GMPlatformConfig( + [GMCarDocs("Cadillac Escalade ESV 2019", "Adaptive Cruise Control (ACC) & LKAS")], + CADILLAC_ESCALADE_ESV.specs, ) - BOLT_EUV = GMPlatformConfig( - "CHEVROLET BOLT EUV 2022", + CHEVROLET_BOLT_EUV = GMPlatformConfig( [ - GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"), - GMCarInfo("Chevrolet Bolt EV 2022-23", "2LT Trim with Adaptive Cruise Control Package"), + GMCarDocs("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"), + GMCarDocs("Chevrolet Bolt EV 2022-23", "2LT Trim with Adaptive Cruise Control Package"), ], GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0), ) - SILVERADO = GMPlatformConfig( - "CHEVROLET SILVERADO 1500 2020", + CHEVROLET_SILVERADO = GMPlatformConfig( [ - GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II"), - GMCarInfo("GMC Sierra 1500 2020-21", "Driver Alert Package II", video_link="https://youtu.be/5HbNoBLzRwE"), + GMCarDocs("Chevrolet Silverado 1500 2020-21", "Safety Package II"), + GMCarDocs("GMC Sierra 1500 2020-21", "Driver Alert Package II", video_link="https://youtu.be/5HbNoBLzRwE"), ], GMCarSpecs(mass=2450, wheelbase=3.75, steerRatio=16.3, tireStiffnessFactor=1.0), ) - EQUINOX = GMPlatformConfig( - "CHEVROLET EQUINOX 2019", - GMCarInfo("Chevrolet Equinox 2019-22"), + CHEVROLET_EQUINOX = GMPlatformConfig( + [GMCarDocs("Chevrolet Equinox 2019-22")], GMCarSpecs(mass=1588, wheelbase=2.72, steerRatio=14.4, centerToFrontRatio=0.4), ) - TRAILBLAZER = GMPlatformConfig( - "CHEVROLET TRAILBLAZER 2021", - GMCarInfo("Chevrolet Trailblazer 2021-22"), + CHEVROLET_TRAILBLAZER = GMPlatformConfig( + [GMCarDocs("Chevrolet Trailblazer 2021-22")], GMCarSpecs(mass=1345, wheelbase=2.64, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0), ) @@ -240,10 +226,10 @@ FW_QUERY_CONFIG = FwQueryConfig( extra_ecus=[(Ecu.fwdCamera, 0x24b, None)], ) -EV_CAR = {CAR.VOLT, CAR.BOLT_EUV} +EV_CAR = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_BOLT_EUV} # We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) -CAMERA_ACC_CAR = {CAR.BOLT_EUV, CAR.SILVERADO, CAR.EQUINOX, CAR.TRAILBLAZER} +CAMERA_ACC_CAR = {CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_SILVERADO, CAR.CHEVROLET_EQUINOX, CAR.CHEVROLET_TRAILBLAZER} STEER_THRESHOLD = 1.0 diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 547abcd9b9..6fe8c27585 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -4,7 +4,6 @@ from cereal import car from openpilot.common.numpy_fast import clip, interp from openpilot.common.realtime import DT_CTRL from opendbc.can.packer import CANPacker -from openpilot.selfdrive.car import create_gas_interceptor_command from openpilot.selfdrive.car.honda import hondacan from openpilot.selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams from openpilot.selfdrive.car.interfaces import CarControllerBase @@ -96,7 +95,7 @@ def process_hud_alert(hud_alert): HUDData = namedtuple("HUDData", ["pcm_accel", "v_cruise", "lead_visible", - "lanes_visible", "fcw", "acc_alert", "steer_required"]) + "lanes_visible", "fcw", "acc_alert", "steer_required", "lead_distance_bars"]) def rate_limit_steer(new_steer, last_steer): @@ -183,7 +182,7 @@ class CarController(CarControllerBase): 0.5] # The Honda ODYSSEY seems to have different PCM_ACCEL # msgs, is it other cars too? - if self.CP.enableGasInterceptor or not CC.longActive: + if not CC.longActive: pcm_speed = 0.0 pcm_accel = int(0.0) elif self.CP.carFingerprint in HONDA_NIDEC_ALT_PCM_ACCEL: @@ -235,30 +234,15 @@ class CarController(CarControllerBase): self.apply_brake_last = apply_brake self.brake = apply_brake / self.params.NIDEC_BRAKE_MAX - if self.CP.enableGasInterceptor: - # way too aggressive at low speed without this - gas_mult = interp(CS.out.vEgo, [0., 10.], [0.4, 1.0]) - # send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas. - # This prevents unexpected pedal range rescaling - # Sending non-zero gas when OP is not enabled will cause the PCM not to respond to throttle as expected - # when you do enable. - if CC.longActive: - self.gas = clip(gas_mult * (gas - brake + wind_brake * 3 / 4), 0., 1.) - else: - self.gas = 0.0 - can_sends.append(create_gas_interceptor_command(self.packer, self.gas, self.frame // 2)) - # Send dashboard UI commands. if self.frame % 10 == 0: hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_control.leadVisible, - hud_control.lanesVisible, fcw_display, acc_alert, steer_required) + hud_control.lanesVisible, fcw_display, acc_alert, steer_required, hud_control.leadDistanceBars) can_sends.extend(hondacan.create_ui_commands(self.packer, self.CAN, self.CP, CC.enabled, pcm_speed, hud, CS.is_metric, CS.acc_hud, CS.lkas_hud)) if self.CP.openpilotLongitudinalControl and self.CP.carFingerprint not in HONDA_BOSCH: self.speed = pcm_speed - - if not self.CP.enableGasInterceptor: - self.gas = pcm_accel / self.params.NIDEC_GAS_MAX + self.gas = pcm_accel / self.params.NIDEC_GAS_MAX new_actuators = actuators.copy() new_actuators.speed = self.speed diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 7784581e1c..c98d1a72d3 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -28,7 +28,7 @@ def get_can_messages(CP, gearbox_msg): ("STEER_MOTOR_TORQUE", 0), # TODO: not on every car ] - if CP.carFingerprint == CAR.ODYSSEY_CHN: + if CP.carFingerprint == CAR.HONDA_ODYSSEY_CHN: messages += [ ("SCM_FEEDBACK", 25), ("SCM_BUTTONS", 50), @@ -39,7 +39,7 @@ def get_can_messages(CP, gearbox_msg): ("SCM_BUTTONS", 25), ] - if CP.carFingerprint in (CAR.CRV_HYBRID, CAR.CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E): + if CP.carFingerprint in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E): messages.append((gearbox_msg, 50)) else: messages.append((gearbox_msg, 100)) @@ -47,7 +47,7 @@ def get_can_messages(CP, gearbox_msg): if CP.flags & HondaFlags.BOSCH_ALT_BRAKE: messages.append(("BRAKE_MODULE", 50)) - if CP.carFingerprint in (HONDA_BOSCH | {CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN}): + if CP.carFingerprint in (HONDA_BOSCH | {CAR.HONDA_CIVIC, CAR.HONDA_ODYSSEY, CAR.HONDA_ODYSSEY_CHN}): messages.append(("EPB_STATUS", 50)) if CP.carFingerprint in HONDA_BOSCH: @@ -58,24 +58,20 @@ def get_can_messages(CP, gearbox_msg): ("ACC_CONTROL", 50), ] else: # Nidec signals - if CP.carFingerprint == CAR.ODYSSEY_CHN: + if CP.carFingerprint == CAR.HONDA_ODYSSEY_CHN: messages.append(("CRUISE_PARAMS", 10)) else: messages.append(("CRUISE_PARAMS", 50)) # TODO: clean this up - if CP.carFingerprint in (CAR.ACCORD, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_HYBRID, CAR.INSIGHT, - CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.CIVIC_2022, CAR.HRV_3G): + if CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT, + CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G): pass - elif CP.carFingerprint in (CAR.ODYSSEY_CHN, CAR.FREED, CAR.HRV): + elif CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV): pass else: messages.append(("DOORS_STATUS", 3)) - # add gas interceptor reading if we are using it - if CP.enableGasInterceptor: - messages.append(("GAS_SENSOR", 50)) - if CP.carFingerprint in HONDA_BOSCH_RADARLESS: messages.append(("CRUISE_FAULT_STATUS", 50)) elif CP.openpilotLongitudinalControl: @@ -89,7 +85,7 @@ class CarState(CarStateBase): super().__init__(CP) can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) self.gearbox_msg = "GEARBOX" - if CP.carFingerprint == CAR.ACCORD and CP.transmissionType == TransmissionType.cvt: + if CP.carFingerprint == CAR.HONDA_ACCORD and CP.transmissionType == TransmissionType.cvt: self.gearbox_msg = "GEARBOX_15T" self.main_on_sig_msg = "SCM_FEEDBACK" @@ -129,10 +125,10 @@ class CarState(CarStateBase): # panda checks if the signal is non-zero ret.standstill = cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] < 1e-5 # TODO: find a common signal across all cars - if self.CP.carFingerprint in (CAR.ACCORD, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_HYBRID, CAR.INSIGHT, - CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.CIVIC_2022, CAR.HRV_3G): + if self.CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT, + CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G): ret.doorOpen = bool(cp.vl["SCM_FEEDBACK"]["DRIVERS_DOOR_OPEN"]) - elif self.CP.carFingerprint in (CAR.ODYSSEY_CHN, CAR.FREED, CAR.HRV): + elif self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV): ret.doorOpen = bool(cp.vl["SCM_BUTTONS"]["DRIVERS_DOOR_OPEN"]) else: ret.doorOpen = any([cp.vl["DOORS_STATUS"]["DOOR_OPEN_FL"], cp.vl["DOORS_STATUS"]["DOOR_OPEN_FR"], @@ -185,25 +181,24 @@ class CarState(CarStateBase): ret.brakeHoldActive = cp.vl["VSA_STATUS"]["BRAKE_HOLD_ACTIVE"] == 1 # TODO: set for all cars - if self.CP.carFingerprint in (HONDA_BOSCH | {CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN}): + if self.CP.carFingerprint in (HONDA_BOSCH | {CAR.HONDA_CIVIC, CAR.HONDA_ODYSSEY, CAR.HONDA_ODYSSEY_CHN}): ret.parkingBrake = cp.vl["EPB_STATUS"]["EPB_STATE"] != 0 gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"]) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear, None)) - if self.CP.enableGasInterceptor: - # Same threshold as panda, equivalent to 1e-5 with previous DBC scaling - ret.gas = (cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) // 2 - ret.gasPressed = ret.gas > 492 - else: - ret.gas = cp.vl["POWERTRAIN_DATA"]["PEDAL_GAS"] - ret.gasPressed = ret.gas > 1e-5 + ret.gas = cp.vl["POWERTRAIN_DATA"]["PEDAL_GAS"] + ret.gasPressed = ret.gas > 1e-5 ret.steeringTorque = cp.vl["STEER_STATUS"]["STEER_TORQUE_SENSOR"] ret.steeringTorqueEps = cp.vl["STEER_MOTOR_TORQUE"]["MOTOR_TORQUE"] ret.steeringPressed = abs(ret.steeringTorque) > STEER_THRESHOLD.get(self.CP.carFingerprint, 1200) if self.CP.carFingerprint in HONDA_BOSCH: + # The PCM always manages its own cruise control state, but doesn't publish it + if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS: + ret.cruiseState.nonAdaptive = cp_cam.vl["ACC_HUD"]["CRUISE_CONTROL_LABEL"] != 0 + if not self.CP.openpilotLongitudinalControl: # ACC_HUD is on camera bus on radarless cars acc_hud = cp_cam.vl["ACC_HUD"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else cp.vl["ACC_HUD"] @@ -237,7 +232,7 @@ class CarState(CarStateBase): ret.cruiseState.available = bool(cp.vl[self.main_on_sig_msg]["MAIN_ON"]) # Gets rid of Pedal Grinding noise when brake is pressed at slow speeds for some models - if self.CP.carFingerprint in (CAR.PILOT, CAR.RIDGELINE): + if self.CP.carFingerprint in (CAR.HONDA_PILOT, CAR.HONDA_RIDGELINE): if ret.brake > 0.1: ret.brakePressed = True @@ -276,9 +271,10 @@ class CarState(CarStateBase): ] if CP.carFingerprint in HONDA_BOSCH_RADARLESS: - messages.append(("LKAS_HUD", 10)) - if not CP.openpilotLongitudinalControl: - messages.append(("ACC_HUD", 10)) + messages += [ + ("ACC_HUD", 10), + ("LKAS_HUD", 10), + ] elif CP.carFingerprint not in HONDA_BOSCH: messages += [ diff --git a/selfdrive/car/honda/fingerprints.py b/selfdrive/car/honda/fingerprints.py index a842baac88..8068c63308 100644 --- a/selfdrive/car/honda/fingerprints.py +++ b/selfdrive/car/honda/fingerprints.py @@ -10,7 +10,7 @@ Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.ACCORD: { + CAR.HONDA_ACCORD: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-6A0-8720\x00\x00', b'37805-6A0-9520\x00\x00', @@ -39,6 +39,7 @@ FW_VERSIONS = { b'37805-6B2-A810\x00\x00', b'37805-6B2-A820\x00\x00', b'37805-6B2-A920\x00\x00', + b'37805-6B2-A960\x00\x00', b'37805-6B2-AA10\x00\x00', b'37805-6B2-C520\x00\x00', b'37805-6B2-C540\x00\x00', @@ -204,7 +205,7 @@ FW_VERSIONS = { b'38897-TWD-J020\x00\x00', ], }, - CAR.CIVIC: { + CAR.HONDA_CIVIC: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-5AA-A640\x00\x00', b'37805-5AA-A650\x00\x00', @@ -304,7 +305,7 @@ FW_VERSIONS = { b'38897-TBA-A020\x00\x00', ], }, - CAR.CIVIC_BOSCH: { + CAR.HONDA_CIVIC_BOSCH: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-5AA-A940\x00\x00', b'37805-5AA-A950\x00\x00', @@ -489,7 +490,7 @@ FW_VERSIONS = { b'39494-TGL-G030\x00\x00', ], }, - CAR.CIVIC_BOSCH_DIESEL: { + CAR.HONDA_CIVIC_BOSCH_DIESEL: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-59N-G630\x00\x00', b'37805-59N-G830\x00\x00', @@ -527,7 +528,7 @@ FW_VERSIONS = { b'38897-TBA-A020\x00\x00', ], }, - CAR.CRV: { + CAR.HONDA_CRV: { (Ecu.vsa, 0x18da28f1, None): [ b'57114-T1W-A230\x00\x00', b'57114-T1W-A240\x00\x00', @@ -547,7 +548,7 @@ FW_VERSIONS = { b'36161-T1X-A830\x00\x00', ], }, - CAR.CRV_5G: { + CAR.HONDA_CRV_5G: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-5PA-3060\x00\x00', b'37805-5PA-3080\x00\x00', @@ -675,7 +676,7 @@ FW_VERSIONS = { b'77959-TMM-F040\x00\x00', ], }, - CAR.CRV_EU: { + CAR.HONDA_CRV_EU: { (Ecu.programmedFuelInjection, 0x18da10f1, None): [ b'37805-R5Z-G740\x00\x00', b'37805-R5Z-G780\x00\x00', @@ -701,7 +702,7 @@ FW_VERSIONS = { b'77959-T1G-G940\x00\x00', ], }, - CAR.CRV_HYBRID: { + CAR.HONDA_CRV_HYBRID: { (Ecu.vsa, 0x18da28f1, None): [ b'57114-TMB-H030\x00\x00', b'57114-TPA-G020\x00\x00', @@ -746,7 +747,7 @@ FW_VERSIONS = { b'77959-TLA-H240\x00\x00', ], }, - CAR.FIT: { + CAR.HONDA_FIT: { (Ecu.vsa, 0x18da28f1, None): [ b'57114-T5R-L020\x00\x00', b'57114-T5R-L220\x00\x00', @@ -773,7 +774,7 @@ FW_VERSIONS = { b'77959-T5R-A230\x00\x00', ], }, - CAR.FREED: { + CAR.HONDA_FREED: { (Ecu.gateway, 0x18daeff1, None): [ b'38897-TDK-J010\x00\x00', ], @@ -795,7 +796,7 @@ FW_VERSIONS = { b'36161-TDK-J530\x00\x00', ], }, - CAR.ODYSSEY: { + CAR.HONDA_ODYSSEY: { (Ecu.gateway, 0x18daeff1, None): [ b'38897-THR-A010\x00\x00', b'38897-THR-A020\x00\x00', @@ -898,7 +899,7 @@ FW_VERSIONS = { b'54008-THR-A020\x00\x00', ], }, - CAR.ODYSSEY_CHN: { + CAR.HONDA_ODYSSEY_CHN: { (Ecu.eps, 0x18da30f1, None): [ b'39990-T6D-H220\x00\x00', ], @@ -915,12 +916,13 @@ FW_VERSIONS = { b'77959-T6A-P110\x00\x00', ], }, - CAR.PILOT: { + CAR.HONDA_PILOT: { (Ecu.shiftByWire, 0x18da0bf1, None): [ b'54008-TG7-A520\x00\x00', b'54008-TG7-A530\x00\x00', ], (Ecu.transmission, 0x18da1ef1, None): [ + b'28101-5EY-A040\x00\x00', b'28101-5EY-A050\x00\x00', b'28101-5EY-A100\x00\x00', b'28101-5EY-A430\x00\x00', @@ -941,6 +943,7 @@ FW_VERSIONS = { b'37805-RLV-4070\x00\x00', b'37805-RLV-5140\x00\x00', b'37805-RLV-5230\x00\x00', + b'37805-RLV-A630\x00\x00', b'37805-RLV-A830\x00\x00', b'37805-RLV-A840\x00\x00', b'37805-RLV-B210\x00\x00', @@ -1056,6 +1059,7 @@ FW_VERSIONS = { b'57114-TG7-A630\x00\x00', b'57114-TG7-A730\x00\x00', b'57114-TG8-A140\x00\x00', + b'57114-TG8-A230\x00\x00', b'57114-TG8-A240\x00\x00', b'57114-TG8-A630\x00\x00', b'57114-TG8-A730\x00\x00', @@ -1174,7 +1178,7 @@ FW_VERSIONS = { b'39990-TJB-A130\x00\x00', ], }, - CAR.RIDGELINE: { + CAR.HONDA_RIDGELINE: { (Ecu.eps, 0x18da30f1, None): [ b'39990-T6Z-A020\x00\x00', b'39990-T6Z-A030\x00\x00', @@ -1217,7 +1221,7 @@ FW_VERSIONS = { b'57114-TJZ-A520\x00\x00', ], }, - CAR.INSIGHT: { + CAR.HONDA_INSIGHT: { (Ecu.eps, 0x18da30f1, None): [ b'39990-TXM-A040\x00\x00', ], @@ -1250,7 +1254,7 @@ FW_VERSIONS = { b'78109-TXM-C010\x00\x00', ], }, - CAR.HRV: { + CAR.HONDA_HRV: { (Ecu.gateway, 0x18daeff1, None): [ b'38897-T7A-A010\x00\x00', b'38897-T7A-A110\x00\x00', @@ -1276,7 +1280,7 @@ FW_VERSIONS = { b'78109-THX-C220\x00\x00', ], }, - CAR.HRV_3G: { + CAR.HONDA_HRV_3G: { (Ecu.eps, 0x18da30f1, None): [ b'39990-3W0-A030\x00\x00', ], @@ -1346,7 +1350,7 @@ FW_VERSIONS = { b'57114-TYF-E030\x00\x00', ], }, - CAR.CIVIC_2022: { + CAR.HONDA_CIVIC_2022: { (Ecu.eps, 0x18da30f1, None): [ b'39990-T24-T120\x00\x00', b'39990-T39-A130\x00\x00', diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index d10d5576d9..1be496d951 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -143,7 +143,8 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ acc_hud_values = { 'CRUISE_SPEED': hud.v_cruise, 'ENABLE_MINI_CAR': 1 if enabled else 0, - 'HUD_DISTANCE': 0, # max distance setting on display + # only moves the lead car without ACC_ON + 'HUD_DISTANCE': (hud.lead_distance_bars + 1) % 4, # wraps to 0 at 4 bars 'IMPERIAL_UNIT': int(not is_metric), 'HUD_LEAD': 2 if enabled and hud.lead_visible else 1 if enabled else 0, 'SET_ME_X01_2': 1, @@ -154,6 +155,8 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ acc_hud_values['FCM_OFF'] = 1 acc_hud_values['FCM_OFF_2'] = 1 else: + # Shows the distance bars, TODO: stock camera shows updates temporarily while disabled + acc_hud_values['ACC_ON'] = int(enabled) acc_hud_values['PCM_SPEED'] = pcm_speed * CV.MS_TO_KPH acc_hud_values['PCM_GAS'] = hud.pcm_accel acc_hud_values['SET_ME_X01'] = 1 @@ -192,7 +195,7 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ } commands.append(packer.make_can_msg('RADAR_HUD', CAN.pt, radar_hud_values)) - if CP.carFingerprint == CAR.CIVIC_BOSCH: + if CP.carFingerprint == CAR.HONDA_CIVIC_BOSCH: commands.append(packer.make_can_msg("LEGACY_BRAKE_COMMAND", CAN.pt, {})) return commands diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index f791d4b639..2a5a07093d 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -4,8 +4,8 @@ from panda import Panda from openpilot.common.conversions import Conversions as CV from openpilot.common.numpy_fast import interp from openpilot.selfdrive.car.honda.hondacan import CanBus -from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, \ - HONDA_BOSCH_RADARLESS +from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, CruiseSettings, HondaFlags, CAR, HONDA_BOSCH, \ + HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.disable_ecu import disable_ecu @@ -16,6 +16,7 @@ EventName = car.CarEvent.EventName TransmissionType = car.CarParams.TransmissionType BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise, CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel} +SETTINGS_BUTTONS_DICT = {CruiseSettings.DISTANCE: ButtonType.gapAdjustCruise, CruiseSettings.LKAS: ButtonType.altButton1} class CarInterface(CarInterfaceBase): @@ -23,8 +24,6 @@ class CarInterface(CarInterfaceBase): def get_pid_accel_limits(CP, current_speed, cruise_speed): if CP.carFingerprint in HONDA_BOSCH: return CarControllerParams.BOSCH_ACCEL_MIN, CarControllerParams.BOSCH_ACCEL_MAX - elif CP.enableGasInterceptor: - return CarControllerParams.NIDEC_ACCEL_MIN, CarControllerParams.NIDEC_ACCEL_MAX else: # NIDECs don't allow acceleration near cruise_speed, # so limit limits of pid to prevent windup @@ -49,12 +48,11 @@ class CarInterface(CarInterfaceBase): ret.pcmCruise = not ret.openpilotLongitudinalControl else: ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaNidec)] - ret.enableGasInterceptor = 0x201 in fingerprint[CAN.pt] ret.openpilotLongitudinalControl = True - ret.pcmCruise = not ret.enableGasInterceptor + ret.pcmCruise = True - if candidate == CAR.CRV_5G: + if candidate == CAR.HONDA_CRV_5G: ret.enableBsm = 0x12f8bfa7 in fingerprint[CAN.radar] # Detect Bosch cars with new HUD msgs @@ -62,7 +60,7 @@ class CarInterface(CarInterfaceBase): ret.flags |= HondaFlags.BOSCH_EXT_HUD.value # Accord ICE 1.5T CVT has different gearbox message - if candidate == CAR.ACCORD and 0x191 in fingerprint[CAN.pt]: + if candidate == CAR.HONDA_ACCORD and 0x191 in fingerprint[CAN.pt]: ret.transmissionType = TransmissionType.cvt # Certain Hondas have an extra steering sensor at the bottom of the steering rack, @@ -91,7 +89,7 @@ class CarInterface(CarInterfaceBase): if fw.ecu == "eps" and b"," in fw.fwVersion: eps_modified = True - if candidate == CAR.CIVIC: + if candidate == CAR.HONDA_CIVIC: if eps_modified: # stock request input values: 0x0000, 0x00DE, 0x014D, 0x01EF, 0x0290, 0x0377, 0x0454, 0x0610, 0x06EE # stock request output values: 0x0000, 0x0917, 0x0DC5, 0x1017, 0x119F, 0x140B, 0x1680, 0x1680, 0x1680 @@ -105,11 +103,11 @@ class CarInterface(CarInterfaceBase): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2560], [0, 2560]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[1.1], [0.33]] - elif candidate in (CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CIVIC_2022): + elif candidate in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CIVIC_2022): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] - elif candidate == CAR.ACCORD: + elif candidate == CAR.HONDA_ACCORD: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end if eps_modified: @@ -121,12 +119,12 @@ class CarInterface(CarInterfaceBase): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] - elif candidate in (CAR.CRV, CAR.CRV_EU): + elif candidate in (CAR.HONDA_CRV, CAR.HONDA_CRV_EU): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] ret.wheelSpeedFactor = 1.025 - elif candidate == CAR.CRV_5G: + elif candidate == CAR.HONDA_CRV_5G: if eps_modified: # stock request input values: 0x0000, 0x00DB, 0x01BB, 0x0296, 0x0377, 0x0454, 0x0532, 0x0610, 0x067F # stock request output values: 0x0000, 0x0500, 0x0A15, 0x0E6D, 0x1100, 0x1200, 0x129A, 0x134D, 0x1400 @@ -138,22 +136,22 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.64], [0.192]] ret.wheelSpeedFactor = 1.025 - elif candidate == CAR.CRV_HYBRID: + elif candidate == CAR.HONDA_CRV_HYBRID: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] ret.wheelSpeedFactor = 1.025 - elif candidate == CAR.FIT: + elif candidate == CAR.HONDA_FIT: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] - elif candidate == CAR.FREED: + elif candidate == CAR.HONDA_FREED: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]] - elif candidate in (CAR.HRV, CAR.HRV_3G): + elif candidate in (CAR.HONDA_HRV, CAR.HONDA_HRV_3G): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] - if candidate == CAR.HRV: + if candidate == CAR.HONDA_HRV: ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.025]] ret.wheelSpeedFactor = 1.025 else: @@ -167,22 +165,22 @@ class CarInterface(CarInterfaceBase): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.06]] - elif candidate in (CAR.ODYSSEY, CAR.ODYSSEY_CHN): + elif candidate in (CAR.HONDA_ODYSSEY, CAR.HONDA_ODYSSEY_CHN): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]] - if candidate == CAR.ODYSSEY_CHN: + if candidate == CAR.HONDA_ODYSSEY_CHN: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 32767], [0, 32767]] # TODO: determine if there is a dead zone at the top end else: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end - elif candidate == CAR.PILOT: + elif candidate == CAR.HONDA_PILOT: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] - elif candidate == CAR.RIDGELINE: + elif candidate == CAR.HONDA_RIDGELINE: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]] - elif candidate == CAR.INSIGHT: + elif candidate == CAR.HONDA_INSIGHT: ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] @@ -195,7 +193,7 @@ class CarInterface(CarInterfaceBase): # These cars use alternate user brake msg (0x1BE) # TODO: Only detect feature for Accord/Accord Hybrid, not all Bosch DBCs have BRAKE_MODULE - if 0x1BE in fingerprint[CAN.pt] and candidate == CAR.ACCORD: + if 0x1BE in fingerprint[CAN.pt] and candidate == CAR.HONDA_ACCORD: ret.flags |= HondaFlags.BOSCH_ALT_BRAKE.value if ret.flags & HondaFlags.BOSCH_ALT_BRAKE: @@ -208,16 +206,13 @@ class CarInterface(CarInterfaceBase): if ret.openpilotLongitudinalControl and candidate in HONDA_BOSCH: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HONDA_BOSCH_LONG - if ret.enableGasInterceptor and candidate not in HONDA_BOSCH: - ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HONDA_GAS_INTERCEPTOR - if candidate in HONDA_BOSCH_RADARLESS: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HONDA_RADARLESS # min speed to enable ACC. if car can do stop and go, then set enabling speed # to a negative value, so it won't matter. Otherwise, add 0.5 mph margin to not # conflict with PCM acc - ret.autoResumeSng = candidate in (HONDA_BOSCH | {CAR.CIVIC}) or ret.enableGasInterceptor + ret.autoResumeSng = candidate in (HONDA_BOSCH | {CAR.HONDA_CIVIC}) ret.minEnableSpeed = -1. if ret.autoResumeSng else 25.5 * CV.MPH_TO_MS ret.steerActuatorDelay = 0.1 @@ -236,7 +231,7 @@ class CarInterface(CarInterfaceBase): ret.buttonEvents = [ *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT), - *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1}), + *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT), ] # events @@ -262,8 +257,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - # pass in a car.CarControl - # to be called @ 100hz - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 4960380bbc..533e01e9b4 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -5,7 +5,7 @@ from cereal import car from openpilot.common.conversions import Conversions as CV from panda.python import uds from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 Ecu = car.CarParams.Ecu @@ -68,6 +68,11 @@ class CruiseButtons: MAIN = 1 +class CruiseSettings: + DISTANCE = 3 + LKAS = 1 + + # See dbc files for info on values VISUAL_HUD = { VisualAlert.none: 0, @@ -82,7 +87,7 @@ VISUAL_HUD = { @dataclass -class HondaCarInfo(CarInfo): +class HondaCarDocs(CarDocs): package: str = "Honda Sensing" def init_make(self, CP: car.CarParams): @@ -110,169 +115,147 @@ class HondaNidecPlatformConfig(PlatformConfig): class CAR(Platforms): # Bosch Cars - ACCORD = HondaBoschPlatformConfig( - "HONDA ACCORD 2018", + HONDA_ACCORD = HondaBoschPlatformConfig( [ - HondaCarInfo("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS), - HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS), - HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS), + HondaCarDocs("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS), + HondaCarDocs("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS), + HondaCarDocs("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS), ], # steerRatio: 11.82 is spec end-to-end CarSpecs(mass=3279 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=16.33, centerToFrontRatio=0.39, tireStiffnessFactor=0.8467), dbc_dict('honda_accord_2018_can_generated', None), ) - CIVIC_BOSCH = HondaBoschPlatformConfig( - "HONDA CIVIC (BOSCH) 2019", + HONDA_CIVIC_BOSCH = HondaBoschPlatformConfig( [ - HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", + HondaCarDocs("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS), - HondaCarInfo("Honda Civic Hatchback 2017-21", min_steer_speed=12. * CV.MPH_TO_MS), + HondaCarDocs("Honda Civic Hatchback 2017-21", min_steer_speed=12. * CV.MPH_TO_MS), ], CarSpecs(mass=1326, wheelbase=2.7, steerRatio=15.38, centerToFrontRatio=0.4), # steerRatio: 10.93 is end-to-end spec dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None), ) - CIVIC_BOSCH_DIESEL = HondaBoschPlatformConfig( - "HONDA CIVIC SEDAN 1.6 DIESEL 2019", - None, # don't show in docs - CIVIC_BOSCH.specs, + HONDA_CIVIC_BOSCH_DIESEL = HondaBoschPlatformConfig( + [], # don't show in docs + HONDA_CIVIC_BOSCH.specs, dbc_dict('honda_accord_2018_can_generated', None), ) - CIVIC_2022 = HondaBoschPlatformConfig( - "HONDA CIVIC 2022", + HONDA_CIVIC_2022 = HondaBoschPlatformConfig( [ - HondaCarInfo("Honda Civic 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"), - HondaCarInfo("Honda Civic Hatchback 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"), + HondaCarDocs("Honda Civic 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"), + HondaCarDocs("Honda Civic Hatchback 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"), ], - CIVIC_BOSCH.specs, + HONDA_CIVIC_BOSCH.specs, dbc_dict('honda_civic_ex_2022_can_generated', None), flags=HondaFlags.BOSCH_RADARLESS, ) - CRV_5G = HondaBoschPlatformConfig( - "HONDA CR-V 2017", - HondaCarInfo("Honda CR-V 2017-22", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_CRV_5G = HondaBoschPlatformConfig( + [HondaCarDocs("Honda CR-V 2017-22", min_steer_speed=12. * CV.MPH_TO_MS)], # steerRatio: 12.3 is spec end-to-end CarSpecs(mass=3410 * CV.LB_TO_KG, wheelbase=2.66, steerRatio=16.0, centerToFrontRatio=0.41, tireStiffnessFactor=0.677), dbc_dict('honda_crv_ex_2017_can_generated', None, body_dbc='honda_crv_ex_2017_body_generated'), flags=HondaFlags.BOSCH_ALT_BRAKE, ) - CRV_HYBRID = HondaBoschPlatformConfig( - "HONDA CR-V HYBRID 2019", - HondaCarInfo("Honda CR-V Hybrid 2017-20", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_CRV_HYBRID = HondaBoschPlatformConfig( + [HondaCarDocs("Honda CR-V Hybrid 2017-20", min_steer_speed=12. * CV.MPH_TO_MS)], # mass: mean of 4 models in kg, steerRatio: 12.3 is spec end-to-end CarSpecs(mass=1667, wheelbase=2.66, steerRatio=16, centerToFrontRatio=0.41, tireStiffnessFactor=0.677), dbc_dict('honda_accord_2018_can_generated', None), ) - HRV_3G = HondaBoschPlatformConfig( - "HONDA HR-V 2023", - HondaCarInfo("Honda HR-V 2023", "All"), + HONDA_HRV_3G = HondaBoschPlatformConfig( + [HondaCarDocs("Honda HR-V 2023", "All")], CarSpecs(mass=3125 * CV.LB_TO_KG, wheelbase=2.61, steerRatio=15.2, centerToFrontRatio=0.41, tireStiffnessFactor=0.5), dbc_dict('honda_civic_ex_2022_can_generated', None), flags=HondaFlags.BOSCH_RADARLESS | HondaFlags.BOSCH_ALT_BRAKE, ) ACURA_RDX_3G = HondaBoschPlatformConfig( - "ACURA RDX 2020", - HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS), + [HondaCarDocs("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)], CarSpecs(mass=4068 * CV.LB_TO_KG, wheelbase=2.75, steerRatio=11.95, centerToFrontRatio=0.41, tireStiffnessFactor=0.677), # as spec dbc_dict('acura_rdx_2020_can_generated', None), flags=HondaFlags.BOSCH_ALT_BRAKE, ) - INSIGHT = HondaBoschPlatformConfig( - "HONDA INSIGHT 2019", - HondaCarInfo("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS), + HONDA_INSIGHT = HondaBoschPlatformConfig( + [HondaCarDocs("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)], CarSpecs(mass=2987 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.0, centerToFrontRatio=0.39, tireStiffnessFactor=0.82), # as spec dbc_dict('honda_insight_ex_2019_can_generated', None), ) HONDA_E = HondaBoschPlatformConfig( - "HONDA E 2020", - HondaCarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS), + [HondaCarDocs("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS)], CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82), dbc_dict('acura_rdx_2020_can_generated', None), ) # Nidec Cars ACURA_ILX = HondaNidecPlatformConfig( - "ACURA ILX 2016", - HondaCarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS), + [HondaCarDocs("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS)], CarSpecs(mass=3095 * CV.LB_TO_KG, wheelbase=2.67, steerRatio=18.61, centerToFrontRatio=0.37, tireStiffnessFactor=0.72), # 15.3 is spec end-to-end dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - CRV = HondaNidecPlatformConfig( - "HONDA CR-V 2016", - HondaCarInfo("Honda CR-V 2015-16", "Touring Trim", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_CRV = HondaNidecPlatformConfig( + [HondaCarDocs("Honda CR-V 2015-16", "Touring Trim", min_steer_speed=12. * CV.MPH_TO_MS)], CarSpecs(mass=3572 * CV.LB_TO_KG, wheelbase=2.62, steerRatio=16.89, centerToFrontRatio=0.41, tireStiffnessFactor=0.444), # as spec dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - CRV_EU = HondaNidecPlatformConfig( - "HONDA CR-V EU 2016", - None, # Euro version of CRV Touring, don't show in docs - CRV.specs, + HONDA_CRV_EU = HondaNidecPlatformConfig( + [], # Euro version of CRV Touring, don't show in docs + HONDA_CRV.specs, dbc_dict('honda_crv_executive_2016_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - FIT = HondaNidecPlatformConfig( - "HONDA FIT 2018", - HondaCarInfo("Honda Fit 2018-20", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_FIT = HondaNidecPlatformConfig( + [HondaCarDocs("Honda Fit 2018-20", min_steer_speed=12. * CV.MPH_TO_MS)], CarSpecs(mass=2644 * CV.LB_TO_KG, wheelbase=2.53, steerRatio=13.06, centerToFrontRatio=0.39, tireStiffnessFactor=0.75), dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - FREED = HondaNidecPlatformConfig( - "HONDA FREED 2020", - HondaCarInfo("Honda Freed 2020", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_FREED = HondaNidecPlatformConfig( + [HondaCarDocs("Honda Freed 2020", min_steer_speed=12. * CV.MPH_TO_MS)], CarSpecs(mass=3086. * CV.LB_TO_KG, wheelbase=2.74, steerRatio=13.06, centerToFrontRatio=0.39, tireStiffnessFactor=0.75), # mostly copied from FIT dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - HRV = HondaNidecPlatformConfig( - "HONDA HRV 2019", - HondaCarInfo("Honda HR-V 2019-22", min_steer_speed=12. * CV.MPH_TO_MS), - HRV_3G.specs, + HONDA_HRV = HondaNidecPlatformConfig( + [HondaCarDocs("Honda HR-V 2019-22", min_steer_speed=12. * CV.MPH_TO_MS)], + HONDA_HRV_3G.specs, dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - ODYSSEY = HondaNidecPlatformConfig( - "HONDA ODYSSEY 2018", - HondaCarInfo("Honda Odyssey 2018-20"), + HONDA_ODYSSEY = HondaNidecPlatformConfig( + [HondaCarDocs("Honda Odyssey 2018-20")], CarSpecs(mass=1900, wheelbase=3.0, steerRatio=14.35, centerToFrontRatio=0.41, tireStiffnessFactor=0.82), dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_PCM_ACCEL, ) - ODYSSEY_CHN = HondaNidecPlatformConfig( - "HONDA ODYSSEY CHN 2019", - None, # Chinese version of Odyssey, don't show in docs - ODYSSEY.specs, + HONDA_ODYSSEY_CHN = HondaNidecPlatformConfig( + [], # Chinese version of Odyssey, don't show in docs + HONDA_ODYSSEY.specs, dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) ACURA_RDX = HondaNidecPlatformConfig( - "ACURA RDX 2018", - HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS), + [HondaCarDocs("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS)], CarSpecs(mass=3925 * CV.LB_TO_KG, wheelbase=2.68, steerRatio=15.0, centerToFrontRatio=0.38, tireStiffnessFactor=0.444), # as spec dbc_dict('acura_rdx_2018_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - PILOT = HondaNidecPlatformConfig( - "HONDA PILOT 2017", + HONDA_PILOT = HondaNidecPlatformConfig( [ - HondaCarInfo("Honda Pilot 2016-22", min_steer_speed=12. * CV.MPH_TO_MS), - HondaCarInfo("Honda Passport 2019-23", "All", min_steer_speed=12. * CV.MPH_TO_MS), + HondaCarDocs("Honda Pilot 2016-22", min_steer_speed=12. * CV.MPH_TO_MS), + HondaCarDocs("Honda Passport 2019-23", "All", min_steer_speed=12. * CV.MPH_TO_MS), ], CarSpecs(mass=4278 * CV.LB_TO_KG, wheelbase=2.86, centerToFrontRatio=0.428, steerRatio=16.0, tireStiffnessFactor=0.444), # as spec dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - RIDGELINE = HondaNidecPlatformConfig( - "HONDA RIDGELINE 2017", - HondaCarInfo("Honda Ridgeline 2017-24", min_steer_speed=12. * CV.MPH_TO_MS), + HONDA_RIDGELINE = HondaNidecPlatformConfig( + [HondaCarDocs("Honda Ridgeline 2017-24", min_steer_speed=12. * CV.MPH_TO_MS)], CarSpecs(mass=4515 * CV.LB_TO_KG, wheelbase=3.18, centerToFrontRatio=0.41, steerRatio=15.59, tireStiffnessFactor=0.444), # as spec dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'), flags=HondaFlags.NIDEC_ALT_SCM_MESSAGES, ) - CIVIC = HondaNidecPlatformConfig( - "HONDA CIVIC 2016", - HondaCarInfo("Honda Civic 2016-18", min_steer_speed=12. * CV.MPH_TO_MS, video_link="https://youtu.be/-IkImTe1NYE"), + HONDA_CIVIC = HondaNidecPlatformConfig( + [HondaCarDocs("Honda Civic 2016-18", min_steer_speed=12. * CV.MPH_TO_MS, video_link="https://youtu.be/-IkImTe1NYE")], CarSpecs(mass=1326, wheelbase=2.70, centerToFrontRatio=0.4, steerRatio=15.38), # 10.93 is end-to-end spec dbc_dict('honda_civic_touring_2016_can_generated', 'acura_ilx_2016_nidec'), ) @@ -324,16 +307,16 @@ FW_QUERY_CONFIG = FwQueryConfig( # We lose these ECUs without the comma power on these cars. # Note that we still attempt to match with them when they are present non_essential_ecus={ - Ecu.programmedFuelInjection: [CAR.ACCORD, CAR.CIVIC, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.transmission: [CAR.ACCORD, CAR.CIVIC, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.srs: [CAR.ACCORD], - Ecu.eps: [CAR.ACCORD], - Ecu.vsa: [CAR.ACCORD, CAR.CIVIC, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.combinationMeter: [CAR.ACCORD, CAR.CIVIC, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.gateway: [CAR.ACCORD, CAR.CIVIC, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.electricBrakeBooster: [CAR.ACCORD, CAR.CIVIC_BOSCH, CAR.CRV_5G], - Ecu.shiftByWire: [CAR.ACCORD], # existence correlates with transmission type for ICE - Ecu.hud: [CAR.ACCORD], # existence correlates with trim level + Ecu.programmedFuelInjection: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.transmission: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.srs: [CAR.HONDA_ACCORD], + Ecu.eps: [CAR.HONDA_ACCORD], + Ecu.vsa: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.combinationMeter: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.gateway: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.electricBrakeBooster: [CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CRV_5G], + Ecu.shiftByWire: [CAR.HONDA_ACCORD], # existence correlates with transmission type for ICE + Ecu.hud: [CAR.HONDA_ACCORD], # existence correlates with trim level }, extra_ecus=[ # The only other ECU on PT bus accessible by camera on radarless Civic @@ -344,7 +327,7 @@ FW_QUERY_CONFIG = FwQueryConfig( STEER_THRESHOLD = { # default is 1200, overrides go here CAR.ACURA_RDX: 400, - CAR.CRV_EU: 400, + CAR.HONDA_CRV_EU: 400, } HONDA_NIDEC_ALT_PCM_ACCEL = CAR.with_flags(HondaFlags.NIDEC_ALT_PCM_ACCEL) diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index ee7f441227..7829d764b0 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -129,7 +129,7 @@ class CarController(CarControllerBase): can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame)) if self.frame % 2 == 0: can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override, - set_speed_in_units)) + set_speed_in_units, hud_control)) self.accel_last = accel else: # button presses @@ -148,7 +148,7 @@ class CarController(CarControllerBase): jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0 use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2), - hud_control.leadVisible, set_speed_in_units, stopping, + hud_control, set_speed_in_units, stopping, CC.cruiseControl.override, use_fca)) # 20 Hz LFA MFA message diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 64a9fdf2ce..eac91d5293 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -207,7 +207,7 @@ class CarState(CarStateBase): # TODO: alt signal usage may be described by cp.vl['BLINKERS']['USE_ALT_LAMP'] left_blinker_sig, right_blinker_sig = "LEFT_LAMP", "RIGHT_LAMP" - if self.CP.carFingerprint == CAR.KONA_EV_2ND_GEN: + if self.CP.carFingerprint == CAR.HYUNDAI_KONA_EV_2ND_GEN: left_blinker_sig, right_blinker_sig = "LEFT_LAMP_ALT", "RIGHT_LAMP_ALT" ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][left_blinker_sig], cp.vl["BLINKERS"][right_blinker_sig]) diff --git a/selfdrive/car/hyundai/fingerprints.py b/selfdrive/car/hyundai/fingerprints.py index 6349318fbf..b7f9cb3384 100644 --- a/selfdrive/car/hyundai/fingerprints.py +++ b/selfdrive/car/hyundai/fingerprints.py @@ -5,7 +5,7 @@ from openpilot.selfdrive.car.hyundai.values import CAR Ecu = car.CarParams.Ecu FINGERPRINTS = { - CAR.SANTA_FE: [{ + CAR.HYUNDAI_SANTA_FE: [{ 67: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 593: 8, 608: 8, 688: 6, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1155: 8, 1156: 8, 1162: 8, 1164: 8, 1168: 7, 1170: 8, 1173: 8, 1183: 8, 1186: 2, 1191: 2, 1227: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1379: 8, 1384: 8, 1407: 8, 1414: 3, 1419: 8, 1427: 6, 1456: 4, 1470: 8 }, { @@ -14,7 +14,7 @@ FINGERPRINTS = { { 67: 8, 68: 8, 80: 4, 160: 8, 161: 8, 272: 8, 288: 4, 339: 8, 356: 8, 357: 8, 399: 8, 544: 8, 608: 8, 672: 8, 688: 5, 704: 1, 790: 8, 809: 8, 848: 8, 880: 8, 898: 8, 900: 8, 901: 8, 904: 8, 1056: 8, 1064: 8, 1065: 8, 1072: 8, 1075: 8, 1087: 8, 1088: 8, 1151: 8, 1200: 8, 1201: 8, 1232: 4, 1264: 8, 1265: 8, 1266: 8, 1296: 8, 1306: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1348: 8, 1349: 8, 1369: 8, 1370: 8, 1371: 8, 1407: 8, 1415: 8, 1419: 8, 1440: 8, 1442: 4, 1461: 8, 1470: 8 }], - CAR.SONATA: [{ + CAR.HYUNDAI_SONATA: [{ 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 546: 8, 549: 8, 550: 8, 576: 8, 593: 8, 608: 8, 688: 6, 809: 8, 832: 8, 854: 8, 865: 8, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 905: 8, 908: 8, 909: 8, 912: 7, 913: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1089: 5, 1096: 8, 1107: 5, 1108: 8, 1114: 8, 1136: 8, 1145: 8, 1151: 8, 1155: 8, 1156: 8, 1157: 4, 1162: 8, 1164: 8, 1168: 8, 1170: 8, 1173: 8, 1180: 8, 1183: 8, 1184: 8, 1186: 2, 1191: 2, 1193: 8, 1210: 8, 1225: 8, 1227: 8, 1265: 4, 1268: 8, 1280: 8, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1330: 8, 1339: 8, 1342: 6, 1343: 8, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1371: 8, 1378: 8, 1379: 8, 1384: 8, 1394: 8, 1407: 8, 1419: 8, 1427: 6, 1446: 8, 1456: 4, 1460: 8, 1470: 8, 1485: 8, 1504: 3, 1988: 8, 1996: 8, 2000: 8, 2004: 8, 2008: 8, 2012: 8, 2015: 8 }], CAR.KIA_STINGER: [{ @@ -23,13 +23,13 @@ FINGERPRINTS = { CAR.GENESIS_G90: [{ 67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 358: 6, 359: 8, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1162: 4, 1168: 7, 1170: 8, 1173: 8, 1184: 8, 1265: 4, 1280: 1, 1281: 3, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1378: 4, 1384: 8, 1407: 8, 1419: 8, 1425: 2, 1427: 6, 1434: 2, 1456: 4, 1470: 8, 1988: 8, 2000: 8, 2003: 8, 2004: 8, 2005: 8, 2008: 8, 2011: 8, 2012: 8, 2013: 8 }], - CAR.IONIQ_EV_2020: [{ + CAR.HYUNDAI_IONIQ_EV_2020: [{ 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 524: 8, 544: 7, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 8, 1151: 6, 1155: 8, 1156: 8, 1157: 4, 1164: 8, 1168: 7, 1173: 8, 1183: 8, 1186: 2, 1191: 2, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1379: 8, 1407: 8, 1419: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1473: 8, 1507: 8, 1535: 8, 1988: 8, 1996: 8, 2000: 8, 2004: 8, 2005: 8, 2008: 8, 2012: 8, 2013: 8 }], - CAR.KONA_EV: [{ + CAR.HYUNDAI_KONA_EV: [{ 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 549: 8, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1078: 4, 1136: 8, 1151: 6, 1168: 7, 1173: 8, 1183: 8, 1186: 2, 1191: 2, 1225: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1307: 8, 1312: 8, 1322: 8, 1342: 6, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1378: 4, 1407: 8, 1419: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1456: 4, 1470: 8, 1473: 8, 1507: 8, 1535: 8, 2000: 8, 2004: 8, 2008: 8, 2012: 8, 1157: 4, 1193: 8, 1379: 8, 1988: 8, 1996: 8 }], - CAR.KONA_EV_2022: [{ + CAR.HYUNDAI_KONA_EV_2022: [{ 127: 8, 304: 8, 320: 8, 339: 8, 352: 8, 356: 4, 544: 8, 593: 8, 688: 5, 832: 8, 881: 8, 882: 8, 897: 8, 902: 8, 903: 8, 905: 8, 909: 8, 913: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1069: 8, 1078: 4, 1136: 8, 1145: 8, 1151: 8, 1155: 8, 1156: 8, 1157: 4, 1162: 8, 1164: 8, 1168: 8, 1173: 8, 1183: 8, 1188: 8, 1191: 2, 1193: 8, 1225: 8, 1227: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1291: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1339: 8, 1342: 8, 1343: 8, 1345: 8, 1348: 8, 1355: 8, 1363: 8, 1369: 8, 1379: 8, 1407: 8, 1419: 8, 1426: 8, 1427: 6, 1429: 8, 1430: 8, 1446: 8, 1456: 4, 1470: 8, 1473: 8, 1485: 8, 1507: 8, 1535: 8, 1990: 8, 1998: 8 }], CAR.KIA_NIRO_EV: [{ @@ -44,7 +44,7 @@ FINGERPRINTS = { } FW_VERSIONS = { - CAR.AZERA_6TH_GEN: { + CAR.HYUNDAI_AZERA_6TH_GEN: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00IG__ SCC F-CU- 1.00 1.00 99110-G8100 ', ], @@ -61,7 +61,7 @@ FW_VERSIONS = { b'\xf1\x81641KA051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.AZERA_HEV_6TH_GEN: { + CAR.HYUNDAI_AZERA_HEV_6TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00IGH MFC AT KOR LHD 1.00 1.00 99211-G8000 180903', b'\xf1\x00IGH MFC AT KOR LHD 1.00 1.01 99211-G8000 181109', @@ -93,7 +93,7 @@ FW_VERSIONS = { b'\xf1\x00DH LKAS 1.5 -140425', ], }, - CAR.IONIQ: { + CAR.HYUNDAI_IONIQ: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2000 ', ], @@ -110,7 +110,7 @@ FW_VERSIONS = { b'\xf1\x816U3H1051\x00\x00\xf1\x006U3H0_C2\x00\x006U3H1051\x00\x00HAE0G16US2\x00\x00\x00\x00', ], }, - CAR.IONIQ_PHEV_2019: { + CAR.HYUNDAI_IONIQ_PHEV_2019: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEhe SCC H-CUP 1.01 1.01 96400-G2100 ', ], @@ -128,7 +128,7 @@ FW_VERSIONS = { b'\xf1\x816U3J2051\x00\x00\xf1\x006U3H0_C2\x00\x006U3J2051\x00\x00PAE0G16NS1\xdbD\r\x81', ], }, - CAR.IONIQ_PHEV: { + CAR.HYUNDAI_IONIQ_PHEV: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEhe SCC F-CUP 1.00 1.00 99110-G2200 ', b'\xf1\x00AEhe SCC F-CUP 1.00 1.00 99110-G2600 ', @@ -162,7 +162,7 @@ FW_VERSIONS = { b'\xf1\x816U3J9051\x00\x00\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00PAE0G16NL2\x00\x00\x00\x00', ], }, - CAR.IONIQ_EV_2020: { + CAR.HYUNDAI_IONIQ_EV_2020: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEev SCC F-CUP 1.00 1.00 99110-G7200 ', b'\xf1\x00AEev SCC F-CUP 1.00 1.00 99110-G7500 ', @@ -180,7 +180,7 @@ FW_VERSIONS = { b'\xf1\x00AEE MFC AT EUR RHD 1.00 1.01 95740-G2600 190819', ], }, - CAR.IONIQ_EV_LTD: { + CAR.HYUNDAI_IONIQ_EV_LTD: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEev SCC F-CUP 1.00 1.00 96400-G7000 ', b'\xf1\x00AEev SCC F-CUP 1.00 1.00 96400-G7100 ', @@ -199,7 +199,7 @@ FW_VERSIONS = { b'\xf1\x00AEE MFC AT USA LHD 1.00 1.00 95740-G2400 180222', ], }, - CAR.IONIQ_HEV_2022: { + CAR.HYUNDAI_IONIQ_HEV_2022: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00AEhe SCC F-CUP 1.00 1.00 99110-G2600 ', b'\xf1\x00AEhe SCC FHCUP 1.00 1.00 99110-G2600 ', @@ -218,7 +218,7 @@ FW_VERSIONS = { b'\xf1\x816U3J9051\x00\x00\xf1\x006U3H1_C2\x00\x006U3J9051\x00\x00HAE0G16NL2\x00\x00\x00\x00', ], }, - CAR.SONATA: { + CAR.HYUNDAI_SONATA: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DN8_ SCC F-CU- 1.00 1.00 99110-L0000 ', b'\xf1\x00DN8_ SCC F-CUP 1.00 1.00 99110-L0000 ', @@ -361,7 +361,7 @@ FW_VERSIONS = { b'\xf1\x87SANFB45889451GC7wx\x87\x88gw\x87x\x88\x88x\x88\x87wxw\x87wxw\x87\x8f\xfc\xffeU\x8f\xff+Q\xf1\x81U913\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U913\x00\x00\x00\x00\x00\x00SDN8T16NB2\n\xdd^\xbc', ], }, - CAR.SONATA_LF: { + CAR.HYUNDAI_SONATA_LF: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00LF__ SCC F-CUP 1.00 1.00 96401-C2200 ', ], @@ -389,7 +389,7 @@ FW_VERSIONS = { b'\xf1\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x816T6B4051\x00\x00\xf1\x006T6H0_C2\x00\x006T6B4051\x00\x00TLF0G24SL2n\x8d\xbe\xd8', ], }, - CAR.TUCSON: { + CAR.HYUNDAI_TUCSON: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TL__ FCA F-CUP 1.00 1.01 99110-D3500 ', b'\xf1\x00TL__ FCA F-CUP 1.00 1.02 99110-D3510 ', @@ -407,7 +407,7 @@ FW_VERSIONS = { b'\xf1\x87LBJXAN202299KF22\x87x\x87\x88ww\x87xx\x88\x97\x88\x87\x88\x98x\x88\x99\x98\x89\x87o\xf6\xff\x87w\x7f\xff\x12\x9a\xf1\x81U083\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U083\x00\x00\x00\x00\x00\x00TTL2V20KL1\x8fRn\x8a', ], }, - CAR.SANTA_FE: { + CAR.HYUNDAI_SANTA_FE: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1210 ', b'\xf1\x00TM__ SCC F-CUP 1.00 1.01 99110-S2000 ', @@ -470,7 +470,7 @@ FW_VERSIONS = { b'\xf1\x87SDKXAA2443414GG1vfvgwv\x87h\x88\x88\x88\x88ww\x87wwwww\x99_\xfc\xffvD?\xffl\xd2\xf1\x816W3E1051\x00\x00\xf1\x006W351_C2\x00\x006W3E1051\x00\x00TTM4G24NS6\x00\x00\x00\x00', ], }, - CAR.SANTA_FE_2022: { + CAR.HYUNDAI_SANTA_FE_2022: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TM__ SCC F-CUP 1.00 1.00 99110-S1500 ', b'\xf1\x00TM__ SCC FHCUP 1.00 1.00 99110-S1500 ', @@ -532,35 +532,42 @@ FW_VERSIONS = { b'\xf1\x87SDMXCA9087684GN1VfvgUUeVwwgwwwwwffffU?\xfb\xff\x97\x88\x7f\xff+\xa4\xf1\x89HT6WAD00A1\xf1\x82STM4G25NH1\x00\x00\x00\x00\x00\x00', ], }, - CAR.SANTA_FE_HEV_2022: { + CAR.HYUNDAI_SANTA_FE_HEV_2022: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ', + b'\xf1\x00TMhe SCC FHCUP 1.00 1.01 99110-CL500 ', ], (Ecu.eps, 0x7d4, None): [ 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 R 1.00 1.05 57700-CL000 4TSHP105', + b'\xf1\x00TM MDPS R 1.00 1.06 57700-CL000 4TSHP106', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00TMA MFC AT USA LHD 1.00 1.03 99211-S2500 220414', b'\xf1\x00TMH MFC AT EUR LHD 1.00 1.06 99211-S1500 220727', + b'\xf1\x00TMH MFC AT KOR LHD 1.00 1.06 99211-S1500 220727', b'\xf1\x00TMH MFC AT USA LHD 1.00 1.03 99211-S1500 210224', + b'\xf1\x00TMH MFC AT USA LHD 1.00 1.05 99211-S1500 220126', b'\xf1\x00TMH MFC AT USA LHD 1.00 1.06 99211-S1500 220727', ], (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16KA1\xc6\x15Q\x1e', b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16SA3\xa3\x1b\xe14', b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2H16UA3I\x94\xac\x8f', b'\xf1\x87959102T250\x00\x00\x00\x00\x00\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E14\x00\x00\x00\x00\x00\x00\x00TTM2H16SA2\x80\xd7l\xb2', ], (Ecu.engine, 0x7e0, None): [ + b'\xf1\x87391312MTA0', b'\xf1\x87391312MTC1', b'\xf1\x87391312MTE0', b'\xf1\x87391312MTL0', ], }, - CAR.SANTA_FE_PHEV_2022: { + CAR.HYUNDAI_SANTA_FE_PHEV_2022: { (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00TMhe SCC F-CUP 1.00 1.00 99110-CL500 ', b'\xf1\x00TMhe SCC FHCUP 1.00 1.01 99110-CL500 ', b'\xf1\x8799110CL500\xf1\x00TMhe SCC FHCUP 1.00 1.00 99110-CL500 ', ], @@ -574,6 +581,7 @@ FW_VERSIONS = { b'\xf1\x00TMP MFC AT USA LHD 1.00 1.06 99211-S1500 220727', ], (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA0o\x88^\xbe', b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea', b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA0o\x88^\xbe', b'\xf1\x8795441-3D121\x00\xf1\x81E16\x00\x00\x00\x00\x00\x00\x00\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TTM2P16SA1\x0b\xc5\x0f\xea', @@ -583,7 +591,7 @@ FW_VERSIONS = { b'\xf1\x87391312MTF1', ], }, - CAR.CUSTIN_1ST_GEN: { + CAR.HYUNDAI_CUSTIN_1ST_GEN: { (Ecu.abs, 0x7d1, None): [ b'\xf1\x00KU ESC \x01 101!\x02\x03 58910-O3200', ], @@ -677,7 +685,7 @@ FW_VERSIONS = { b'\xf1\x87VCNLF11383972DK1vffV\x99\x99\x89\x98\x86eUU\x88wg\x89vfff\x97fff\x99\x87o\xff"\xc1\xf1\x81E30\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E30\x00\x00\x00\x00\x00\x00\x00SCK0T33GH0\xbe`\xfb\xc6', ], }, - CAR.PALISADE: { + CAR.HYUNDAI_PALISADE: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00LX2 SCC FHCUP 1.00 1.04 99110-S8100 ', b'\xf1\x00LX2_ SCC F-CUP 1.00 1.04 99110-S8100 ', @@ -784,7 +792,7 @@ FW_VERSIONS = { b'\xf1\x87LDMVBN950669KF37\x97www\x96fffy\x99\xa7\x99\xa9\x99\xaa\x99g\x88\x96x\xb8\x8f\xf9\xffTD/\xff\xa7\xcb\xf1\x81U922\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U922\x00\x00\x00\x00\x00\x00SLX4G38NB5\xb9\x94\xe8\x89', ], }, - CAR.VELOSTER: { + CAR.HYUNDAI_VELOSTER: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00JS__ SCC H-CUP 1.00 1.02 95650-J3200 ', b'\xf1\x00JS__ SCC HNCUP 1.00 1.02 95650-J3100 ', @@ -836,10 +844,12 @@ FW_VERSIONS = { b'\xf1\x00IK MDPS R 1.00 1.07 57700-G9420 4I4VL107', b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9200 4I2CL108', b'\xf1\x00IK MDPS R 1.00 1.08 57700-G9420 4I4VL108', + b'\xf1\x00IK MDPS R 1.00 5.09 57700-G9520 4I4VL509', ], (Ecu.transmission, 0x7e1, None): [ b'\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL', b'\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T20KB3Wuvz', + b'\xf1\x00bcsh8p54 E31\x00\x00\x00\x00\x00\x00\x00SIK0T33NH0\x0f\xa3Y*', b'\xf1\x87VCJLP18407832DN3\x88vXfvUVT\x97eFU\x87d7v\x88eVeveFU\x89\x98\x7f\xff\xb2\xb0\xf1\x81E25\x00\x00\x00', b'\xf1\x87VDJLC18480772DK9\x88eHfwfff\x87eFUeDEU\x98eFe\x86T5DVyo\xff\x87s\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33KB5\x9f\xa5&\x81', b'\xf1\x87VDKLT18912362DN4wfVfwefeveVUwfvw\x88vWfvUFU\x89\xa9\x8f\xff\x87w\xf1\x81E25\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SIK0T33NB4\xecE\xefL', @@ -847,16 +857,19 @@ FW_VERSIONS = { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 ', b'\xf1\x00IK__ SCC F-CUP 1.00 1.02 96400-G9100 \xf1\xa01.02', + b'\xf1\x00IK__ SCC FHCUP 1.00 1.00 99110-G9300 ', b'\xf1\x00IK__ SCC FHCUP 1.00 1.02 96400-G9000 ', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00IK MFC AT KOR LHD 1.00 1.01 95740-G9000 170920', b'\xf1\x00IK MFC AT USA LHD 1.00 1.01 95740-G9000 170920', + b'\xf1\x00IK MFC AT USA LHD 1.00 1.04 99211-G9000 220401', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x81606G2051\x00\x00\x00\x00\x00\x00\x00\x00', b'\xf1\x81640H0051\x00\x00\x00\x00\x00\x00\x00\x00', b'\xf1\x81640J0051\x00\x00\x00\x00\x00\x00\x00\x00', + b'\xf1\x81640N2051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, CAR.GENESIS_G80: { @@ -887,22 +900,25 @@ FW_VERSIONS = { }, CAR.GENESIS_G90: { (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x00bcsh8p54 E25\x00\x00\x00\x00\x00\x00\x00SHI0G50NH0\xff\x80\xc2*', b'\xf1\x87VDGMD15352242DD3w\x87gxwvgv\x87wvw\x88wXwffVfffUfw\x88o\xff\x06J\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcshcm49 E14\x00\x00\x00\x00\x00\x00\x00SHI0G50NB1tc5\xb7', b'\xf1\x87VDGMD15866192DD3x\x88x\x89wuFvvfUf\x88vWwgwwwvfVgx\x87o\xff\xbc^\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcshcm49 E14\x00\x00\x00\x00\x00\x00\x00SHI0G50NB1tc5\xb7', b'\xf1\x87VDHMD16446682DD3WwwxxvGw\x88\x88\x87\x88\x88whxx\x87\x87\x87\x85fUfwu_\xffT\xf8\xf1\x81E14\x00\x00\x00\x00\x00\x00\x00\xf1\x00bcshcm49 E14\x00\x00\x00\x00\x00\x00\x00SHI0G50NB1tc5\xb7', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00HI__ SCC F-CUP 1.00 1.01 96400-D2100 ', + b'\xf1\x00HI__ SCC FHCUP 1.00 1.02 99110-D2100 ', ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00HI LKAS AT USA LHD 1.00 1.00 95895-D2020 160302', b'\xf1\x00HI LKAS AT USA LHD 1.00 1.00 95895-D2030 170208', + b'\xf1\x00HI MFC AT USA LHD 1.00 1.03 99211-D2000 190831', ], (Ecu.engine, 0x7e0, None): [ b'\xf1\x810000000000\x00', ], }, - CAR.KONA: { + CAR.HYUNDAI_KONA: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00OS__ SCC F-CUP 1.00 1.00 95655-J9200 ', ], @@ -1047,7 +1063,7 @@ FW_VERSIONS = { b'\xf1\x00PSBG2333 E16\x00\x00\x00\x00\x00\x00\x00TDL2H20KA5T\xf2\xc9\xc2', ], }, - CAR.KONA_EV: { + CAR.HYUNDAI_KONA_EV: { (Ecu.abs, 0x7d1, None): [ b'\xf1\x00OS IEB \x01 212 \x11\x13 58520-K4000', b'\xf1\x00OS IEB \x02 212 \x11\x13 58520-K4000', @@ -1075,7 +1091,7 @@ FW_VERSIONS = { b'\xf1\x00OSev SCC FNCUP 1.00 1.01 99110-K4000 ', ], }, - CAR.KONA_EV_2022: { + CAR.HYUNDAI_KONA_EV_2022: { (Ecu.abs, 0x7d1, None): [ b'\xf1\x00OS IEB \x02 102"\x05\x16 58520-K4010', b'\xf1\x00OS IEB \x03 102"\x05\x16 58520-K4010', @@ -1104,7 +1120,7 @@ FW_VERSIONS = { b'\xf1\x00YB__ FCA ----- 1.00 1.01 99110-K4500 \x00\x00\x00', ], }, - CAR.KONA_EV_2ND_GEN: { + CAR.HYUNDAI_KONA_EV_2ND_GEN: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00SXev RDR ----- 1.00 1.00 99110-BF000 ', ], @@ -1304,7 +1320,7 @@ FW_VERSIONS = { b'\xf1\x816H6D1051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.ELANTRA: { + CAR.HYUNDAI_ELANTRA: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00AD LKAS AT USA LHD 1.01 1.01 95895-F2000 251', b'\xf1\x00ADP LKAS AT USA LHD 1.00 1.03 99211-F2000 X31', @@ -1331,7 +1347,7 @@ FW_VERSIONS = { b'\xf1\x00AD__ SCC H-CUP 1.00 1.01 96400-F2100 ', ], }, - CAR.ELANTRA_GT_I30: { + CAR.HYUNDAI_ELANTRA_GT_I30: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00PD LKAS AT KOR LHD 1.00 1.02 95740-G3000 A51', b'\xf1\x00PD LKAS AT USA LHD 1.00 1.02 95740-G3000 A51', @@ -1359,7 +1375,7 @@ FW_VERSIONS = { b'\xf1\x00PD__ SCC FNCUP 1.01 1.00 96400-G3000 ', ], }, - CAR.ELANTRA_2021: { + CAR.HYUNDAI_ELANTRA_2021: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00CN7_ SCC F-CUP 1.00 1.01 99110-AA000 ', b'\xf1\x00CN7_ SCC FHCUP 1.00 1.01 99110-AA000 ', @@ -1401,7 +1417,7 @@ FW_VERSIONS = { b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M2_0a0_HC0', ], }, - CAR.ELANTRA_HEV_2021: { + CAR.HYUNDAI_ELANTRA_HEV_2021: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00CN7HMFC AT USA LHD 1.00 1.03 99210-AA000 200819', b'\xf1\x00CN7HMFC AT USA LHD 1.00 1.05 99210-AA000 210930', @@ -1432,7 +1448,7 @@ FW_VERSIONS = { b'\xf1\x816H6G8051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.KONA_HEV: { + CAR.HYUNDAI_KONA_HEV: { (Ecu.abs, 0x7d1, None): [ b'\xf1\x00OS IEB \x01 104 \x11 58520-CM000', ], @@ -1452,7 +1468,7 @@ FW_VERSIONS = { b'\xf1\x816H6F6051\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.SONATA_HYBRID: { + CAR.HYUNDAI_SONATA_HYBRID: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DNhe SCC F-CUP 1.00 1.02 99110-L5000 ', b'\xf1\x00DNhe SCC FHCUP 1.00 1.00 99110-L5000 ', @@ -1528,7 +1544,7 @@ FW_VERSIONS = { b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.06 99210-CV000 220328', ], }, - CAR.IONIQ_5: { + CAR.HYUNDAI_IONIQ_5: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ', ], @@ -1548,7 +1564,7 @@ FW_VERSIONS = { b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.06 99211-GI010 230110', ], }, - CAR.IONIQ_6: { + CAR.HYUNDAI_IONIQ_6: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00CE__ RDR ----- 1.00 1.01 99110-KL000 ', ], @@ -1558,7 +1574,7 @@ FW_VERSIONS = { b'\xf1\x00CE MFC AT USA LHD 1.00 1.04 99211-KL000 221213', ], }, - CAR.TUCSON_4TH_GEN: { + CAR.HYUNDAI_TUCSON_4TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NX4 FR_CMR AT CAN LHD 1.00 1.01 99211-N9100 14A', b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 1.00 99211-N9220 14K', @@ -1578,10 +1594,11 @@ FW_VERSIONS = { b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ', ], }, - CAR.SANTA_CRUZ_1ST_GEN: { + CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW000 14M', b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW010 14X', + b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW020 14Z', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NX4__ 1.00 1.00 99110-K5000 ', @@ -1595,6 +1612,7 @@ FW_VERSIONS = { b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1030 662', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1040 663', b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1060 665', + b'\xf1\x00NQ5 FR_CMR AT USA LHD 1.00 1.00 99211-P1070 690', ], (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00NQ5__ 1.00 1.02 99110-P1000 ', @@ -1690,7 +1708,7 @@ FW_VERSIONS = { b'\xf1\x00GL3_ RDR ----- 1.00 1.02 99110-L8000 ', ], }, - CAR.STARIA_4TH_GEN: { + CAR.HYUNDAI_STARIA_4TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00US4 MFC AT KOR LHD 1.00 1.06 99211-CG000 230524', ], diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py index 0bf29664e8..fe43def2ae 100644 --- a/selfdrive/car/hyundai/hyundaican.py +++ b/selfdrive/car/hyundai/hyundaican.py @@ -33,12 +33,12 @@ def create_lkas11(packer, frame, CP, apply_steer, steer_req, values["CF_Lkas_ToiFlt"] = torque_fault # seems to allow actuation on CR_Lkas_StrToqReq values["CF_Lkas_MsgCount"] = frame % 0x10 - if CP.carFingerprint in (CAR.SONATA, CAR.PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.SANTA_FE, - CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020, - CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022, - CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, - CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED, - CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.CUSTIN_1ST_GEN): + if CP.carFingerprint in (CAR.HYUNDAI_SONATA, CAR.HYUNDAI_PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.HYUNDAI_SANTA_FE, + CAR.HYUNDAI_IONIQ_EV_2020, CAR.HYUNDAI_IONIQ_PHEV, CAR.KIA_SELTOS, CAR.HYUNDAI_ELANTRA_2021, CAR.GENESIS_G70_2020, + CAR.HYUNDAI_ELANTRA_HEV_2021, CAR.HYUNDAI_SONATA_HYBRID, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022, + CAR.HYUNDAI_SANTA_FE_2022, CAR.KIA_K5_2021, CAR.HYUNDAI_IONIQ_HEV_2022, CAR.HYUNDAI_SANTA_FE_HEV_2022, + CAR.HYUNDAI_SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED, + CAR.HYUNDAI_AZERA_6TH_GEN, CAR.HYUNDAI_AZERA_HEV_6TH_GEN, CAR.HYUNDAI_CUSTIN_1ST_GEN): values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1) values["CF_Lkas_LdwsOpt_USM"] = 2 @@ -126,12 +126,12 @@ def create_lfahda_mfc(packer, enabled, hda_set_speed=0): } return packer.make_can_msg("LFAHDA_MFC", 0, values) -def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, set_speed, stopping, long_override, use_fca): +def create_acc_commands(packer, enabled, accel, upper_jerk, idx, hud_control, set_speed, stopping, long_override, use_fca): commands = [] scc11_values = { "MainMode_ACC": 1, - "TauGapSet": 4, + "TauGapSet": hud_control.leadDistanceBars + 1, "VSetDis": set_speed if enabled else 0, "AliveCounterACC": idx % 0x10, "ObjValid": 1, # close lead makes controls tighter @@ -167,7 +167,7 @@ def create_acc_commands(packer, enabled, accel, upper_jerk, idx, lead_visible, s "JerkUpperLimit": upper_jerk, # stock usually is 1.0 but sometimes uses higher values "JerkLowerLimit": 5.0, # stock usually is 0.5 but sometimes uses higher values "ACCMode": 2 if enabled and long_override else 1 if enabled else 4, # stock will always be 4 instead of 0 after first disengage - "ObjGap": 2 if lead_visible else 0, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead + "ObjGap": 2 if hud_control.leadVisible else 0, # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead } commands.append(packer.make_can_msg("SCC14", 0, scc14_values)) diff --git a/selfdrive/car/hyundai/hyundaicanfd.py b/selfdrive/car/hyundai/hyundaicanfd.py index a35fcb7779..17ec9dcdd2 100644 --- a/selfdrive/car/hyundai/hyundaicanfd.py +++ b/selfdrive/car/hyundai/hyundaicanfd.py @@ -121,7 +121,7 @@ def create_lfahda_cluster(packer, CAN, enabled): return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values) -def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed): +def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control): jerk = 5 jn = jerk / 50 if not enabled or gas_override: @@ -146,7 +146,7 @@ def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_ov "SET_ME_2": 0x4, "SET_ME_3": 0x3, "SET_ME_TMP_64": 0x64, - "DISTANCE_SETTING": 4, + "DISTANCE_SETTING": hud_control.leadDistanceBars + 1, } return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 69b5132806..00452a9ae0 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -132,7 +132,7 @@ class CarInterface(CarInterfaceBase): elif ret.flags & HyundaiFlags.EV: ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_EV_GAS - if candidate in (CAR.KONA, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022): + if candidate in (CAR.HYUNDAI_KONA, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022): ret.flags |= HyundaiFlags.ALT_LIMITS.value ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_ALT_LIMITS @@ -175,6 +175,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/hyundai/tests/test_hyundai.py b/selfdrive/car/hyundai/tests/test_hyundai.py index 61b11a1992..c9ec972313 100755 --- a/selfdrive/car/hyundai/tests/test_hyundai.py +++ b/selfdrive/car/hyundai/tests/test_hyundai.py @@ -18,22 +18,22 @@ ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} NO_DATES_PLATFORMS = { # CAN FD CAR.KIA_SPORTAGE_5TH_GEN, - CAR.SANTA_CRUZ_1ST_GEN, - CAR.TUCSON_4TH_GEN, + CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN, + CAR.HYUNDAI_TUCSON_4TH_GEN, # CAN - CAR.ELANTRA, - CAR.ELANTRA_GT_I30, + CAR.HYUNDAI_ELANTRA, + CAR.HYUNDAI_ELANTRA_GT_I30, CAR.KIA_CEED, CAR.KIA_FORTE, CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.KIA_SORENTO, - CAR.KONA, - CAR.KONA_EV, - CAR.KONA_EV_2022, - CAR.KONA_HEV, - CAR.SONATA_LF, - CAR.VELOSTER, + CAR.HYUNDAI_KONA, + CAR.HYUNDAI_KONA_EV, + CAR.HYUNDAI_KONA_EV_2022, + CAR.HYUNDAI_KONA_HEV, + CAR.HYUNDAI_SONATA_LF, + CAR.HYUNDAI_VELOSTER, } @@ -67,7 +67,7 @@ class TestHyundaiFingerprint(unittest.TestCase): # Tucson having Santa Cruz camera and EPS for example for car_model, ecus in FW_VERSIONS.items(): with self.subTest(car_model=car_model.value): - if car_model == CAR.SANTA_CRUZ_1ST_GEN: + if car_model == CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN: raise unittest.SkipTest("Skip checking Santa Cruz for its parts") for code, _ in get_platform_codes(ecus[(Ecu.fwdCamera, 0x7c4, None)]): @@ -108,9 +108,9 @@ class TestHyundaiFingerprint(unittest.TestCase): # Third and fourth character are usually EV/hybrid identifiers codes = {code.split(b"-")[0][:2] for code, _ in get_platform_codes(fws)} - if car_model == CAR.PALISADE: + if car_model == CAR.HYUNDAI_PALISADE: self.assertEqual(codes, {b"LX", b"ON"}, f"Car has unexpected platform codes: {car_model} {codes}") - elif car_model == CAR.KONA_EV and ecu[0] == Ecu.fwdCamera: + elif car_model == CAR.HYUNDAI_KONA_EV and ecu[0] == Ecu.fwdCamera: self.assertEqual(codes, {b"OE", b"OS"}, f"Car has unexpected platform codes: {car_model} {codes}") else: self.assertEqual(len(codes), 1, f"Car has multiple platform codes: {car_model} {codes}") @@ -120,7 +120,7 @@ class TestHyundaiFingerprint(unittest.TestCase): def test_platform_code_ecus_available(self): # TODO: add queries for these non-CAN FD cars to get EPS no_eps_platforms = CANFD_CAR | {CAR.KIA_SORENTO, CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.KIA_OPTIMA_H, - CAR.KIA_OPTIMA_H_G4_FL, CAR.SONATA_LF, CAR.TUCSON, CAR.GENESIS_G90, CAR.GENESIS_G80, CAR.ELANTRA} + CAR.KIA_OPTIMA_H_G4_FL, CAR.HYUNDAI_SONATA_LF, CAR.HYUNDAI_TUCSON, CAR.GENESIS_G90, CAR.GENESIS_G80, CAR.HYUNDAI_ELANTRA} # Asserts ECU keys essential for fuzzy fingerprinting are available on all platforms for car_model, ecus in FW_VERSIONS.items(): diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index e79da0f473..f1a3c3ebc6 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -6,7 +6,7 @@ from cereal import car from panda.python import uds from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16 Ecu = car.CarParams.Ecu @@ -35,8 +35,8 @@ class CarControllerParams: # To determine the limit for your car, find the maximum value that the stock LKAS will request. # If the max stock LKAS request is <384, add your car to this list. - elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.IONIQ, - CAR.IONIQ_EV_LTD, CAR.SANTA_FE_PHEV_2022, CAR.SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_PHEV, + elif CP.carFingerprint in (CAR.GENESIS_G80, CAR.GENESIS_G90, CAR.HYUNDAI_ELANTRA, CAR.HYUNDAI_ELANTRA_GT_I30, CAR.HYUNDAI_IONIQ, + CAR.HYUNDAI_IONIQ_EV_LTD, CAR.HYUNDAI_SANTA_FE_PHEV_2022, CAR.HYUNDAI_SONATA_LF, CAR.KIA_FORTE, CAR.KIA_NIRO_PHEV, CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.KIA_SORENTO): self.STEER_MAX = 255 @@ -104,7 +104,7 @@ class Footnote(Enum): @dataclass -class HyundaiCarInfo(CarInfo): +class HyundaiCarDocs(CarDocs): package: str = "Smart Cruise Control (SCC)" def init_make(self, CP: car.CarParams): @@ -134,418 +134,360 @@ class HyundaiCanFDPlatformConfig(PlatformConfig): class CAR(Platforms): # Hyundai - AZERA_6TH_GEN = HyundaiPlatformConfig( - "HYUNDAI AZERA 6TH GEN", - HyundaiCarInfo("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + HYUNDAI_AZERA_6TH_GEN = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=1600, wheelbase=2.885, steerRatio=14.5), ) - AZERA_HEV_6TH_GEN = HyundaiPlatformConfig( - "HYUNDAI AZERA HYBRID 6TH GEN", + HYUNDAI_AZERA_HEV_6TH_GEN = HyundaiPlatformConfig( [ - HyundaiCarInfo("Hyundai Azera Hybrid 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c])), - HyundaiCarInfo("Hyundai Azera Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + HyundaiCarDocs("Hyundai Azera Hybrid 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarDocs("Hyundai Azera Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), ], CarSpecs(mass=1675, wheelbase=2.885, steerRatio=14.5), flags=HyundaiFlags.HYBRID, ) - ELANTRA = HyundaiPlatformConfig( - "HYUNDAI ELANTRA 2017", + HYUNDAI_ELANTRA = HyundaiPlatformConfig( [ # TODO: 2017-18 could be Hyundai G - HyundaiCarInfo("Hyundai Elantra 2017-18", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])), - HyundaiCarInfo("Hyundai Elantra 2019", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_g])), + HyundaiCarDocs("Hyundai Elantra 2017-18", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])), + HyundaiCarDocs("Hyundai Elantra 2019", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_g])), ], # steerRatio: 14 is Stock | Settled Params Learner values are steerRatio: 15.401566348670535, stiffnessFactor settled on 1.0081302973865127 CarSpecs(mass=1275, wheelbase=2.7, steerRatio=15.4, tireStiffnessFactor=0.385), flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS | HyundaiFlags.MIN_STEER_32_MPH, ) - ELANTRA_GT_I30 = HyundaiPlatformConfig( - "HYUNDAI I30 N LINE 2019 & GT 2018 DCT", + HYUNDAI_ELANTRA_GT_I30 = HyundaiPlatformConfig( [ - HyundaiCarInfo("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), - HyundaiCarInfo("Hyundai i30 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), + HyundaiCarDocs("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), + HyundaiCarDocs("Hyundai i30 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])), ], - ELANTRA.specs, + HYUNDAI_ELANTRA.specs, flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS | HyundaiFlags.MIN_STEER_32_MPH, ) - ELANTRA_2021 = HyundaiPlatformConfig( - "HYUNDAI ELANTRA 2021", - HyundaiCarInfo("Hyundai Elantra 2021-23", video_link="https://youtu.be/_EdYQtV52-c", car_parts=CarParts.common([CarHarness.hyundai_k])), + HYUNDAI_ELANTRA_2021 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Elantra 2021-23", video_link="https://youtu.be/_EdYQtV52-c", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=2800 * CV.LB_TO_KG, wheelbase=2.72, steerRatio=12.9, tireStiffnessFactor=0.65), flags=HyundaiFlags.CHECKSUM_CRC8, ) - ELANTRA_HEV_2021 = HyundaiPlatformConfig( - "HYUNDAI ELANTRA HYBRID 2021", - HyundaiCarInfo("Hyundai Elantra Hybrid 2021-23", video_link="https://youtu.be/_EdYQtV52-c", - car_parts=CarParts.common([CarHarness.hyundai_k])), + HYUNDAI_ELANTRA_HEV_2021 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Elantra Hybrid 2021-23", video_link="https://youtu.be/_EdYQtV52-c", + car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=3017 * CV.LB_TO_KG, wheelbase=2.72, steerRatio=12.9, tireStiffnessFactor=0.65), flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) HYUNDAI_GENESIS = HyundaiPlatformConfig( - "HYUNDAI GENESIS 2015-2016", [ # TODO: check 2015 packages - HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])), - HyundaiCarInfo("Genesis G80 2017", "All", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])), + HyundaiCarDocs("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])), + HyundaiCarDocs("Genesis G80 2017", "All", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])), ], CarSpecs(mass=2060, wheelbase=3.01, steerRatio=16.5, minSteerSpeed=60 * CV.KPH_TO_MS), flags=HyundaiFlags.CHECKSUM_6B | HyundaiFlags.LEGACY, ) - IONIQ = HyundaiPlatformConfig( - "HYUNDAI IONIQ HYBRID 2017-2019", - HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", car_parts=CarParts.common([CarHarness.hyundai_c])), + HYUNDAI_IONIQ = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Hybrid 2017-19", car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID | HyundaiFlags.MIN_STEER_32_MPH, ) - IONIQ_HEV_2022 = HyundaiPlatformConfig( - "HYUNDAI IONIQ HYBRID 2020-2022", - HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_h])), # TODO: confirm 2020-21 harness, + HYUNDAI_IONIQ_HEV_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_h]))], # TODO: confirm 2020-21 harness, CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, ) - IONIQ_EV_LTD = HyundaiPlatformConfig( - "HYUNDAI IONIQ ELECTRIC LIMITED 2019", - HyundaiCarInfo("Hyundai Ioniq Electric 2019", car_parts=CarParts.common([CarHarness.hyundai_c])), + HYUNDAI_IONIQ_EV_LTD = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Electric 2019", car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.EV | HyundaiFlags.LEGACY | HyundaiFlags.MIN_STEER_32_MPH, ) - IONIQ_EV_2020 = HyundaiPlatformConfig( - "HYUNDAI IONIQ ELECTRIC 2020", - HyundaiCarInfo("Hyundai Ioniq Electric 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), + HYUNDAI_IONIQ_EV_2020 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Electric 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_h]))], CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.EV, ) - IONIQ_PHEV_2019 = HyundaiPlatformConfig( - "HYUNDAI IONIQ PLUG-IN HYBRID 2019", - HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_c])), + HYUNDAI_IONIQ_PHEV_2019 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Plug-in Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID | HyundaiFlags.MIN_STEER_32_MPH, ) - IONIQ_PHEV = HyundaiPlatformConfig( - "HYUNDAI IONIQ PHEV 2020", - HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), + HYUNDAI_IONIQ_PHEV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq Plug-in Hybrid 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h]))], CarSpecs(mass=1490, wheelbase=2.7, steerRatio=13.73, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID, ) - KONA = HyundaiPlatformConfig( - "HYUNDAI KONA 2020", - HyundaiCarInfo("Hyundai Kona 2020", car_parts=CarParts.common([CarHarness.hyundai_b])), + HYUNDAI_KONA = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Kona 2020", car_parts=CarParts.common([CarHarness.hyundai_b]))], CarSpecs(mass=1275, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.CLUSTER_GEARS, ) - KONA_EV = HyundaiPlatformConfig( - "HYUNDAI KONA ELECTRIC 2019", - HyundaiCarInfo("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g])), + HYUNDAI_KONA_EV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g]))], CarSpecs(mass=1685, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.EV, ) - KONA_EV_2022 = HyundaiPlatformConfig( - "HYUNDAI KONA ELECTRIC 2022", - HyundaiCarInfo("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o])), + HYUNDAI_KONA_EV_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o]))], CarSpecs(mass=1743, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.EV, ) - KONA_EV_2ND_GEN = HyundaiCanFDPlatformConfig( - "HYUNDAI KONA ELECTRIC 2ND GEN", - HyundaiCarInfo("Hyundai Kona Electric (with HDA II, Korea only) 2023", video_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw", - car_parts=CarParts.common([CarHarness.hyundai_r])), + HYUNDAI_KONA_EV_2ND_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Electric (with HDA II, Korea only) 2023", video_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw", + car_parts=CarParts.common([CarHarness.hyundai_r]))], CarSpecs(mass=1740, wheelbase=2.66, steerRatio=13.6, tireStiffnessFactor=0.385), flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE, ) - KONA_HEV = HyundaiPlatformConfig( - "HYUNDAI KONA HYBRID 2020", - HyundaiCarInfo("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i])), # TODO: check packages, + HYUNDAI_KONA_HEV = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i]))], # TODO: check packages, CarSpecs(mass=1425, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.HYBRID, ) - SANTA_FE = HyundaiPlatformConfig( - "HYUNDAI SANTA FE 2019", - HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", video_link="https://youtu.be/bjDR0YjM__s", - car_parts=CarParts.common([CarHarness.hyundai_d])), + HYUNDAI_SANTA_FE = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Fe 2019-20", "All", video_link="https://youtu.be/bjDR0YjM__s", + car_parts=CarParts.common([CarHarness.hyundai_d]))], CarSpecs(mass=3982 * CV.LB_TO_KG, wheelbase=2.766, steerRatio=16.55, tireStiffnessFactor=0.82), flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8, ) - SANTA_FE_2022 = HyundaiPlatformConfig( - "HYUNDAI SANTA FE 2022", - HyundaiCarInfo("Hyundai Santa Fe 2021-23", "All", video_link="https://youtu.be/VnHzSTygTS4", - car_parts=CarParts.common([CarHarness.hyundai_l])), - SANTA_FE.specs, + HYUNDAI_SANTA_FE_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Fe 2021-23", "All", video_link="https://youtu.be/VnHzSTygTS4", + car_parts=CarParts.common([CarHarness.hyundai_l]))], + HYUNDAI_SANTA_FE.specs, flags=HyundaiFlags.CHECKSUM_CRC8, ) - SANTA_FE_HEV_2022 = HyundaiPlatformConfig( - "HYUNDAI SANTA FE HYBRID 2022", - HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), - SANTA_FE.specs, + HYUNDAI_SANTA_FE_HEV_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))], + HYUNDAI_SANTA_FE.specs, flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) - SANTA_FE_PHEV_2022 = HyundaiPlatformConfig( - "HYUNDAI SANTA FE PlUG-IN HYBRID 2022", - HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), - SANTA_FE.specs, + HYUNDAI_SANTA_FE_PHEV_2022 = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l]))], + HYUNDAI_SANTA_FE.specs, flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) - SONATA = HyundaiPlatformConfig( - "HYUNDAI SONATA 2020", - HyundaiCarInfo("Hyundai Sonata 2020-23", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", - car_parts=CarParts.common([CarHarness.hyundai_a])), + HYUNDAI_SONATA = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata 2020-23", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", + car_parts=CarParts.common([CarHarness.hyundai_a]))], CarSpecs(mass=1513, wheelbase=2.84, steerRatio=13.27 * 1.15, tireStiffnessFactor=0.65), # 15% higher at the center seems reasonable flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8, ) - SONATA_LF = HyundaiPlatformConfig( - "HYUNDAI SONATA 2019", - HyundaiCarInfo("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e])), + HYUNDAI_SONATA_LF = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e]))], CarSpecs(mass=1536, wheelbase=2.804, steerRatio=13.27 * 1.15), # 15% higher at the center seems reasonable flags=HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.TCU_GEARS, ) - STARIA_4TH_GEN = HyundaiCanFDPlatformConfig( - "HYUNDAI STARIA 4TH GEN", - HyundaiCarInfo("Hyundai Staria 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + HYUNDAI_STARIA_4TH_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Staria 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=2205, wheelbase=3.273, steerRatio=11.94), # https://www.hyundai.com/content/dam/hyundai/au/en/models/staria-load/premium-pip-update-2023/spec-sheet/STARIA_Load_Spec-Table_March_2023_v3.1.pdf ) - TUCSON = HyundaiPlatformConfig( - "HYUNDAI TUCSON 2019", + HYUNDAI_TUCSON = HyundaiPlatformConfig( [ - HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_l])), - HyundaiCarInfo("Hyundai Tucson Diesel 2019", car_parts=CarParts.common([CarHarness.hyundai_l])), + HyundaiCarDocs("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_l])), + HyundaiCarDocs("Hyundai Tucson Diesel 2019", car_parts=CarParts.common([CarHarness.hyundai_l])), ], CarSpecs(mass=3520 * CV.LB_TO_KG, wheelbase=2.67, steerRatio=16.1, tireStiffnessFactor=0.385), flags=HyundaiFlags.TCU_GEARS, ) - PALISADE = HyundaiPlatformConfig( - "HYUNDAI PALISADE 2020", + HYUNDAI_PALISADE = HyundaiPlatformConfig( [ - HyundaiCarInfo("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", car_parts=CarParts.common([CarHarness.hyundai_h])), - HyundaiCarInfo("Kia Telluride 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), + HyundaiCarDocs("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", car_parts=CarParts.common([CarHarness.hyundai_h])), + HyundaiCarDocs("Kia Telluride 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), ], CarSpecs(mass=1999, wheelbase=2.9, steerRatio=15.6 * 1.15, tireStiffnessFactor=0.63), flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8, ) - VELOSTER = HyundaiPlatformConfig( - "HYUNDAI VELOSTER 2019", - HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_e])), + HYUNDAI_VELOSTER = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_e]))], CarSpecs(mass=2917 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75 * 1.15, tireStiffnessFactor=0.5), flags=HyundaiFlags.LEGACY | HyundaiFlags.TCU_GEARS, ) - SONATA_HYBRID = HyundaiPlatformConfig( - "HYUNDAI SONATA HYBRID 2021", - HyundaiCarInfo("Hyundai Sonata Hybrid 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), - SONATA.specs, + HYUNDAI_SONATA_HYBRID = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata Hybrid 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], + HYUNDAI_SONATA.specs, flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) - IONIQ_5 = HyundaiCanFDPlatformConfig( - "HYUNDAI IONIQ 5 2022", + HYUNDAI_IONIQ_5 = HyundaiCanFDPlatformConfig( [ - HyundaiCarInfo("Hyundai Ioniq 5 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_q])), - HyundaiCarInfo("Hyundai Ioniq 5 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_k])), - HyundaiCarInfo("Hyundai Ioniq 5 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), + HyundaiCarDocs("Hyundai Ioniq 5 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_q])), + HyundaiCarDocs("Hyundai Ioniq 5 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_k])), + HyundaiCarDocs("Hyundai Ioniq 5 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), ], CarSpecs(mass=1948, wheelbase=2.97, steerRatio=14.26, tireStiffnessFactor=0.65), flags=HyundaiFlags.EV, ) - IONIQ_6 = HyundaiCanFDPlatformConfig( - "HYUNDAI IONIQ 6 2023", - HyundaiCarInfo("Hyundai Ioniq 6 (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])), - IONIQ_5.specs, + HYUNDAI_IONIQ_6 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Ioniq 6 (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))], + HYUNDAI_IONIQ_5.specs, flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE, ) - TUCSON_4TH_GEN = HyundaiCanFDPlatformConfig( - "HYUNDAI TUCSON 4TH GEN", + HYUNDAI_TUCSON_4TH_GEN = HyundaiCanFDPlatformConfig( [ - HyundaiCarInfo("Hyundai Tucson 2022", car_parts=CarParts.common([CarHarness.hyundai_n])), - HyundaiCarInfo("Hyundai Tucson 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_n])), - HyundaiCarInfo("Hyundai Tucson Hybrid 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_n])), + HyundaiCarDocs("Hyundai Tucson 2022", car_parts=CarParts.common([CarHarness.hyundai_n])), + HyundaiCarDocs("Hyundai Tucson 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_n])), + HyundaiCarDocs("Hyundai Tucson Hybrid 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_n])), ], - CarSpecs(mass=1630, wheelbase=2.756, steerRatio=16, tireStiffnessFactor=0.385), + CarSpecs(mass=1630, wheelbase=2.756, steerRatio=13.7, tireStiffnessFactor=0.385), ) - SANTA_CRUZ_1ST_GEN = HyundaiCanFDPlatformConfig( - "HYUNDAI SANTA CRUZ 1ST GEN", - HyundaiCarInfo("Hyundai Santa Cruz 2022-23", car_parts=CarParts.common([CarHarness.hyundai_n])), + HYUNDAI_SANTA_CRUZ_1ST_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Cruz 2022-24", car_parts=CarParts.common([CarHarness.hyundai_n]))], # weight from Limited trim - the only supported trim, steering ratio according to Hyundai News https://www.hyundainews.com/assets/documents/original/48035-2022SantaCruzProductGuideSpecsv2081521.pdf CarSpecs(mass=1870, wheelbase=3, steerRatio=14.2), ) - CUSTIN_1ST_GEN = HyundaiPlatformConfig( - "HYUNDAI CUSTIN 1ST GEN", - HyundaiCarInfo("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + HYUNDAI_CUSTIN_1ST_GEN = HyundaiPlatformConfig( + [HyundaiCarDocs("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=1690, wheelbase=3.055, steerRatio=17), # mass: from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0, steerRatio: from learner flags=HyundaiFlags.CHECKSUM_CRC8, ) # Kia KIA_FORTE = HyundaiPlatformConfig( - "KIA FORTE E 2018 & GT 2021", [ - HyundaiCarInfo("Kia Forte 2019-21", car_parts=CarParts.common([CarHarness.hyundai_g])), - HyundaiCarInfo("Kia Forte 2023", car_parts=CarParts.common([CarHarness.hyundai_e])), + HyundaiCarDocs("Kia Forte 2019-21", car_parts=CarParts.common([CarHarness.hyundai_g])), + HyundaiCarDocs("Kia Forte 2023", car_parts=CarParts.common([CarHarness.hyundai_e])), ], CarSpecs(mass=2878 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5) ) KIA_K5_2021 = HyundaiPlatformConfig( - "KIA K5 2021", - HyundaiCarInfo("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a])), + [HyundaiCarDocs("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a]))], CarSpecs(mass=3381 * CV.LB_TO_KG, wheelbase=2.85, steerRatio=13.27, tireStiffnessFactor=0.5), # 2021 Kia K5 Steering Ratio (all trims) flags=HyundaiFlags.CHECKSUM_CRC8, ) KIA_K5_HEV_2020 = HyundaiPlatformConfig( - "KIA K5 HYBRID 2020", - HyundaiCarInfo("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a])), + [HyundaiCarDocs("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a]))], KIA_K5_2021.specs, flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) KIA_K8_HEV_1ST_GEN = HyundaiCanFDPlatformConfig( - "KIA K8 HYBRID 1ST GEN", - HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])), + [HyundaiCarDocs("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q]))], # mass: https://carprices.ae/brands/kia/2023/k8/1.6-turbo-hybrid, steerRatio: guesstimate from K5 platform CarSpecs(mass=1630, wheelbase=2.895, steerRatio=13.27) ) KIA_NIRO_EV = HyundaiPlatformConfig( - "KIA NIRO EV 2020", [ - HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), - HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])), - HyundaiCarInfo("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_c])), - HyundaiCarInfo("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), + HyundaiCarDocs("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), + HyundaiCarDocs("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])), + HyundaiCarDocs("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarDocs("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])), ], CarSpecs(mass=3543 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=13.6, tireStiffnessFactor=0.385), # average of all the cars flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.EV, ) KIA_NIRO_EV_2ND_GEN = HyundaiCanFDPlatformConfig( - "KIA NIRO EV 2ND GEN", - HyundaiCarInfo("Kia Niro EV 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), + [HyundaiCarDocs("Kia Niro EV 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a]))], KIA_NIRO_EV.specs, flags=HyundaiFlags.EV, ) KIA_NIRO_PHEV = HyundaiPlatformConfig( - "KIA NIRO HYBRID 2019", [ - HyundaiCarInfo("Kia Niro Hybrid 2018", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), - HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), - HyundaiCarInfo("Kia Niro Plug-in Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_d])), + HyundaiCarDocs("Kia Niro Hybrid 2018", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarDocs("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])), + HyundaiCarDocs("Kia Niro Plug-in Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_d])), ], KIA_NIRO_EV.specs, flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.HYBRID | HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.MIN_STEER_32_MPH, ) KIA_NIRO_PHEV_2022 = HyundaiPlatformConfig( - "KIA NIRO PLUG-IN HYBRID 2022", [ - HyundaiCarInfo("Kia Niro Plug-in Hybrid 2021", "All", car_parts=CarParts.common([CarHarness.hyundai_d])), - HyundaiCarInfo("Kia Niro Plug-in Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_f])), + HyundaiCarDocs("Kia Niro Plug-in Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_d])), + HyundaiCarDocs("Kia Niro Plug-in Hybrid 2022", car_parts=CarParts.common([CarHarness.hyundai_f])), ], KIA_NIRO_EV.specs, flags=HyundaiFlags.HYBRID | HyundaiFlags.MANDO_RADAR, ) KIA_NIRO_HEV_2021 = HyundaiPlatformConfig( - "KIA NIRO HYBRID 2021", [ - HyundaiCarInfo("Kia Niro Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_d])), - HyundaiCarInfo("Kia Niro Hybrid 2022", car_parts=CarParts.common([CarHarness.hyundai_f])), + HyundaiCarDocs("Kia Niro Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_d])), + HyundaiCarDocs("Kia Niro Hybrid 2022", car_parts=CarParts.common([CarHarness.hyundai_f])), ], KIA_NIRO_EV.specs, flags=HyundaiFlags.HYBRID, ) KIA_NIRO_HEV_2ND_GEN = HyundaiCanFDPlatformConfig( - "KIA NIRO HYBRID 2ND GEN", - HyundaiCarInfo("Kia Niro Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_a])), + [HyundaiCarDocs("Kia Niro Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_a]))], KIA_NIRO_EV.specs, ) KIA_OPTIMA_G4 = HyundaiPlatformConfig( - "KIA OPTIMA 4TH GEN", - HyundaiCarInfo("Kia Optima 2017", "Advanced Smart Cruise Control", - car_parts=CarParts.common([CarHarness.hyundai_b])), # TODO: may support 2016, 2018 + [HyundaiCarDocs("Kia Optima 2017", "Advanced Smart Cruise Control", + car_parts=CarParts.common([CarHarness.hyundai_b]))], # TODO: may support 2016, 2018 CarSpecs(mass=3558 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.LEGACY | HyundaiFlags.TCU_GEARS | HyundaiFlags.MIN_STEER_32_MPH, ) KIA_OPTIMA_G4_FL = HyundaiPlatformConfig( - "KIA OPTIMA 4TH GEN FACELIFT", - HyundaiCarInfo("Kia Optima 2019-20", car_parts=CarParts.common([CarHarness.hyundai_g])), + [HyundaiCarDocs("Kia Optima 2019-20", car_parts=CarParts.common([CarHarness.hyundai_g]))], CarSpecs(mass=3558 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.TCU_GEARS, ) # TODO: may support adjacent years. may have a non-zero minimum steering speed KIA_OPTIMA_H = HyundaiPlatformConfig( - "KIA OPTIMA HYBRID 2017 & SPORTS 2019", - HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c])), + [HyundaiCarDocs("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=3558 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY, ) KIA_OPTIMA_H_G4_FL = HyundaiPlatformConfig( - "KIA OPTIMA HYBRID 4TH GEN FACELIFT", - HyundaiCarInfo("Kia Optima Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_h])), + [HyundaiCarDocs("Kia Optima Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_h]))], CarSpecs(mass=3558 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.HYBRID | HyundaiFlags.UNSUPPORTED_LONGITUDINAL, ) KIA_SELTOS = HyundaiPlatformConfig( - "KIA SELTOS 2021", - HyundaiCarInfo("Kia Seltos 2021", car_parts=CarParts.common([CarHarness.hyundai_a])), + [HyundaiCarDocs("Kia Seltos 2021", car_parts=CarParts.common([CarHarness.hyundai_a]))], CarSpecs(mass=1337, wheelbase=2.63, steerRatio=14.56), flags=HyundaiFlags.CHECKSUM_CRC8, ) KIA_SPORTAGE_5TH_GEN = HyundaiCanFDPlatformConfig( - "KIA SPORTAGE 5TH GEN", [ - HyundaiCarInfo("Kia Sportage 2023", car_parts=CarParts.common([CarHarness.hyundai_n])), - HyundaiCarInfo("Kia Sportage Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_n])), + HyundaiCarDocs("Kia Sportage 2023-24", car_parts=CarParts.common([CarHarness.hyundai_n])), + HyundaiCarDocs("Kia Sportage Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_n])), ], # weight from SX and above trims, average of FWD and AWD version, steering ratio according to Kia News https://www.kiamedia.com/us/en/models/sportage/2023/specifications CarSpecs(mass=1725, wheelbase=2.756, steerRatio=13.6), ) KIA_SORENTO = HyundaiPlatformConfig( - "KIA SORENTO GT LINE 2018", [ - HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control & LKAS", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", + HyundaiCarDocs("Kia Sorento 2018", "Advanced Smart Cruise Control & LKAS", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])), - HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])), + HyundaiCarDocs("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])), ], CarSpecs(mass=1985, wheelbase=2.78, steerRatio=14.4 * 1.1), # 10% higher at the center seems reasonable flags=HyundaiFlags.CHECKSUM_6B | HyundaiFlags.UNSUPPORTED_LONGITUDINAL, ) KIA_SORENTO_4TH_GEN = HyundaiCanFDPlatformConfig( - "KIA SORENTO 4TH GEN", - HyundaiCarInfo("Kia Sorento 2021-23", car_parts=CarParts.common([CarHarness.hyundai_k])), + [HyundaiCarDocs("Kia Sorento 2021-23", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=3957 * CV.LB_TO_KG, wheelbase=2.81, steerRatio=13.5), # average of the platforms flags=HyundaiFlags.RADAR_SCC, ) KIA_SORENTO_HEV_4TH_GEN = HyundaiCanFDPlatformConfig( - "KIA SORENTO HYBRID 4TH GEN", [ - HyundaiCarInfo("Kia Sorento Hybrid 2021-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), - HyundaiCarInfo("Kia Sorento Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), + HyundaiCarDocs("Kia Sorento Hybrid 2021-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), + HyundaiCarDocs("Kia Sorento Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), ], CarSpecs(mass=4395 * CV.LB_TO_KG, wheelbase=2.81, steerRatio=13.5), # average of the platforms flags=HyundaiFlags.RADAR_SCC, ) KIA_STINGER = HyundaiPlatformConfig( - "KIA STINGER GT2 2018", - HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", - car_parts=CarParts.common([CarHarness.hyundai_c])), + [HyundaiCarDocs("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", + car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=1825, wheelbase=2.78, steerRatio=14.4 * 1.15) # 15% higher at the center seems reasonable ) KIA_STINGER_2022 = HyundaiPlatformConfig( - "KIA STINGER 2022", - HyundaiCarInfo("Kia Stinger 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + [HyundaiCarDocs("Kia Stinger 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], KIA_STINGER.specs, ) KIA_CEED = HyundaiPlatformConfig( - "KIA CEED INTRO ED 2019", - HyundaiCarInfo("Kia Ceed 2019", car_parts=CarParts.common([CarHarness.hyundai_e])), + [HyundaiCarDocs("Kia Ceed 2019", car_parts=CarParts.common([CarHarness.hyundai_e]))], CarSpecs(mass=1450, wheelbase=2.65, steerRatio=13.75, tireStiffnessFactor=0.5), flags=HyundaiFlags.LEGACY, ) KIA_EV6 = HyundaiCanFDPlatformConfig( - "KIA EV6 2022", [ - HyundaiCarInfo("Kia EV6 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_p])), - HyundaiCarInfo("Kia EV6 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_l])), - HyundaiCarInfo("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])) + HyundaiCarDocs("Kia EV6 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_p])), + HyundaiCarDocs("Kia EV6 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_l])), + HyundaiCarDocs("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])) ], CarSpecs(mass=2055, wheelbase=2.9, steerRatio=16, tireStiffnessFactor=0.65), flags=HyundaiFlags.EV, ) KIA_CARNIVAL_4TH_GEN = HyundaiCanFDPlatformConfig( - "KIA CARNIVAL 4TH GEN", [ - HyundaiCarInfo("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])), - HyundaiCarInfo("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k])) + HyundaiCarDocs("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])), + HyundaiCarDocs("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k])) ], CarSpecs(mass=2087, wheelbase=3.09, steerRatio=14.23), flags=HyundaiFlags.RADAR_SCC, @@ -553,49 +495,42 @@ class CAR(Platforms): # Genesis GENESIS_GV60_EV_1ST_GEN = HyundaiCanFDPlatformConfig( - "GENESIS GV60 ELECTRIC 1ST GEN", [ - HyundaiCarInfo("Genesis GV60 (Advanced Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), - HyundaiCarInfo("Genesis GV60 (Performance Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), + HyundaiCarDocs("Genesis GV60 (Advanced Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), + HyundaiCarDocs("Genesis GV60 (Performance Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])), ], CarSpecs(mass=2205, wheelbase=2.9, steerRatio=12.6), # steerRatio: https://www.motor1.com/reviews/586376/2023-genesis-gv60-first-drive/#:~:text=Relative%20to%20the%20related%20Ioniq,5%2FEV6%27s%2014.3%3A1. flags=HyundaiFlags.EV, ) GENESIS_G70 = HyundaiPlatformConfig( - "GENESIS G70 2018", - HyundaiCarInfo("Genesis G70 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_f])), + [HyundaiCarDocs("Genesis G70 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_f]))], CarSpecs(mass=1640, wheelbase=2.84, steerRatio=13.56), flags=HyundaiFlags.LEGACY, ) GENESIS_G70_2020 = HyundaiPlatformConfig( - "GENESIS G70 2020", - HyundaiCarInfo("Genesis G70 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_f])), + [HyundaiCarDocs("Genesis G70 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_f]))], CarSpecs(mass=3673 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=12.9), flags=HyundaiFlags.MANDO_RADAR, ) GENESIS_GV70_1ST_GEN = HyundaiCanFDPlatformConfig( - "GENESIS GV70 1ST GEN", [ - HyundaiCarInfo("Genesis GV70 (2.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), - HyundaiCarInfo("Genesis GV70 (3.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_m])), + HyundaiCarDocs("Genesis GV70 (2.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])), + HyundaiCarDocs("Genesis GV70 (3.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_m])), ], CarSpecs(mass=1950, wheelbase=2.87, steerRatio=14.6), flags=HyundaiFlags.RADAR_SCC, ) GENESIS_G80 = HyundaiPlatformConfig( - "GENESIS G80 2017", - HyundaiCarInfo("Genesis G80 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_h])), + [HyundaiCarDocs("Genesis G80 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_h]))], CarSpecs(mass=2060, wheelbase=3.01, steerRatio=16.5), flags=HyundaiFlags.LEGACY, ) GENESIS_G90 = HyundaiPlatformConfig( - "GENESIS G90 2017", - HyundaiCarInfo("Genesis G90 2017-18", "All", car_parts=CarParts.common([CarHarness.hyundai_c])), + [HyundaiCarDocs("Genesis G90 2017-20", "All", car_parts=CarParts.common([CarHarness.hyundai_c]))], CarSpecs(mass=2200, wheelbase=3.15, steerRatio=12.069), ) GENESIS_GV80 = HyundaiCanFDPlatformConfig( - "GENESIS GV80 2023", - HyundaiCarInfo("Genesis GV80 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_m])), + [HyundaiCarDocs("Genesis GV80 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_m]))], CarSpecs(mass=2258, wheelbase=2.95, steerRatio=14.14), flags=HyundaiFlags.RADAR_SCC, ) @@ -701,7 +636,9 @@ DATE_FW_PATTERN = re.compile(b'(?<=[ -])([0-9]{6}$)') PART_NUMBER_FW_PATTERN = re.compile(b'(?<=[0-9][.,][0-9]{2} )([0-9]{5}[-/]?[A-Z][A-Z0-9]{3}[0-9])') # We've seen both ICE and hybrid for these platforms, and they have hybrid descriptors (e.g. MQ4 vs MQ4H) -CANFD_FUZZY_WHITELIST = {CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN} +CANFD_FUZZY_WHITELIST = {CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KIA_K8_HEV_1ST_GEN, + # TODO: the hybrid variant is not out yet + CAR.KIA_CARNIVAL_4TH_GEN} # List of ECUs expected to have platform codes, camera and radar should exist on all cars # TODO: use abs, it has the platform code and part number on many platforms @@ -806,9 +743,9 @@ FW_QUERY_CONFIG = FwQueryConfig( # We lose these ECUs without the comma power on these cars. # Note that we still attempt to match with them when they are present non_essential_ecus={ - Ecu.transmission: [CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.PALISADE, CAR.SONATA], - Ecu.engine: [CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.PALISADE, CAR.SONATA], - Ecu.abs: [CAR.PALISADE, CAR.SONATA], + Ecu.transmission: [CAR.HYUNDAI_AZERA_6TH_GEN, CAR.HYUNDAI_AZERA_HEV_6TH_GEN, CAR.HYUNDAI_PALISADE, CAR.HYUNDAI_SONATA], + Ecu.engine: [CAR.HYUNDAI_AZERA_6TH_GEN, CAR.HYUNDAI_AZERA_HEV_6TH_GEN, CAR.HYUNDAI_PALISADE, CAR.HYUNDAI_SONATA], + Ecu.abs: [CAR.HYUNDAI_PALISADE, CAR.HYUNDAI_SONATA], }, extra_ecus=[ (Ecu.adas, 0x730, None), # ADAS Driving ECU on HDA2 platforms diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 9e9e668981..b6a626edec 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -14,7 +14,7 @@ from openpilot.common.simple_kalman import KF1D, get_kalman_gain from openpilot.common.numpy_fast import clip from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG -from openpilot.selfdrive.car.values import Platform +from openpilot.selfdrive.car.values import PLATFORMS from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction from openpilot.selfdrive.controls.lib.events import Events from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel @@ -81,45 +81,44 @@ class CarInterfaceBase(ABC): self.silent_steer_warning = True self.v_ego_cluster_seen = False - self.CS = None - self.can_parsers = [] - if CarState is not None: - self.CS = CarState(CP) + self.CS = CarState(CP) + self.cp = self.CS.get_can_parser(CP) + self.cp_cam = self.CS.get_cam_can_parser(CP) + self.cp_adas = self.CS.get_adas_can_parser(CP) + self.cp_body = self.CS.get_body_can_parser(CP) + self.cp_loopback = self.CS.get_loopback_can_parser(CP) + self.can_parsers = [self.cp, self.cp_cam, self.cp_adas, self.cp_body, self.cp_loopback] - self.cp = self.CS.get_can_parser(CP) - self.cp_cam = self.CS.get_cam_can_parser(CP) - self.cp_adas = self.CS.get_adas_can_parser(CP) - self.cp_body = self.CS.get_body_can_parser(CP) - self.cp_loopback = self.CS.get_loopback_can_parser(CP) - self.can_parsers = [self.cp, self.cp_cam, self.cp_adas, self.cp_body, self.cp_loopback] + dbc_name = "" if self.cp is None else self.cp.dbc_name + self.CC: CarControllerBase = CarController(dbc_name, CP, self.VM) - self.CC = None - if CarController is not None: - self.CC = CarController(self.cp.dbc_name, CP, self.VM) + def apply(self, c: car.CarControl, now_nanos: int) -> tuple[car.CarControl.Actuators, list[tuple[int, int, bytes, int]]]: + return self.CC.update(c, self.CS, now_nanos) @staticmethod def get_pid_accel_limits(CP, current_speed, cruise_speed): return ACCEL_MIN, ACCEL_MAX @classmethod - def get_non_essential_params(cls, candidate: Platform): + def get_non_essential_params(cls, candidate: str): """ Parameters essential to controlling the car may be incomplete or wrong without FW versions or fingerprints. """ return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False) @classmethod - def get_params(cls, candidate: Platform, fingerprint: dict[int, dict[int, int]], car_fw: list[car.CarParams.CarFw], experimental_long: bool, docs: bool): + def get_params(cls, candidate: str, fingerprint: dict[int, dict[int, int]], car_fw: list[car.CarParams.CarFw], experimental_long: bool, docs: bool): ret = CarInterfaceBase.get_std_params(candidate) - ret.mass = candidate.config.specs.mass - ret.wheelbase = candidate.config.specs.wheelbase - ret.steerRatio = candidate.config.specs.steerRatio - ret.centerToFront = ret.wheelbase * candidate.config.specs.centerToFrontRatio - ret.minEnableSpeed = candidate.config.specs.minEnableSpeed - ret.minSteerSpeed = candidate.config.specs.minSteerSpeed - ret.tireStiffnessFactor = candidate.config.specs.tireStiffnessFactor - ret.flags |= int(candidate.config.flags) + platform = PLATFORMS[candidate] + ret.mass = platform.config.specs.mass + ret.wheelbase = platform.config.specs.wheelbase + ret.steerRatio = platform.config.specs.steerRatio + ret.centerToFront = ret.wheelbase * platform.config.specs.centerToFrontRatio + ret.minEnableSpeed = platform.config.specs.minEnableSpeed + ret.minSteerSpeed = platform.config.specs.minSteerSpeed + ret.tireStiffnessFactor = platform.config.specs.tireStiffnessFactor + ret.flags |= int(platform.config.flags) ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs) @@ -249,9 +248,6 @@ class CarInterfaceBase(ABC): return reader - @abstractmethod - def apply(self, c: car.CarControl, now_nanos: int) -> tuple[car.CarControl.Actuators, list[bytes]]: - pass def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)): @@ -437,6 +433,10 @@ class CarStateBase(ABC): } return d.get(gear.upper(), GearShifter.unknown) + @staticmethod + def get_can_parser(CP): + return None + @staticmethod def get_cam_can_parser(CP): return None @@ -458,8 +458,11 @@ SendCan = tuple[int, int, bytes, int] class CarControllerBase(ABC): + def __init__(self, dbc_name: str, CP, VM): + pass + @abstractmethod - def update(self, CC, CS, now_nanos) -> tuple[car.CarControl.Actuators, list[SendCan]]: + def update(self, CC: car.CarControl.Actuators, CS: car.CarState, now_nanos: int) -> tuple[car.CarControl.Actuators, list[SendCan]]: pass diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py index 37a67ecd93..83b238fb68 100644 --- a/selfdrive/car/mazda/carstate.py +++ b/selfdrive/car/mazda/carstate.py @@ -18,9 +18,16 @@ class CarState(CarStateBase): self.lkas_allowed_speed = False self.lkas_disabled = False + self.prev_distance_button = 0 + self.distance_button = 0 + def update(self, cp, cp_cam): ret = car.CarState.new_message() + + self.prev_distance_button = self.distance_button + self.distance_button = cp.vl["CRZ_BTNS"]["DISTANCE_LESS"] + ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["WHEEL_SPEEDS"]["FL"], cp.vl["WHEEL_SPEEDS"]["FR"], diff --git a/selfdrive/car/mazda/fingerprints.py b/selfdrive/car/mazda/fingerprints.py index 292f407935..e7396d566e 100644 --- a/selfdrive/car/mazda/fingerprints.py +++ b/selfdrive/car/mazda/fingerprints.py @@ -4,12 +4,13 @@ from openpilot.selfdrive.car.mazda.values import CAR Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.CX5_2022: { + CAR.MAZDA_CX5_2022: { (Ecu.eps, 0x730, None): [ b'KSD5-3210X-C-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], (Ecu.engine, 0x7e0, None): [ b'PEW5-188K2-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PW67-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2H-188K2-J\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -31,6 +32,7 @@ FW_VERSIONS = { ], (Ecu.transmission, 0x7e1, None): [ b'PG69-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', + b'PW66-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXDL-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXFG-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PXFG-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -39,7 +41,7 @@ FW_VERSIONS = { b'SH51-21PS1-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.CX5: { + CAR.MAZDA_CX5: { (Ecu.eps, 0x730, None): [ b'K319-3210X-A-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'KCB8-3210X-B-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -108,7 +110,7 @@ FW_VERSIONS = { b'SH9T-21PS1-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.CX9: { + CAR.MAZDA_CX9: { (Ecu.eps, 0x730, None): [ b'K070-3210X-C-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'KJ01-3210X-G-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -158,7 +160,7 @@ FW_VERSIONS = { b'PYFM-21PS1-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.MAZDA3: { + CAR.MAZDA_3: { (Ecu.eps, 0x730, None): [ b'BHN1-3210X-J-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'K070-3210X-C-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -193,7 +195,7 @@ FW_VERSIONS = { b'PYKE-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.MAZDA6: { + CAR.MAZDA_6: { (Ecu.eps, 0x730, None): [ b'GBEF-3210X-B-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'GBEF-3210X-C-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', @@ -225,7 +227,7 @@ FW_VERSIONS = { b'PYH7-21PS1-B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], }, - CAR.CX9_2021: { + CAR.MAZDA_CX9_2021: { (Ecu.eps, 0x730, None): [ b'TC3M-3210X-A-00\x00\x00\x00\x00\x00\x00\x00\x00\x00', ], diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 85be0166ce..6992d49ffe 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -2,7 +2,7 @@ from cereal import car from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS -from openpilot.selfdrive.car import get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -16,14 +16,14 @@ class CarInterface(CarInterfaceBase): ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.mazda)] ret.radarUnavailable = True - ret.dashcamOnly = candidate not in (CAR.CX5_2022, CAR.CX9_2021) + ret.dashcamOnly = candidate not in (CAR.MAZDA_CX5_2022, CAR.MAZDA_CX9_2021) ret.steerActuatorDelay = 0.1 ret.steerLimitTimer = 0.8 CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - if candidate not in (CAR.CX5_2022, ): + if candidate not in (CAR.MAZDA_CX5_2022, ): ret.minSteerSpeed = LKAS_LIMITS.DISABLE_SPEED * CV.KPH_TO_MS ret.centerToFront = ret.wheelbase * 0.41 @@ -34,6 +34,9 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) + # TODO: add button types for inc and dec + ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + # events events = self.create_common_events(ret) @@ -45,6 +48,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index b55690f39a..a8c808d582 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -4,7 +4,7 @@ from enum import IntFlag from cereal import car from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarHarness, CarInfo, CarParts +from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarParts from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -27,7 +27,7 @@ class CarControllerParams: @dataclass -class MazdaCarInfo(CarInfo): +class MazdaCarDocs(CarDocs): package: str = "All" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.mazda])) @@ -50,35 +50,29 @@ class MazdaPlatformConfig(PlatformConfig): class CAR(Platforms): - CX5 = MazdaPlatformConfig( - "MAZDA CX-5", - MazdaCarInfo("Mazda CX-5 2017-21"), + MAZDA_CX5 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda CX-5 2017-21")], MazdaCarSpecs(mass=3655 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.5) ) - CX9 = MazdaPlatformConfig( - "MAZDA CX-9", - MazdaCarInfo("Mazda CX-9 2016-20"), + MAZDA_CX9 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda CX-9 2016-20")], MazdaCarSpecs(mass=4217 * CV.LB_TO_KG, wheelbase=3.1, steerRatio=17.6) ) - MAZDA3 = MazdaPlatformConfig( - "MAZDA 3", - MazdaCarInfo("Mazda 3 2017-18"), + MAZDA_3 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda 3 2017-18")], MazdaCarSpecs(mass=2875 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=14.0) ) - MAZDA6 = MazdaPlatformConfig( - "MAZDA 6", - MazdaCarInfo("Mazda 6 2017-20"), + MAZDA_6 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda 6 2017-20")], MazdaCarSpecs(mass=3443 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=15.5) ) - CX9_2021 = MazdaPlatformConfig( - "MAZDA CX-9 2021", - MazdaCarInfo("Mazda CX-9 2021-23", video_link="https://youtu.be/dA3duO4a0O4"), - CX9.specs + MAZDA_CX9_2021 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda CX-9 2021-23", video_link="https://youtu.be/dA3duO4a0O4")], + MAZDA_CX9.specs ) - CX5_2022 = MazdaPlatformConfig( - "MAZDA CX-5 2022", - MazdaCarInfo("Mazda CX-5 2022-24"), - CX5.specs, + MAZDA_CX5_2022 = MazdaPlatformConfig( + [MazdaCarDocs("Mazda CX-5 2022-24")], + MAZDA_CX5.specs, ) diff --git a/selfdrive/car/mock/carcontroller.py b/selfdrive/car/mock/carcontroller.py new file mode 100644 index 0000000000..2b2da954ff --- /dev/null +++ b/selfdrive/car/mock/carcontroller.py @@ -0,0 +1,5 @@ +from openpilot.selfdrive.car.interfaces import CarControllerBase + +class CarController(CarControllerBase): + def update(self, CC, CS, now_nanos): + return CC.actuators.copy(), [] diff --git a/selfdrive/car/mock/carstate.py b/selfdrive/car/mock/carstate.py new file mode 100644 index 0000000000..ece908b51c --- /dev/null +++ b/selfdrive/car/mock/carstate.py @@ -0,0 +1,4 @@ +from openpilot.selfdrive.car.interfaces import CarStateBase + +class CarState(CarStateBase): + pass diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 2e4ac43033..6100717a74 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -29,7 +29,3 @@ class CarInterface(CarInterfaceBase): ret.vEgoRaw = self.sm[gps_sock].speed return ret - - def apply(self, c, now_nanos): - actuators = car.CarControl.Actuators.new_message() - return actuators, [] diff --git a/selfdrive/car/mock/values.py b/selfdrive/car/mock/values.py index ddab599a93..f98aac2ee3 100644 --- a/selfdrive/car/mock/values.py +++ b/selfdrive/car/mock/values.py @@ -3,8 +3,7 @@ from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms class CAR(Platforms): MOCK = PlatformConfig( - 'mock', - None, + [], CarSpecs(mass=1700, wheelbase=2.7, steerRatio=13), {} ) diff --git a/selfdrive/car/nissan/carcontroller.py b/selfdrive/car/nissan/carcontroller.py index 6aa4bb9438..83775462b7 100644 --- a/selfdrive/car/nissan/carcontroller.py +++ b/selfdrive/car/nissan/carcontroller.py @@ -51,21 +51,21 @@ class CarController(CarControllerBase): self.apply_angle_last = apply_angle - if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA) and pcm_cancel_cmd: + if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA) and pcm_cancel_cmd: can_sends.append(nissancan.create_acc_cancel_cmd(self.packer, self.car_fingerprint, CS.cruise_throttle_msg)) # TODO: Find better way to cancel! # For some reason spamming the cancel button is unreliable on the Leaf # We now cancel by making propilot think the seatbelt is unlatched, # this generates a beep and a warning message every time you disengage - if self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC) and self.frame % 2 == 0: + if self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC) and self.frame % 2 == 0: can_sends.append(nissancan.create_cancel_msg(self.packer, CS.cancel_msg, pcm_cancel_cmd)) can_sends.append(nissancan.create_steering_control( self.packer, apply_angle, self.frame, CC.latActive, self.lkas_max_torque)) # Below are the HUD messages. We copy the stock message and modify - if self.CP.carFingerprint != CAR.ALTIMA: + if self.CP.carFingerprint != CAR.NISSAN_ALTIMA: if self.frame % 2 == 0: can_sends.append(nissancan.create_lkas_hud_msg(self.packer, CS.lkas_hud_msg, CC.enabled, hud_control.leftLaneVisible, hud_control.rightLaneVisible, hud_control.leftLaneDepart, hud_control.rightLaneDepart)) diff --git a/selfdrive/car/nissan/carstate.py b/selfdrive/car/nissan/carstate.py index b2ba9ce290..57146b49c4 100644 --- a/selfdrive/car/nissan/carstate.py +++ b/selfdrive/car/nissan/carstate.py @@ -20,19 +20,25 @@ class CarState(CarStateBase): self.steeringTorqueSamples = deque(TORQUE_SAMPLES*[0], TORQUE_SAMPLES) self.shifter_values = can_define.dv["GEARBOX"]["GEAR_SHIFTER"] + self.prev_distance_button = 0 + self.distance_button = 0 + def update(self, cp, cp_adas, cp_cam): ret = car.CarState.new_message() - if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA): + self.prev_distance_button = self.distance_button + self.distance_button = cp.vl["CRUISE_THROTTLE"]["FOLLOW_DISTANCE_BUTTON"] + + if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA): ret.gas = cp.vl["GAS_PEDAL"]["GAS_PEDAL"] - elif self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): + elif self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): ret.gas = cp.vl["CRUISE_THROTTLE"]["GAS_PEDAL"] ret.gasPressed = bool(ret.gas > 3) - if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA): + if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA): ret.brakePressed = bool(cp.vl["DOORS_LIGHTS"]["USER_BRAKE_PRESSED"]) - elif self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): + elif self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): ret.brakePressed = bool(cp.vl["CRUISE_THROTTLE"]["USER_BRAKE_PRESSED"]) ret.wheelSpeeds = self.get_wheel_speeds( @@ -46,38 +52,38 @@ class CarState(CarStateBase): ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) ret.standstill = cp.vl["WHEEL_SPEEDS_REAR"]["WHEEL_SPEED_RL"] == 0.0 and cp.vl["WHEEL_SPEEDS_REAR"]["WHEEL_SPEED_RR"] == 0.0 - if self.CP.carFingerprint == CAR.ALTIMA: + if self.CP.carFingerprint == CAR.NISSAN_ALTIMA: ret.cruiseState.enabled = bool(cp.vl["CRUISE_STATE"]["CRUISE_ENABLED"]) else: ret.cruiseState.enabled = bool(cp_adas.vl["CRUISE_STATE"]["CRUISE_ENABLED"]) - if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL): + if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL): ret.seatbeltUnlatched = cp.vl["HUD"]["SEATBELT_DRIVER_LATCHED"] == 0 ret.cruiseState.available = bool(cp_cam.vl["PRO_PILOT"]["CRUISE_ON"]) - elif self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): - if self.CP.carFingerprint == CAR.LEAF: + elif self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): + if self.CP.carFingerprint == CAR.NISSAN_LEAF: ret.seatbeltUnlatched = cp.vl["SEATBELT"]["SEATBELT_DRIVER_LATCHED"] == 0 - elif self.CP.carFingerprint == CAR.LEAF_IC: + elif self.CP.carFingerprint == CAR.NISSAN_LEAF_IC: ret.seatbeltUnlatched = cp.vl["CANCEL_MSG"]["CANCEL_SEATBELT"] == 1 ret.cruiseState.available = bool(cp.vl["CRUISE_THROTTLE"]["CRUISE_AVAILABLE"]) - elif self.CP.carFingerprint == CAR.ALTIMA: + elif self.CP.carFingerprint == CAR.NISSAN_ALTIMA: ret.seatbeltUnlatched = cp.vl["HUD"]["SEATBELT_DRIVER_LATCHED"] == 0 ret.cruiseState.available = bool(cp_adas.vl["PRO_PILOT"]["CRUISE_ON"]) - if self.CP.carFingerprint == CAR.ALTIMA: + if self.CP.carFingerprint == CAR.NISSAN_ALTIMA: speed = cp.vl["PROPILOT_HUD"]["SET_SPEED"] else: speed = cp_adas.vl["PROPILOT_HUD"]["SET_SPEED"] if speed != 255: - if self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): + if self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): conversion = CV.MPH_TO_MS if cp.vl["HUD_SETTINGS"]["SPEED_MPH"] else CV.KPH_TO_MS else: conversion = CV.MPH_TO_MS if cp.vl["HUD"]["SPEED_MPH"] else CV.KPH_TO_MS ret.cruiseState.speed = speed * conversion ret.cruiseState.speedCluster = (speed - 1) * conversion # Speed on HUD is always 1 lower than actually sent on can bus - if self.CP.carFingerprint == CAR.ALTIMA: + if self.CP.carFingerprint == CAR.NISSAN_ALTIMA: ret.steeringTorque = cp_cam.vl["STEER_TORQUE_SENSOR"]["STEER_TORQUE_DRIVER"] else: ret.steeringTorque = cp.vl["STEER_TORQUE_SENSOR"]["STEER_TORQUE_DRIVER"] @@ -101,17 +107,17 @@ class CarState(CarStateBase): can_gear = int(cp.vl["GEARBOX"]["GEAR_SHIFTER"]) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) - if self.CP.carFingerprint == CAR.ALTIMA: + if self.CP.carFingerprint == CAR.NISSAN_ALTIMA: self.lkas_enabled = bool(cp.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) else: self.lkas_enabled = bool(cp_adas.vl["LKAS_SETTINGS"]["LKAS_ENABLED"]) self.cruise_throttle_msg = copy.copy(cp.vl["CRUISE_THROTTLE"]) - if self.CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): + if self.CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): self.cancel_msg = copy.copy(cp.vl["CANCEL_MSG"]) - if self.CP.carFingerprint != CAR.ALTIMA: + if self.CP.carFingerprint != CAR.NISSAN_ALTIMA: self.lkas_hud_msg = copy.copy(cp_adas.vl["PROPILOT_HUD"]) self.lkas_hud_info_msg = copy.copy(cp_adas.vl["PROPILOT_HUD_INFO_MSG"]) @@ -130,14 +136,14 @@ class CarState(CarStateBase): ("LIGHTS", 10), ] - if CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA): + if CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA): messages += [ ("GAS_PEDAL", 100), ("CRUISE_THROTTLE", 50), ("HUD", 25), ] - elif CP.carFingerprint in (CAR.LEAF, CAR.LEAF_IC): + elif CP.carFingerprint in (CAR.NISSAN_LEAF, CAR.NISSAN_LEAF_IC): messages += [ ("BRAKE_PEDAL", 100), ("CRUISE_THROTTLE", 50), @@ -146,7 +152,7 @@ class CarState(CarStateBase): ("SEATBELT", 10), ] - if CP.carFingerprint == CAR.ALTIMA: + if CP.carFingerprint == CAR.NISSAN_ALTIMA: messages += [ ("CRUISE_STATE", 10), ("LKAS_SETTINGS", 10), @@ -162,7 +168,7 @@ class CarState(CarStateBase): def get_adas_can_parser(CP): # this function generates lists for signal, messages and initial values - if CP.carFingerprint == CAR.ALTIMA: + if CP.carFingerprint == CAR.NISSAN_ALTIMA: messages = [ ("LKAS", 100), ("PRO_PILOT", 100), @@ -182,9 +188,9 @@ class CarState(CarStateBase): def get_cam_can_parser(CP): messages = [] - if CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL): + if CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL): messages.append(("PRO_PILOT", 100)) - elif CP.carFingerprint == CAR.ALTIMA: + elif CP.carFingerprint == CAR.NISSAN_ALTIMA: messages.append(("STEER_TORQUE_SENSOR", 100)) return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0) diff --git a/selfdrive/car/nissan/fingerprints.py b/selfdrive/car/nissan/fingerprints.py index 19267ded46..743feeace9 100644 --- a/selfdrive/car/nissan/fingerprints.py +++ b/selfdrive/car/nissan/fingerprints.py @@ -5,31 +5,31 @@ from openpilot.selfdrive.car.nissan.values import CAR Ecu = car.CarParams.Ecu FINGERPRINTS = { - CAR.XTRAIL: [{ + CAR.NISSAN_XTRAIL: [{ 2: 5, 42: 6, 346: 6, 347: 5, 348: 8, 349: 7, 361: 8, 386: 8, 389: 8, 397: 8, 398: 8, 403: 8, 520: 2, 523: 6, 548: 8, 645: 8, 658: 8, 665: 8, 666: 8, 674: 2, 682: 8, 683: 8, 689: 8, 723: 8, 758: 3, 768: 2, 783: 3, 851: 8, 855: 8, 1041: 8, 1055: 2, 1104: 4, 1105: 6, 1107: 4, 1108: 8, 1111: 4, 1227: 8, 1228: 8, 1247: 4, 1266: 8, 1273: 7, 1342: 1, 1376: 6, 1401: 8, 1474: 2, 1497: 3, 1821: 8, 1823: 8, 1837: 8, 2015: 8, 2016: 8, 2024: 8 }, { 2: 5, 42: 6, 346: 6, 347: 5, 348: 8, 349: 7, 361: 8, 386: 8, 389: 8, 397: 8, 398: 8, 403: 8, 520: 2, 523: 6, 527: 1, 548: 8, 637: 4, 645: 8, 658: 8, 665: 8, 666: 8, 674: 2, 682: 8, 683: 8, 689: 8, 723: 8, 758: 3, 768: 6, 783: 3, 851: 8, 855: 8, 1041: 8, 1055: 2, 1104: 4, 1105: 6, 1107: 4, 1108: 8, 1111: 4, 1227: 8, 1228: 8, 1247: 4, 1266: 8, 1273: 7, 1342: 1, 1376: 6, 1401: 8, 1474: 8, 1497: 3, 1534: 6, 1792: 8, 1821: 8, 1823: 8, 1837: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 2015: 8, 2016: 8, 2024: 8 }], - CAR.LEAF: [{ + CAR.NISSAN_LEAF: [{ 2: 5, 42: 6, 264: 3, 361: 8, 372: 8, 384: 8, 389: 8, 403: 8, 459: 7, 460: 4, 470: 8, 520: 1, 569: 8, 581: 8, 634: 7, 640: 8, 644: 8, 645: 8, 646: 5, 658: 8, 682: 8, 683: 8, 689: 8, 724: 6, 758: 3, 761: 2, 783: 3, 852: 8, 853: 8, 856: 8, 861: 8, 944: 1, 976: 6, 1008: 7, 1011: 7, 1057: 3, 1227: 8, 1228: 8, 1261: 5, 1342: 1, 1354: 8, 1361: 8, 1459: 8, 1477: 8, 1497: 3, 1549: 8, 1573: 6, 1821: 8, 1837: 8, 1856: 8, 1859: 8, 1861: 8, 1864: 8, 1874: 8, 1888: 8, 1891: 8, 1893: 8, 1906: 8, 1947: 8, 1949: 8, 1979: 8, 1981: 8, 2016: 8, 2017: 8, 2021: 8, 643: 5, 1792: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 1988: 8, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2015: 8 }, { 2: 5, 42: 8, 264: 3, 361: 8, 372: 8, 384: 8, 389: 8, 403: 8, 459: 7, 460: 4, 470: 8, 520: 1, 569: 8, 581: 8, 634: 7, 640: 8, 643: 5, 644: 8, 645: 8, 646: 5, 658: 8, 682: 8, 683: 8, 689: 8, 724: 6, 758: 3, 761: 2, 772: 8, 773: 6, 774: 7, 775: 8, 776: 6, 777: 7, 778: 6, 783: 3, 852: 8, 853: 8, 856: 8, 861: 8, 943: 8, 944: 1, 976: 6, 1008: 7, 1009: 8, 1010: 8, 1011: 7, 1012: 8, 1013: 8, 1019: 8, 1020: 8, 1021: 8, 1022: 8, 1057: 3, 1227: 8, 1228: 8, 1261: 5, 1342: 1, 1354: 8, 1361: 8, 1402: 8, 1459: 8, 1477: 8, 1497: 3, 1549: 8, 1573: 6, 1821: 8, 1837: 8 }], - CAR.LEAF_IC: [{ + CAR.NISSAN_LEAF_IC: [{ 2: 5, 42: 6, 264: 3, 282: 8, 361: 8, 372: 8, 384: 8, 389: 8, 403: 8, 459: 7, 460: 4, 470: 8, 520: 1, 569: 8, 581: 8, 634: 7, 640: 8, 643: 5, 644: 8, 645: 8, 646: 5, 658: 8, 682: 8, 683: 8, 689: 8, 756: 5, 758: 3, 761: 2, 783: 3, 830: 2, 852: 8, 853: 8, 856: 8, 861: 8, 943: 8, 944: 1, 1001: 6, 1057: 3, 1227: 8, 1228: 8, 1229: 8, 1342: 1, 1354: 8, 1361: 8, 1459: 8, 1477: 8, 1497: 3, 1514: 6, 1549: 8, 1573: 6, 1792: 8, 1821: 8, 1822: 8, 1837: 8, 1838: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 1988: 8, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2015: 8, 2016: 8, 2017: 8 }], - CAR.ROGUE: [{ + CAR.NISSAN_ROGUE: [{ 2: 5, 42: 6, 346: 6, 347: 5, 348: 8, 349: 7, 361: 8, 386: 8, 389: 8, 397: 8, 398: 8, 403: 8, 520: 2, 523: 6, 548: 8, 634: 7, 643: 5, 645: 8, 658: 8, 665: 8, 666: 8, 674: 2, 682: 8, 683: 8, 689: 8, 723: 8, 758: 3, 772: 8, 773: 6, 774: 7, 775: 8, 776: 6, 777: 7, 778: 6, 783: 3, 851: 8, 855: 8, 1041: 8, 1042: 8, 1055: 2, 1104: 4, 1105: 6, 1107: 4, 1108: 8, 1110: 7, 1111: 7, 1227: 8, 1228: 8, 1247: 4, 1266: 8, 1273: 7, 1342: 1, 1376: 6, 1401: 8, 1474: 2, 1497: 3, 1534: 7, 1792: 8, 1821: 8, 1823: 8, 1837: 8, 1839: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 1988: 8, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], - CAR.ALTIMA: [{ + CAR.NISSAN_ALTIMA: [{ 2: 5, 42: 6, 346: 6, 347: 5, 348: 8, 349: 7, 361: 8, 386: 8, 389: 8, 397: 8, 398: 8, 403: 8, 438: 8, 451: 8, 517: 8, 520: 2, 522: 8, 523: 6, 539: 8, 541: 7, 542: 8, 543: 8, 544: 8, 545: 8, 546: 8, 547: 8, 548: 8, 570: 8, 576: 8, 577: 8, 582: 8, 583: 8, 584: 8, 586: 8, 587: 8, 588: 8, 589: 8, 590: 8, 591: 8, 592: 8, 600: 8, 601: 8, 610: 8, 611: 8, 612: 8, 614: 8, 615: 8, 616: 8, 617: 8, 622: 8, 623: 8, 634: 7, 638: 8, 645: 8, 648: 5, 654: 6, 658: 8, 659: 8, 660: 8, 661: 8, 665: 8, 666: 8, 674: 2, 675: 8, 676: 8, 682: 8, 683: 8, 684: 8, 685: 8, 686: 8, 687: 8, 689: 8, 690: 8, 703: 8, 708: 7, 709: 7, 711: 7, 712: 7, 713: 7, 714: 8, 715: 8, 716: 8, 717: 7, 718: 7, 719: 7, 720: 7, 723: 8, 726: 7, 727: 7, 728: 7, 735: 8, 746: 8, 748: 6, 749: 6, 750: 8, 758: 3, 772: 8, 773: 6, 774: 7, 775: 8, 776: 6, 777: 7, 778: 6, 779: 7, 781: 7, 782: 7, 783: 3, 851: 8, 855: 5, 1001: 6, 1041: 8, 1042: 8, 1055: 3, 1100: 7, 1104: 4, 1105: 6, 1107: 4, 1108: 8, 1110: 7, 1111: 7, 1144: 7, 1145: 7, 1227: 8, 1228: 8, 1229: 8, 1232: 8, 1247: 4, 1258: 8, 1259: 8, 1266: 8, 1273: 7, 1306: 1, 1314: 8, 1323: 8, 1324: 8, 1342: 1, 1376: 8, 1401: 8, 1454: 8, 1497: 3, 1514: 6, 1526: 8, 1527: 5, 1792: 8, 1821: 8, 1823: 8, 1837: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 1988: 8, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8 }], } FW_VERSIONS = { - CAR.ALTIMA: { + CAR.NISSAN_ALTIMA: { (Ecu.fwdCamera, 0x707, None): [ b'284N86CA1D', ], @@ -43,7 +43,7 @@ FW_VERSIONS = { b'284U29HE0A', ], }, - CAR.LEAF: { + CAR.NISSAN_LEAF: { (Ecu.abs, 0x740, None): [ b'476605SA1C', b'476605SA7D', @@ -72,7 +72,7 @@ FW_VERSIONS = { b'284U26WK0C', ], }, - CAR.LEAF_IC: { + CAR.NISSAN_LEAF_IC: { (Ecu.fwdCamera, 0x707, None): [ b'5SH1BDB\x04\x18\x00\x00\x00\x00\x00_-?\x04\x91\xf2\x00\x00\x00\x80', b'5SH4BDB\x04\x18\x00\x00\x00\x00\x00_-?\x04\x91\xf2\x00\x00\x00\x80', @@ -94,7 +94,7 @@ FW_VERSIONS = { b'284U25SK2D', ], }, - CAR.XTRAIL: { + CAR.NISSAN_XTRAIL: { (Ecu.fwdCamera, 0x707, None): [ b'284N86FR2A', ], diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 60cc3a0090..2e9a990610 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -1,9 +1,11 @@ from cereal import car from panda import Panda -from openpilot.selfdrive.car import get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.nissan.values import CAR +ButtonType = car.CarState.ButtonEvent.Type + class CarInterface(CarInterfaceBase): @@ -20,7 +22,7 @@ class CarInterface(CarInterfaceBase): ret.steerControlType = car.CarParams.SteerControlType.angle ret.radarUnavailable = True - if candidate == CAR.ALTIMA: + if candidate == CAR.NISSAN_ALTIMA: # Altima has EPS on C-CAN unlike the others that have it on V-CAN ret.safetyConfigs[0].safetyParam |= Panda.FLAG_NISSAN_ALT_EPS_BUS @@ -30,6 +32,8 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam) + ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.brake]) if self.CS.lkas_enabled: @@ -38,6 +42,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/nissan/nissancan.py b/selfdrive/car/nissan/nissancan.py index 49dcd6fe93..b9a1b4f843 100644 --- a/selfdrive/car/nissan/nissancan.py +++ b/selfdrive/car/nissan/nissancan.py @@ -39,7 +39,7 @@ def create_acc_cancel_cmd(packer, car_fingerprint, cruise_throttle_msg): "unsure2", "unsure3", ]} - can_bus = 1 if car_fingerprint == CAR.ALTIMA else 2 + can_bus = 1 if car_fingerprint == CAR.NISSAN_ALTIMA else 2 values["CANCEL_BUTTON"] = 1 values["NO_BUTTON_PRESSED"] = 0 diff --git a/selfdrive/car/nissan/values.py b/selfdrive/car/nissan/values.py index c0ccb0febf..bdd2dec5f4 100644 --- a/selfdrive/car/nissan/values.py +++ b/selfdrive/car/nissan/values.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field from cereal import car from panda.python import uds from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarInfo, CarHarness, CarParts +from openpilot.selfdrive.car.docs_definitions import CarDocs, CarHarness, CarParts from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -20,7 +20,7 @@ class CarControllerParams: @dataclass -class NissanCarInfo(CarInfo): +class NissanCarDocs(CarDocs): package: str = "ProPILOT Assist" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.nissan_a])) @@ -37,28 +37,24 @@ class NissanPlaformConfig(PlatformConfig): class CAR(Platforms): - XTRAIL = NissanPlaformConfig( - "NISSAN X-TRAIL 2017", - NissanCarInfo("Nissan X-Trail 2017"), + NISSAN_XTRAIL = NissanPlaformConfig( + [NissanCarDocs("Nissan X-Trail 2017")], NissanCarSpecs(mass=1610, wheelbase=2.705) ) - LEAF = NissanPlaformConfig( - "NISSAN LEAF 2018", - NissanCarInfo("Nissan Leaf 2018-23", video_link="https://youtu.be/vaMbtAh_0cY"), + NISSAN_LEAF = NissanPlaformConfig( + [NissanCarDocs("Nissan Leaf 2018-23", video_link="https://youtu.be/vaMbtAh_0cY")], NissanCarSpecs(mass=1610, wheelbase=2.705), dbc_dict('nissan_leaf_2018_generated', None), ) # Leaf with ADAS ECU found behind instrument cluster instead of glovebox # Currently the only known difference between them is the inverted seatbelt signal. - LEAF_IC = LEAF.override(platform_str="NISSAN LEAF 2018 Instrument Cluster", car_info=None) - ROGUE = NissanPlaformConfig( - "NISSAN ROGUE 2019", - NissanCarInfo("Nissan Rogue 2018-20"), + NISSAN_LEAF_IC = NISSAN_LEAF.override(car_docs=[]) + NISSAN_ROGUE = NissanPlaformConfig( + [NissanCarDocs("Nissan Rogue 2018-20")], NissanCarSpecs(mass=1610, wheelbase=2.705) ) - ALTIMA = NissanPlaformConfig( - "NISSAN ALTIMA 2020", - NissanCarInfo("Nissan Altima 2019-20", car_parts=CarParts.common([CarHarness.nissan_b])), + NISSAN_ALTIMA = NissanPlaformConfig( + [NissanCarDocs("Nissan Altima 2019-20", car_parts=CarParts.common([CarHarness.nissan_b]))], NissanCarSpecs(mass=1492, wheelbase=2.824) ) diff --git a/selfdrive/car/subaru/fingerprints.py b/selfdrive/car/subaru/fingerprints.py index 9f6177b4c0..c9b0b859f4 100644 --- a/selfdrive/car/subaru/fingerprints.py +++ b/selfdrive/car/subaru/fingerprints.py @@ -4,7 +4,7 @@ from openpilot.selfdrive.car.subaru.values import CAR Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.ASCENT: { + CAR.SUBARU_ASCENT: { (Ecu.abs, 0x7b0, None): [ b'\xa5 \x19\x02\x00', b'\xa5 !\x02\x00', @@ -33,7 +33,7 @@ FW_VERSIONS = { b'\x01\xfe\xfa\x00\x00', ], }, - CAR.ASCENT_2023: { + CAR.SUBARU_ASCENT_2023: { (Ecu.abs, 0x7b0, None): [ b'\xa5 #\x03\x00', ], @@ -50,7 +50,7 @@ FW_VERSIONS = { b'\x04\xfe\xf3\x00\x00', ], }, - CAR.LEGACY: { + CAR.SUBARU_LEGACY: { (Ecu.abs, 0x7b0, None): [ b'\xa1 \x02\x01', b'\xa1 \x02\x02', @@ -78,7 +78,7 @@ FW_VERSIONS = { b'\xa7\xfe\xc4@\x00', ], }, - CAR.IMPREZA: { + CAR.SUBARU_IMPREZA: { (Ecu.abs, 0x7b0, None): [ b'z\x84\x19\x90\x00', b'z\x94\x08\x90\x00', @@ -149,6 +149,7 @@ FW_VERSIONS = { b'\xe3\xf5C\x00\x00', b'\xe3\xf5F\x00\x00', b'\xe3\xf5G\x00\x00', + b'\xe4\xe5\x021\x00', b'\xe4\xe5\x061\x00', b'\xe4\xf5\x02\x00\x00', b'\xe4\xf5\x07\x00\x00', @@ -157,7 +158,7 @@ FW_VERSIONS = { b'\xe5\xf5B\x00\x00', ], }, - CAR.IMPREZA_2020: { + CAR.SUBARU_IMPREZA_2020: { (Ecu.abs, 0x7b0, None): [ b'\xa2 \x193\x00', b'\xa2 \x194\x00', @@ -196,6 +197,7 @@ FW_VERSIONS = { b'\xe6"fp\x07', b'\xf3"f@\x07', b'\xf3"fp\x07', + b'\xf3"fr\x07', ], (Ecu.transmission, 0x7e1, None): [ b'\xe6\xf5\x04\x00\x00', @@ -210,7 +212,7 @@ FW_VERSIONS = { b'\xe9\xf6F0\x00', ], }, - CAR.CROSSTREK_HYBRID: { + CAR.SUBARU_CROSSTREK_HYBRID: { (Ecu.abs, 0x7b0, None): [ b'\xa2 \x19e\x01', b'\xa2 !e\x01', @@ -228,7 +230,7 @@ FW_VERSIONS = { b'\xf4!`0\x07', ], }, - CAR.FORESTER: { + CAR.SUBARU_FORESTER: { (Ecu.abs, 0x7b0, None): [ b'\xa3 \x18\x14\x00', b'\xa3 \x18&\x00', @@ -268,7 +270,7 @@ FW_VERSIONS = { b'\x1a\xf6b`\x00', ], }, - CAR.FORESTER_HYBRID: { + CAR.SUBARU_FORESTER_HYBRID: { (Ecu.abs, 0x7b0, None): [ b'\xa3 \x19T\x00', ], @@ -285,7 +287,7 @@ FW_VERSIONS = { b'\x1b\xa7@a\x00', ], }, - CAR.FORESTER_PREGLOBAL: { + CAR.SUBARU_FORESTER_PREGLOBAL: { (Ecu.abs, 0x7b0, None): [ b'm\x97\x14@', b'}\x97\x14@', @@ -316,7 +318,7 @@ FW_VERSIONS = { b'\xdc\xf2`\x81\x00', ], }, - CAR.LEGACY_PREGLOBAL: { + CAR.SUBARU_LEGACY_PREGLOBAL: { (Ecu.abs, 0x7b0, None): [ b'[\x97D\x00', b'[\xba\xc4\x03', @@ -349,7 +351,7 @@ FW_VERSIONS = { b'\xbf\xfb\xc0\x80\x00', ], }, - CAR.OUTBACK_PREGLOBAL: { + CAR.SUBARU_OUTBACK_PREGLOBAL: { (Ecu.abs, 0x7b0, None): [ b'[\xba\xac\x03', b'[\xf7\xac\x00', @@ -402,7 +404,7 @@ FW_VERSIONS = { b'\xbf\xfb\xe0b\x00', ], }, - CAR.OUTBACK_PREGLOBAL_2018: { + CAR.SUBARU_OUTBACK_PREGLOBAL_2018: { (Ecu.abs, 0x7b0, None): [ b'\x8b\x97\xac\x00', b'\x8b\x97\xbc\x00', @@ -445,7 +447,7 @@ FW_VERSIONS = { b'\xbc\xfb\xe0\x80\x00', ], }, - CAR.OUTBACK: { + CAR.SUBARU_OUTBACK: { (Ecu.abs, 0x7b0, None): [ b'\xa1 \x06\x00', b'\xa1 \x06\x01', @@ -494,7 +496,7 @@ FW_VERSIONS = { b'\xa7\xfe\xf4@\x00', ], }, - CAR.FORESTER_2022: { + CAR.SUBARU_FORESTER_2022: { (Ecu.abs, 0x7b0, None): [ b'\xa3 !v\x00', b'\xa3 !x\x00', @@ -527,7 +529,7 @@ FW_VERSIONS = { b'\x1e\xf6D0\x00', ], }, - CAR.OUTBACK_2023: { + CAR.SUBARU_OUTBACK_2023: { (Ecu.abs, 0x7b0, None): [ b'\xa1 #\x14\x00', b'\xa1 #\x17\x00', diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 30e186bd09..1aa4bd95ea 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -40,45 +40,45 @@ class CarInterface(CarInterfaceBase): else: CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) - if candidate in (CAR.ASCENT, CAR.ASCENT_2023): + if candidate in (CAR.SUBARU_ASCENT, CAR.SUBARU_ASCENT_2023): ret.steerActuatorDelay = 0.3 # end-to-end angle controller ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00003 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 20.], [0., 20.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.0025, 0.1], [0.00025, 0.01]] - elif candidate == CAR.IMPREZA: + elif candidate == CAR.SUBARU_IMPREZA: ret.steerActuatorDelay = 0.4 # end-to-end angle controller ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00005 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 20.], [0., 20.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2, 0.3], [0.02, 0.03]] - elif candidate == CAR.IMPREZA_2020: + elif candidate == CAR.SUBARU_IMPREZA_2020: ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.00005 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 14., 23.], [0., 14., 23.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.045, 0.042, 0.20], [0.04, 0.035, 0.045]] - elif candidate == CAR.CROSSTREK_HYBRID: + elif candidate == CAR.SUBARU_CROSSTREK_HYBRID: ret.steerActuatorDelay = 0.1 - elif candidate in (CAR.FORESTER, CAR.FORESTER_2022, CAR.FORESTER_HYBRID): + elif candidate in (CAR.SUBARU_FORESTER, CAR.SUBARU_FORESTER_2022, CAR.SUBARU_FORESTER_HYBRID): ret.lateralTuning.init('pid') ret.lateralTuning.pid.kf = 0.000038 ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 14., 23.], [0., 14., 23.]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.01, 0.065, 0.2], [0.001, 0.015, 0.025]] - elif candidate in (CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023): + elif candidate in (CAR.SUBARU_OUTBACK, CAR.SUBARU_LEGACY, CAR.SUBARU_OUTBACK_2023): ret.steerActuatorDelay = 0.1 - elif candidate in (CAR.FORESTER_PREGLOBAL, CAR.OUTBACK_PREGLOBAL_2018): + elif candidate in (CAR.SUBARU_FORESTER_PREGLOBAL, CAR.SUBARU_OUTBACK_PREGLOBAL_2018): ret.safetyConfigs[0].safetyParam = Panda.FLAG_SUBARU_PREGLOBAL_REVERSED_DRIVER_TORQUE # Outback 2018-2019 and Forester have reversed driver torque signal - elif candidate == CAR.LEGACY_PREGLOBAL: + elif candidate == CAR.SUBARU_LEGACY_PREGLOBAL: ret.steerActuatorDelay = 0.15 - elif candidate == CAR.OUTBACK_PREGLOBAL: + elif candidate == CAR.SUBARU_OUTBACK_PREGLOBAL: pass else: raise ValueError(f"unknown car: {candidate}") @@ -114,6 +114,3 @@ class CarInterface(CarInterfaceBase): def init(CP, logcan, sendcan): if CP.flags & SubaruFlags.DISABLE_EYESIGHT: disable_ecu(logcan, sendcan, bus=2, addr=GLOBAL_ES_ADDR, com_cont_req=b'\x28\x03\x01') - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 0bf5e782f5..0542635370 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -4,7 +4,7 @@ from enum import Enum, IntFlag from cereal import car from panda.python import uds from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Tool, Column +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Tool, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 Ecu = car.CarParams.Ecu @@ -23,7 +23,7 @@ class CarControllerParams: self.STEER_MAX = 1000 self.STEER_DELTA_UP = 40 self.STEER_DELTA_DOWN = 40 - elif CP.carFingerprint == CAR.IMPREZA_2020: + elif CP.carFingerprint == CAR.SUBARU_IMPREZA_2020: self.STEER_MAX = 1439 else: self.STEER_MAX = 2047 @@ -88,7 +88,7 @@ class Footnote(Enum): @dataclass -class SubaruCarInfo(CarInfo): +class SubaruCarDocs(CarDocs): package: str = "EyeSight Driver Assistance" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.subaru_a])) footnotes: list[Enum] = field(default_factory=lambda: [Footnote.GLOBAL]) @@ -120,105 +120,90 @@ class SubaruGen2PlatformConfig(SubaruPlatformConfig): class CAR(Platforms): # Global platform - ASCENT = SubaruPlatformConfig( - "SUBARU ASCENT LIMITED 2019", - SubaruCarInfo("Subaru Ascent 2019-21", "All"), + SUBARU_ASCENT = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Ascent 2019-21", "All")], CarSpecs(mass=2031, wheelbase=2.89, steerRatio=13.5), ) - OUTBACK = SubaruGen2PlatformConfig( - "SUBARU OUTBACK 6TH GEN", - SubaruCarInfo("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), + SUBARU_OUTBACK = SubaruGen2PlatformConfig( + [SubaruCarDocs("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b]))], CarSpecs(mass=1568, wheelbase=2.67, steerRatio=17), ) - LEGACY = SubaruGen2PlatformConfig( - "SUBARU LEGACY 7TH GEN", - SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])), - OUTBACK.specs, + SUBARU_LEGACY = SubaruGen2PlatformConfig( + [SubaruCarDocs("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b]))], + SUBARU_OUTBACK.specs, ) - IMPREZA = SubaruPlatformConfig( - "SUBARU IMPREZA LIMITED 2019", + SUBARU_IMPREZA = SubaruPlatformConfig( [ - SubaruCarInfo("Subaru Impreza 2017-19"), - SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), - SubaruCarInfo("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), + SubaruCarDocs("Subaru Impreza 2017-19"), + SubaruCarDocs("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), + SubaruCarDocs("Subaru XV 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), ], CarSpecs(mass=1568, wheelbase=2.67, steerRatio=15), ) - IMPREZA_2020 = SubaruPlatformConfig( - "SUBARU IMPREZA SPORT 2020", + SUBARU_IMPREZA_2020 = SubaruPlatformConfig( [ - SubaruCarInfo("Subaru Impreza 2020-22"), - SubaruCarInfo("Subaru Crosstrek 2020-23"), - SubaruCarInfo("Subaru XV 2020-21"), + SubaruCarDocs("Subaru Impreza 2020-22"), + SubaruCarDocs("Subaru Crosstrek 2020-23"), + SubaruCarDocs("Subaru XV 2020-21"), ], CarSpecs(mass=1480, wheelbase=2.67, steerRatio=17), flags=SubaruFlags.STEER_RATE_LIMITED, ) # TODO: is there an XV and Impreza too? - CROSSTREK_HYBRID = SubaruPlatformConfig( - "SUBARU CROSSTREK HYBRID 2020", - SubaruCarInfo("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b])), + SUBARU_CROSSTREK_HYBRID = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Crosstrek Hybrid 2020", car_parts=CarParts.common([CarHarness.subaru_b]))], CarSpecs(mass=1668, wheelbase=2.67, steerRatio=17), flags=SubaruFlags.HYBRID, ) - FORESTER = SubaruPlatformConfig( - "SUBARU FORESTER 2019", - SubaruCarInfo("Subaru Forester 2019-21", "All"), + SUBARU_FORESTER = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Forester 2019-21", "All")], CarSpecs(mass=1568, wheelbase=2.67, steerRatio=17), flags=SubaruFlags.STEER_RATE_LIMITED, ) - FORESTER_HYBRID = SubaruPlatformConfig( - "SUBARU FORESTER HYBRID 2020", - SubaruCarInfo("Subaru Forester Hybrid 2020"), - FORESTER.specs, + SUBARU_FORESTER_HYBRID = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Forester Hybrid 2020")], + SUBARU_FORESTER.specs, flags=SubaruFlags.HYBRID, ) # Pre-global - FORESTER_PREGLOBAL = SubaruPlatformConfig( - "SUBARU FORESTER 2017 - 2018", - SubaruCarInfo("Subaru Forester 2017-18"), + SUBARU_FORESTER_PREGLOBAL = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Forester 2017-18")], CarSpecs(mass=1568, wheelbase=2.67, steerRatio=20), dbc_dict('subaru_forester_2017_generated', None), flags=SubaruFlags.PREGLOBAL, ) - LEGACY_PREGLOBAL = SubaruPlatformConfig( - "SUBARU LEGACY 2015 - 2018", - SubaruCarInfo("Subaru Legacy 2015-18"), + SUBARU_LEGACY_PREGLOBAL = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Legacy 2015-18")], CarSpecs(mass=1568, wheelbase=2.67, steerRatio=12.5), dbc_dict('subaru_outback_2015_generated', None), flags=SubaruFlags.PREGLOBAL, ) - OUTBACK_PREGLOBAL = SubaruPlatformConfig( - "SUBARU OUTBACK 2015 - 2017", - SubaruCarInfo("Subaru Outback 2015-17"), - FORESTER_PREGLOBAL.specs, + SUBARU_OUTBACK_PREGLOBAL = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Outback 2015-17")], + SUBARU_FORESTER_PREGLOBAL.specs, dbc_dict('subaru_outback_2015_generated', None), flags=SubaruFlags.PREGLOBAL, ) - OUTBACK_PREGLOBAL_2018 = SubaruPlatformConfig( - "SUBARU OUTBACK 2018 - 2019", - SubaruCarInfo("Subaru Outback 2018-19"), - FORESTER_PREGLOBAL.specs, + SUBARU_OUTBACK_PREGLOBAL_2018 = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Outback 2018-19")], + SUBARU_FORESTER_PREGLOBAL.specs, dbc_dict('subaru_outback_2019_generated', None), flags=SubaruFlags.PREGLOBAL, ) # Angle LKAS - FORESTER_2022 = SubaruPlatformConfig( - "SUBARU FORESTER 2022", - SubaruCarInfo("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c])), - FORESTER.specs, + SUBARU_FORESTER_2022 = SubaruPlatformConfig( + [SubaruCarDocs("Subaru Forester 2022-24", "All", car_parts=CarParts.common([CarHarness.subaru_c]))], + SUBARU_FORESTER.specs, flags=SubaruFlags.LKAS_ANGLE, ) - OUTBACK_2023 = SubaruGen2PlatformConfig( - "SUBARU OUTBACK 7TH GEN", - SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), - OUTBACK.specs, + SUBARU_OUTBACK_2023 = SubaruGen2PlatformConfig( + [SubaruCarDocs("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d]))], + SUBARU_OUTBACK.specs, flags=SubaruFlags.LKAS_ANGLE, ) - ASCENT_2023 = SubaruGen2PlatformConfig( - "SUBARU ASCENT 2023", - SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])), - ASCENT.specs, + SUBARU_ASCENT_2023 = SubaruGen2PlatformConfig( + [SubaruCarDocs("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d]))], + SUBARU_ASCENT.specs, flags=SubaruFlags.LKAS_ANGLE, ) @@ -228,6 +213,13 @@ SUBARU_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ SUBARU_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + \ p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_DATA_IDENTIFICATION) +# The EyeSight ECU takes 10s to respond to SUBARU_VERSION_REQUEST properly, +# log this alternate manufacturer-specific query +SUBARU_ALT_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \ + p16(0xf100) +SUBARU_ALT_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40]) + \ + p16(0xf100) + FW_QUERY_CONFIG = FwQueryConfig( requests=[ Request( @@ -245,6 +237,13 @@ FW_QUERY_CONFIG = FwQueryConfig( whitelist_ecus=[Ecu.fwdCamera], bus=0, ), + Request( + [SUBARU_ALT_VERSION_REQUEST], + [SUBARU_ALT_VERSION_RESPONSE], + whitelist_ecus=[Ecu.fwdCamera], + bus=0, + logging=True, + ), Request( [StdQueries.DEFAULT_DIAGNOSTIC_REQUEST, StdQueries.TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST], [StdQueries.DEFAULT_DIAGNOSTIC_RESPONSE, StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE], diff --git a/selfdrive/car/tesla/carstate.py b/selfdrive/car/tesla/carstate.py index bee652ff30..645ea46014 100644 --- a/selfdrive/car/tesla/carstate.py +++ b/selfdrive/car/tesla/carstate.py @@ -37,7 +37,7 @@ class CarState(CarStateBase): ret.brakePressed = bool(cp.vl["BrakeMessage"]["driverBrakeStatus"] != 1) # Steering wheel - epas_status = cp_cam.vl["EPAS3P_sysStatus"] if self.CP.carFingerprint == CAR.MODELS_RAVEN else cp.vl["EPAS_sysStatus"] + epas_status = cp_cam.vl["EPAS3P_sysStatus"] if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN else cp.vl["EPAS_sysStatus"] self.hands_on_level = epas_status["EPAS_handsOnLevel"] self.steer_warning = self.can_define.dv["EPAS_sysStatus"]["EPAS_eacErrorCode"].get(int(epas_status["EPAS_eacErrorCode"]), None) @@ -87,7 +87,7 @@ class CarState(CarStateBase): ret.rightBlinker = (cp.vl["GTW_carState"]["BC_indicatorRStatus"] == 1) # Seatbelt - if self.CP.carFingerprint == CAR.MODELS_RAVEN: + if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: ret.seatbeltUnlatched = (cp.vl["DriverSeat"]["buckleStatus"] != 1) else: ret.seatbeltUnlatched = (cp.vl["SDM1"]["SDM_bcklDrivStatus"] != 1) @@ -119,7 +119,7 @@ class CarState(CarStateBase): ("BrakeMessage", 50), ] - if CP.carFingerprint == CAR.MODELS_RAVEN: + if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: messages.append(("DriverSeat", 20)) else: messages.append(("SDM1", 10)) @@ -133,7 +133,7 @@ class CarState(CarStateBase): ("DAS_control", 40), ] - if CP.carFingerprint == CAR.MODELS_RAVEN: + if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: messages.append(("EPAS3P_sysStatus", 100)) return CANParser(DBC[CP.carFingerprint]['chassis'], messages, CANBUS.autopilot_chassis) diff --git a/selfdrive/car/tesla/fingerprints.py b/selfdrive/car/tesla/fingerprints.py index 9b6f3865be..5a87986e45 100644 --- a/selfdrive/car/tesla/fingerprints.py +++ b/selfdrive/car/tesla/fingerprints.py @@ -5,13 +5,13 @@ from openpilot.selfdrive.car.tesla.values import CAR Ecu = car.CarParams.Ecu FINGERPRINTS = { - CAR.AP1_MODELS: [{ + CAR.TESLA_AP1_MODELS: [{ 1: 8, 3: 8, 14: 8, 21: 4, 69: 8, 109: 4, 257: 3, 264: 8, 267: 5, 277: 6, 280: 6, 283: 5, 293: 4, 296: 4, 309: 5, 325: 8, 328: 5, 336: 8, 341: 8, 360: 7, 373: 8, 389: 8, 415: 8, 513: 5, 516: 8, 520: 4, 522: 8, 524: 8, 526: 8, 532: 3, 536: 8, 537: 3, 542: 8, 551: 5, 552: 2, 556: 8, 558: 8, 568: 8, 569: 8, 574: 8, 577: 8, 582: 5, 584: 4, 585: 8, 590: 8, 606: 8, 622: 8, 627: 6, 638: 8, 641: 8, 643: 8, 660: 5, 693: 8, 696: 8, 697: 8, 712: 8, 728: 8, 744: 8, 760: 8, 772: 8, 775: 8, 776: 8, 777: 8, 778: 8, 782: 8, 788: 8, 791: 8, 792: 8, 796: 2, 797: 8, 798: 6, 799: 8, 804: 8, 805: 8, 807: 8, 808: 1, 809: 8, 812: 8, 813: 8, 814: 5, 815: 8, 820: 8, 823: 8, 824: 8, 829: 8, 830: 5, 836: 8, 840: 8, 841: 8, 845: 8, 846: 5, 852: 8, 856: 4, 857: 6, 861: 8, 862: 5, 872: 8, 873: 8, 877: 8, 878: 8, 879: 8, 880: 8, 884: 8, 888: 8, 889: 8, 893: 8, 896: 8, 901: 6, 904: 3, 905: 8, 908: 2, 909: 8, 920: 8, 921: 8, 925: 4, 936: 8, 937: 8, 941: 8, 949: 8, 952: 8, 953: 6, 957: 8, 968: 8, 973: 8, 984: 8, 987: 8, 989: 8, 990: 8, 1000: 8, 1001: 8, 1006: 8, 1016: 8, 1026: 8, 1028: 8, 1029: 8, 1030: 8, 1032: 1, 1033: 1, 1034: 8, 1048: 1, 1064: 8, 1070: 8, 1080: 8, 1160: 4, 1281: 8, 1329: 8, 1332: 8, 1335: 8, 1337: 8, 1368: 8, 1412: 8, 1436: 8, 1465: 8, 1476: 8, 1497: 8, 1524: 8, 1527: 8, 1601: 8, 1605: 8, 1611: 8, 1614: 8, 1617: 8, 1621: 8, 1627: 8, 1630: 8, 1800: 4, 1804: 8, 1812: 8, 1815: 8, 1816: 8, 1828: 8, 1831: 8, 1832: 8, 1840: 8, 1848: 8, 1864: 8, 1880: 8, 1892: 8, 1896: 8, 1912: 8, 1960: 8, 1992: 8, 2008: 3, 2043: 5, 2045: 4 }], } FW_VERSIONS = { - CAR.AP2_MODELS: { + CAR.TESLA_AP2_MODELS: { (Ecu.adas, 0x649, None): [ b'\x01\x00\x8b\x07\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11', ], @@ -25,7 +25,7 @@ FW_VERSIONS = { b'\x10#\x01', ], }, - CAR.MODELS_RAVEN: { + CAR.TESLA_MODELS_RAVEN: { (Ecu.electricBrakeBooster, 0x64d, None): [ b'1037123-00-A', ], diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py index f989886738..e039859263 100755 --- a/selfdrive/car/tesla/interface.py +++ b/selfdrive/car/tesla/interface.py @@ -28,7 +28,7 @@ class CarInterface(CarInterfaceBase): # Check if we have messages on an auxiliary panda, and that 0x2bf (DAS_control) is present on the AP powertrain bus # If so, we assume that it is connected to the longitudinal harness. - flags = (Panda.FLAG_TESLA_RAVEN if candidate == CAR.MODELS_RAVEN else 0) + flags = (Panda.FLAG_TESLA_RAVEN if candidate == CAR.TESLA_MODELS_RAVEN else 0) if (CANBUS.autopilot_powertrain in fingerprint.keys()) and (0x2bf in fingerprint[CANBUS.autopilot_powertrain].keys()): ret.openpilotLongitudinalControl = True flags |= Panda.FLAG_TESLA_LONG_CONTROL @@ -50,6 +50,3 @@ class CarInterface(CarInterfaceBase): ret.events = self.create_common_events(ret).to_msg() return ret - - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/tesla/radar_interface.py b/selfdrive/car/tesla/radar_interface.py index 599ab31059..ae5077824b 100755 --- a/selfdrive/car/tesla/radar_interface.py +++ b/selfdrive/car/tesla/radar_interface.py @@ -10,7 +10,7 @@ class RadarInterface(RadarInterfaceBase): super().__init__(CP) self.CP = CP - if CP.carFingerprint == CAR.MODELS_RAVEN: + if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: messages = [('RadarStatus', 16)] self.num_points = 40 self.trigger_msg = 1119 @@ -46,7 +46,7 @@ class RadarInterface(RadarInterfaceBase): if not self.rcp.can_valid: errors.append('canError') - if self.CP.carFingerprint == CAR.MODELS_RAVEN: + if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN: radar_status = self.rcp.vl['RadarStatus'] if radar_status['sensorBlocked'] or radar_status['shortTermUnavailable'] or radar_status['vehDynamicsError']: errors.append('fault') diff --git a/selfdrive/car/tesla/values.py b/selfdrive/car/tesla/values.py index ca3bb38a7a..0f9cd00f63 100644 --- a/selfdrive/car/tesla/values.py +++ b/selfdrive/car/tesla/values.py @@ -2,7 +2,7 @@ from collections import namedtuple from cereal import car from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, PlatformConfig, Platforms, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarInfo +from openpilot.selfdrive.car.docs_definitions import CarDocs from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -10,22 +10,19 @@ Ecu = car.CarParams.Ecu Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) class CAR(Platforms): - AP1_MODELS = PlatformConfig( - 'TESLA AP1 MODEL S', - CarInfo("Tesla AP1 Model S", "All"), + TESLA_AP1_MODELS = PlatformConfig( + [CarDocs("Tesla AP1 Model S", "All")], CarSpecs(mass=2100., wheelbase=2.959, steerRatio=15.0), dbc_dict('tesla_powertrain', 'tesla_radar_bosch_generated', chassis_dbc='tesla_can') ) - AP2_MODELS = PlatformConfig( - 'TESLA AP2 MODEL S', - CarInfo("Tesla AP2 Model S", "All"), - AP1_MODELS.specs, - AP1_MODELS.dbc_dict + TESLA_AP2_MODELS = PlatformConfig( + [CarDocs("Tesla AP2 Model S", "All")], + TESLA_AP1_MODELS.specs, + TESLA_AP1_MODELS.dbc_dict ) - MODELS_RAVEN = PlatformConfig( - 'TESLA MODEL S RAVEN', - CarInfo("Tesla Model S Raven", "All"), - AP1_MODELS.specs, + TESLA_MODELS_RAVEN = PlatformConfig( + [CarDocs("Tesla Model S Raven", "All")], + TESLA_AP1_MODELS.specs, dbc_dict('tesla_powertrain', 'tesla_radar_continental_generated', chassis_dbc='tesla_can') ) diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 265f052b16..036f39c1f3 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -17,14 +17,14 @@ from openpilot.selfdrive.car.body.values import CAR as COMMA # TODO: add routes for these cars non_tested_cars = [ - FORD.F_150_MK14, + FORD.FORD_F_150_MK14, GM.CADILLAC_ATS, GM.HOLDEN_ASTRA, - GM.MALIBU, + GM.CHEVROLET_MALIBU, HYUNDAI.GENESIS_G90, - HONDA.ODYSSEY_CHN, - VOLKSWAGEN.CRAFTER_MK2, # need a route from an ACC-equipped Crafter - SUBARU.FORESTER_HYBRID, + HONDA.HONDA_ODYSSEY_CHN, + VOLKSWAGEN.VOLKSWAGEN_CRAFTER_MK2, # need a route from an ACC-equipped Crafter + SUBARU.SUBARU_FORESTER_HYBRID, ] @@ -35,81 +35,81 @@ class CarTestRoute(NamedTuple): routes = [ - CarTestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.BODY), + CarTestRoute("efdf9af95e71cd84|2022-05-13--19-03-31", COMMA.COMMA_BODY), CarTestRoute("0c94aa1e1296d7c6|2021-05-05--19-48-37", CHRYSLER.JEEP_GRAND_CHEROKEE), CarTestRoute("91dfedae61d7bd75|2021-05-22--20-07-52", CHRYSLER.JEEP_GRAND_CHEROKEE_2019), - CarTestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.PACIFICA_2017_HYBRID), - CarTestRoute("43a685a66291579b|2021-05-27--19-47-29", CHRYSLER.PACIFICA_2018), - CarTestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.PACIFICA_2018_HYBRID), - CarTestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.PACIFICA_2019_HYBRID), - CarTestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.PACIFICA_2020), - CarTestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500), - CarTestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD, segment=6), + CarTestRoute("420a8e183f1aed48|2020-03-05--07-15-29", CHRYSLER.CHRYSLER_PACIFICA_2017_HYBRID), + CarTestRoute("43a685a66291579b|2021-05-27--19-47-29", CHRYSLER.CHRYSLER_PACIFICA_2018), + CarTestRoute("378472f830ee7395|2021-05-28--07-38-43", CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID), + CarTestRoute("8190c7275a24557b|2020-01-29--08-33-58", CHRYSLER.CHRYSLER_PACIFICA_2019_HYBRID), + CarTestRoute("3d84727705fecd04|2021-05-25--08-38-56", CHRYSLER.CHRYSLER_PACIFICA_2020), + CarTestRoute("221c253375af4ee9|2022-06-15--18-38-24", CHRYSLER.RAM_1500_5TH_GEN), + CarTestRoute("8fb5eabf914632ae|2022-08-04--17-28-53", CHRYSLER.RAM_HD_5TH_GEN, segment=6), CarTestRoute("3379c85aeedc8285|2023-12-07--17-49-39", CHRYSLER.DODGE_DURANGO), - CarTestRoute("54827bf84c38b14f|2023-01-25--14-14-11", FORD.BRONCO_SPORT_MK1), - CarTestRoute("f8eaaccd2a90aef8|2023-05-04--15-10-09", FORD.ESCAPE_MK4), - CarTestRoute("62241b0c7fea4589|2022-09-01--15-32-49", FORD.EXPLORER_MK6), - CarTestRoute("e886087f430e7fe7|2023-06-16--23-06-36", FORD.FOCUS_MK4), - CarTestRoute("bd37e43731e5964b|2023-04-30--10-42-26", FORD.MAVERICK_MK1), - CarTestRoute("112e4d6e0cad05e1|2023-11-14--08-21-43", FORD.F_150_LIGHTNING_MK1), - CarTestRoute("83a4e056c7072678|2023-11-13--16-51-33", FORD.MUSTANG_MACH_E_MK1), + CarTestRoute("54827bf84c38b14f|2023-01-25--14-14-11", FORD.FORD_BRONCO_SPORT_MK1), + CarTestRoute("f8eaaccd2a90aef8|2023-05-04--15-10-09", FORD.FORD_ESCAPE_MK4), + CarTestRoute("62241b0c7fea4589|2022-09-01--15-32-49", FORD.FORD_EXPLORER_MK6), + CarTestRoute("e886087f430e7fe7|2023-06-16--23-06-36", FORD.FORD_FOCUS_MK4), + CarTestRoute("bd37e43731e5964b|2023-04-30--10-42-26", FORD.FORD_MAVERICK_MK1), + CarTestRoute("112e4d6e0cad05e1|2023-11-14--08-21-43", FORD.FORD_F_150_LIGHTNING_MK1), + CarTestRoute("83a4e056c7072678|2023-11-13--16-51-33", FORD.FORD_MUSTANG_MACH_E_MK1), #TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION), - CarTestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.ACADIA), + CarTestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.GMC_ACADIA), CarTestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL), CarTestRoute("75a6bcb9b8b40373|2023-03-11--22-47-33", GM.BUICK_LACROSSE), - CarTestRoute("e746f59bc96fd789|2024-01-31--22-25-58", GM.EQUINOX), - CarTestRoute("ef8f2185104d862e|2023-02-09--18-37-13", GM.ESCALADE), - CarTestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV), - CarTestRoute("168f8b3be57f66ae|2023-09-12--21-44-42", GM.ESCALADE_ESV_2019), - CarTestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT), - CarTestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.BOLT_EUV, segment=1), - CarTestRoute("555d4087cf86aa91|2022-12-02--12-15-07", GM.BOLT_EUV, segment=14), # Bolt EV - CarTestRoute("38aa7da107d5d252|2022-08-15--16-01-12", GM.SILVERADO), - CarTestRoute("5085c761395d1fe6|2023-04-07--18-20-06", GM.TRAILBLAZER), + CarTestRoute("e746f59bc96fd789|2024-01-31--22-25-58", GM.CHEVROLET_EQUINOX), + CarTestRoute("ef8f2185104d862e|2023-02-09--18-37-13", GM.CADILLAC_ESCALADE), + CarTestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.CADILLAC_ESCALADE_ESV), + CarTestRoute("168f8b3be57f66ae|2023-09-12--21-44-42", GM.CADILLAC_ESCALADE_ESV_2019), + CarTestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.CHEVROLET_VOLT), + CarTestRoute("f08912a233c1584f|2022-08-11--18-02-41", GM.CHEVROLET_BOLT_EUV, segment=1), + CarTestRoute("555d4087cf86aa91|2022-12-02--12-15-07", GM.CHEVROLET_BOLT_EUV, segment=14), # Bolt EV + CarTestRoute("38aa7da107d5d252|2022-08-15--16-01-12", GM.CHEVROLET_SILVERADO), + CarTestRoute("5085c761395d1fe6|2023-04-07--18-20-06", GM.CHEVROLET_TRAILBLAZER), CarTestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), - CarTestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), - CarTestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.CRV_EU), - CarTestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.CRV), - CarTestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.CRV_HYBRID), - CarTestRoute("52f3e9ae60c0d886|2021-05-23--15-59-43", HONDA.FIT), - CarTestRoute("2c4292a5cd10536c|2021-08-19--21-32-15", HONDA.FREED), - CarTestRoute("03be5f2fd5c508d1|2020-04-19--18-44-15", HONDA.HRV), - CarTestRoute("320098ff6c5e4730|2023-04-13--17-47-46", HONDA.HRV_3G), + CarTestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.HONDA_CIVIC), + CarTestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.HONDA_CRV_EU), + CarTestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.HONDA_CRV), + CarTestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.HONDA_CRV_HYBRID), + CarTestRoute("52f3e9ae60c0d886|2021-05-23--15-59-43", HONDA.HONDA_FIT), + CarTestRoute("2c4292a5cd10536c|2021-08-19--21-32-15", HONDA.HONDA_FREED), + CarTestRoute("03be5f2fd5c508d1|2020-04-19--18-44-15", HONDA.HONDA_HRV), + CarTestRoute("320098ff6c5e4730|2023-04-13--17-47-46", HONDA.HONDA_HRV_3G), CarTestRoute("917b074700869333|2021-05-24--20-40-20", HONDA.ACURA_ILX), - CarTestRoute("08a3deb07573f157|2020-03-06--16-11-19", HONDA.ACCORD), # 1.5T - CarTestRoute("1da5847ac2488106|2021-05-24--19-31-50", HONDA.ACCORD), # 2.0T - CarTestRoute("085ac1d942c35910|2021-03-25--20-11-15", HONDA.ACCORD), # 2021 with new style HUD msgs - CarTestRoute("07585b0da3c88459|2021-05-26--18-52-04", HONDA.ACCORD), # hybrid - CarTestRoute("f29e2b57a55e7ad5|2021-03-24--20-52-38", HONDA.ACCORD), # hybrid, 2021 with new style HUD msgs - CarTestRoute("1ad763dd22ef1a0e|2020-02-29--18-37-03", HONDA.CRV_5G), - CarTestRoute("0a96f86fcfe35964|2020-02-05--07-25-51", HONDA.ODYSSEY), - CarTestRoute("d83f36766f8012a5|2020-02-05--18-42-21", HONDA.CIVIC_BOSCH_DIESEL), - CarTestRoute("f0890d16a07a236b|2021-05-25--17-27-22", HONDA.INSIGHT), - CarTestRoute("07d37d27996096b6|2020-03-04--21-57-27", HONDA.PILOT), - CarTestRoute("684e8f96bd491a0e|2021-11-03--11-08-42", HONDA.PILOT), # Passport - CarTestRoute("0a78dfbacc8504ef|2020-03-04--13-29-55", HONDA.CIVIC_BOSCH), + CarTestRoute("08a3deb07573f157|2020-03-06--16-11-19", HONDA.HONDA_ACCORD), # 1.5T + CarTestRoute("1da5847ac2488106|2021-05-24--19-31-50", HONDA.HONDA_ACCORD), # 2.0T + CarTestRoute("085ac1d942c35910|2021-03-25--20-11-15", HONDA.HONDA_ACCORD), # 2021 with new style HUD msgs + CarTestRoute("07585b0da3c88459|2021-05-26--18-52-04", HONDA.HONDA_ACCORD), # hybrid + CarTestRoute("f29e2b57a55e7ad5|2021-03-24--20-52-38", HONDA.HONDA_ACCORD), # hybrid, 2021 with new style HUD msgs + CarTestRoute("1ad763dd22ef1a0e|2020-02-29--18-37-03", HONDA.HONDA_CRV_5G), + CarTestRoute("0a96f86fcfe35964|2020-02-05--07-25-51", HONDA.HONDA_ODYSSEY), + CarTestRoute("d83f36766f8012a5|2020-02-05--18-42-21", HONDA.HONDA_CIVIC_BOSCH_DIESEL), + CarTestRoute("f0890d16a07a236b|2021-05-25--17-27-22", HONDA.HONDA_INSIGHT), + CarTestRoute("07d37d27996096b6|2020-03-04--21-57-27", HONDA.HONDA_PILOT), + CarTestRoute("684e8f96bd491a0e|2021-11-03--11-08-42", HONDA.HONDA_PILOT), # Passport + CarTestRoute("0a78dfbacc8504ef|2020-03-04--13-29-55", HONDA.HONDA_CIVIC_BOSCH), CarTestRoute("f34a60d68d83b1e5|2020-10-06--14-35-55", HONDA.ACURA_RDX), - CarTestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.RIDGELINE), + CarTestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.HONDA_RIDGELINE), CarTestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E), - CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.CIVIC_2022), + CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.HONDA_CIVIC_2022), - CarTestRoute("87d7f06ade479c2e|2023-09-11--23-30-11", HYUNDAI.AZERA_6TH_GEN), - CarTestRoute("66189dd8ec7b50e6|2023-09-20--07-02-12", HYUNDAI.AZERA_HEV_6TH_GEN), + CarTestRoute("87d7f06ade479c2e|2023-09-11--23-30-11", HYUNDAI.HYUNDAI_AZERA_6TH_GEN), + CarTestRoute("66189dd8ec7b50e6|2023-09-20--07-02-12", HYUNDAI.HYUNDAI_AZERA_HEV_6TH_GEN), CarTestRoute("6fe86b4e410e4c37|2020-07-22--16-27-13", HYUNDAI.HYUNDAI_GENESIS), CarTestRoute("b5d6dc830ad63071|2022-12-12--21-28-25", HYUNDAI.GENESIS_GV60_EV_1ST_GEN, segment=12), CarTestRoute("70c5bec28ec8e345|2020-08-08--12-22-23", HYUNDAI.GENESIS_G70), CarTestRoute("ca4de5b12321bd98|2022-10-18--21-15-59", HYUNDAI.GENESIS_GV70_1ST_GEN), CarTestRoute("6b301bf83f10aa90|2020-11-22--16-45-07", HYUNDAI.GENESIS_G80), - CarTestRoute("0bbe367c98fa1538|2023-09-16--00-16-49", HYUNDAI.CUSTIN_1ST_GEN), - CarTestRoute("f0709d2bc6ca451f|2022-10-15--08-13-54", HYUNDAI.SANTA_CRUZ_1ST_GEN), - CarTestRoute("4dbd55df87507948|2022-03-01--09-45-38", HYUNDAI.SANTA_FE), - CarTestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.SANTA_FE_2022), - CarTestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.SANTA_FE_HEV_2022), - CarTestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022, segment=1), + CarTestRoute("0bbe367c98fa1538|2023-09-16--00-16-49", HYUNDAI.HYUNDAI_CUSTIN_1ST_GEN), + CarTestRoute("f0709d2bc6ca451f|2022-10-15--08-13-54", HYUNDAI.HYUNDAI_SANTA_CRUZ_1ST_GEN), + CarTestRoute("4dbd55df87507948|2022-03-01--09-45-38", HYUNDAI.HYUNDAI_SANTA_FE), + CarTestRoute("bf43d9df2b660eb0|2021-09-23--14-16-37", HYUNDAI.HYUNDAI_SANTA_FE_2022), + CarTestRoute("37398f32561a23ad|2021-11-18--00-11-35", HYUNDAI.HYUNDAI_SANTA_FE_HEV_2022), + CarTestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.HYUNDAI_SANTA_FE_PHEV_2022, segment=1), CarTestRoute("de59124955b921d8|2023-06-24--00-12-50", HYUNDAI.KIA_CARNIVAL_4TH_GEN), CarTestRoute("409c9409979a8abc|2023-07-11--09-06-44", HYUNDAI.KIA_CARNIVAL_4TH_GEN), # Chinese model CarTestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED), @@ -118,36 +118,36 @@ routes = [ CarTestRoute("f9716670b2481438|2023-08-23--14-49-50", HYUNDAI.KIA_OPTIMA_H), CarTestRoute("6a42c1197b2a8179|2023-09-21--10-23-44", HYUNDAI.KIA_OPTIMA_H_G4_FL), CarTestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), - CarTestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA), - CarTestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF), - CarTestRoute("c344fd2492c7a9d2|2023-12-11--09-03-23", HYUNDAI.STARIA_4TH_GEN), - CarTestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.TUCSON), - CarTestRoute("db68bbe12250812c|2022-12-05--00-54-12", HYUNDAI.TUCSON_4TH_GEN), # 2023 - CarTestRoute("36e10531feea61a4|2022-07-25--13-37-42", HYUNDAI.TUCSON_4TH_GEN), # hybrid + CarTestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.HYUNDAI_SONATA), + CarTestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.HYUNDAI_SONATA_LF), + CarTestRoute("c344fd2492c7a9d2|2023-12-11--09-03-23", HYUNDAI.HYUNDAI_STARIA_4TH_GEN), + CarTestRoute("fb3fd42f0baaa2f8|2022-03-30--15-25-05", HYUNDAI.HYUNDAI_TUCSON), + CarTestRoute("db68bbe12250812c|2022-12-05--00-54-12", HYUNDAI.HYUNDAI_TUCSON_4TH_GEN), # 2023 + CarTestRoute("36e10531feea61a4|2022-07-25--13-37-42", HYUNDAI.HYUNDAI_TUCSON_4TH_GEN), # hybrid CarTestRoute("5875672fc1d4bf57|2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), CarTestRoute("1d0d000db3370fd0|2023-01-04--22-28-42", HYUNDAI.KIA_SORENTO_4TH_GEN, segment=5), CarTestRoute("fc19648042eb6896|2023-08-16--11-43-27", HYUNDAI.KIA_SORENTO_HEV_4TH_GEN, segment=14), CarTestRoute("628935d7d3e5f4f7|2022-11-30--01-12-46", HYUNDAI.KIA_SORENTO_HEV_4TH_GEN), # plug-in hybrid - CarTestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.PALISADE), - CarTestRoute("05a8f0197fdac372|2022-10-19--14-14-09", HYUNDAI.IONIQ_5), # HDA2 - CarTestRoute("eb4eae1476647463|2023-08-26--18-07-04", HYUNDAI.IONIQ_6, segment=6), # HDA2 - CarTestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.IONIQ_PHEV_2019), - CarTestRoute("fa8db5869167f821|2021-06-10--22-50-10", HYUNDAI.IONIQ_PHEV), - CarTestRoute("e1107f9d04dfb1e2|2023-09-05--22-32-12", HYUNDAI.IONIQ_PHEV), # openpilot longitudinal enabled - CarTestRoute("2c5cf2dd6102e5da|2020-12-17--16-06-44", HYUNDAI.IONIQ_EV_2020), - CarTestRoute("610ebb9faaad6b43|2020-06-13--15-28-36", HYUNDAI.IONIQ_EV_LTD), - CarTestRoute("2c5cf2dd6102e5da|2020-06-26--16-00-08", HYUNDAI.IONIQ), - CarTestRoute("012c95f06918eca4|2023-01-15--11-19-36", HYUNDAI.IONIQ), # openpilot longitudinal enabled - CarTestRoute("ab59fe909f626921|2021-10-18--18-34-28", HYUNDAI.IONIQ_HEV_2022), - CarTestRoute("22d955b2cd499c22|2020-08-10--19-58-21", HYUNDAI.KONA), - CarTestRoute("efc48acf44b1e64d|2021-05-28--21-05-04", HYUNDAI.KONA_EV), - CarTestRoute("f90d3cd06caeb6fa|2023-09-06--17-15-47", HYUNDAI.KONA_EV), # openpilot longitudinal enabled - CarTestRoute("ff973b941a69366f|2022-07-28--22-01-19", HYUNDAI.KONA_EV_2022, segment=11), - CarTestRoute("1618132d68afc876|2023-08-27--09-32-14", HYUNDAI.KONA_EV_2ND_GEN, segment=13), - CarTestRoute("49f3c13141b6bc87|2021-07-28--08-05-13", HYUNDAI.KONA_HEV), + CarTestRoute("9c917ba0d42ffe78|2020-04-17--12-43-19", HYUNDAI.HYUNDAI_PALISADE), + CarTestRoute("05a8f0197fdac372|2022-10-19--14-14-09", HYUNDAI.HYUNDAI_IONIQ_5), # HDA2 + CarTestRoute("eb4eae1476647463|2023-08-26--18-07-04", HYUNDAI.HYUNDAI_IONIQ_6, segment=6), # HDA2 + CarTestRoute("3f29334d6134fcd4|2022-03-30--22-00-50", HYUNDAI.HYUNDAI_IONIQ_PHEV_2019), + CarTestRoute("fa8db5869167f821|2021-06-10--22-50-10", HYUNDAI.HYUNDAI_IONIQ_PHEV), + CarTestRoute("e1107f9d04dfb1e2|2023-09-05--22-32-12", HYUNDAI.HYUNDAI_IONIQ_PHEV), # openpilot longitudinal enabled + CarTestRoute("2c5cf2dd6102e5da|2020-12-17--16-06-44", HYUNDAI.HYUNDAI_IONIQ_EV_2020), + CarTestRoute("610ebb9faaad6b43|2020-06-13--15-28-36", HYUNDAI.HYUNDAI_IONIQ_EV_LTD), + CarTestRoute("2c5cf2dd6102e5da|2020-06-26--16-00-08", HYUNDAI.HYUNDAI_IONIQ), + CarTestRoute("012c95f06918eca4|2023-01-15--11-19-36", HYUNDAI.HYUNDAI_IONIQ), # openpilot longitudinal enabled + CarTestRoute("ab59fe909f626921|2021-10-18--18-34-28", HYUNDAI.HYUNDAI_IONIQ_HEV_2022), + CarTestRoute("22d955b2cd499c22|2020-08-10--19-58-21", HYUNDAI.HYUNDAI_KONA), + CarTestRoute("efc48acf44b1e64d|2021-05-28--21-05-04", HYUNDAI.HYUNDAI_KONA_EV), + CarTestRoute("f90d3cd06caeb6fa|2023-09-06--17-15-47", HYUNDAI.HYUNDAI_KONA_EV), # openpilot longitudinal enabled + CarTestRoute("ff973b941a69366f|2022-07-28--22-01-19", HYUNDAI.HYUNDAI_KONA_EV_2022, segment=11), + CarTestRoute("1618132d68afc876|2023-08-27--09-32-14", HYUNDAI.HYUNDAI_KONA_EV_2ND_GEN, segment=13), + CarTestRoute("49f3c13141b6bc87|2021-07-28--08-05-13", HYUNDAI.HYUNDAI_KONA_HEV), CarTestRoute("5dddcbca6eb66c62|2020-07-26--13-24-19", HYUNDAI.KIA_STINGER), CarTestRoute("5b50b883a4259afb|2022-11-09--15-00-42", HYUNDAI.KIA_STINGER_2022), - CarTestRoute("d624b3d19adce635|2020-08-01--14-59-12", HYUNDAI.VELOSTER), + CarTestRoute("d624b3d19adce635|2020-08-01--14-59-12", HYUNDAI.HYUNDAI_VELOSTER), CarTestRoute("d545129f3ca90f28|2022-10-19--09-22-54", HYUNDAI.KIA_EV6), # HDA2 CarTestRoute("68d6a96e703c00c9|2022-09-10--16-09-39", HYUNDAI.KIA_EV6), # HDA1 CarTestRoute("9b25e8c1484a1b67|2023-04-13--10-41-45", HYUNDAI.KIA_EV6), @@ -164,37 +164,37 @@ routes = [ CarTestRoute("192283cdbb7a58c2|2022-10-15--01-43-18", HYUNDAI.KIA_SPORTAGE_5TH_GEN), CarTestRoute("09559f1fcaed4704|2023-11-16--02-24-57", HYUNDAI.KIA_SPORTAGE_5TH_GEN), # openpilot longitudinal CarTestRoute("b3537035ffe6a7d6|2022-10-17--15-23-49", HYUNDAI.KIA_SPORTAGE_5TH_GEN), # hybrid - CarTestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.ELANTRA), - CarTestRoute("734ef96182ddf940|2022-10-02--16-41-44", HYUNDAI.ELANTRA_GT_I30), - CarTestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.ELANTRA_2021), - CarTestRoute("715ac05b594e9c59|2021-06-20--16-21-07", HYUNDAI.ELANTRA_HEV_2021), - CarTestRoute("7120aa90bbc3add7|2021-08-02--07-12-31", HYUNDAI.SONATA_HYBRID), + CarTestRoute("c5ac319aa9583f83|2021-06-01--18-18-31", HYUNDAI.HYUNDAI_ELANTRA), + CarTestRoute("734ef96182ddf940|2022-10-02--16-41-44", HYUNDAI.HYUNDAI_ELANTRA_GT_I30), + CarTestRoute("82e9cdd3f43bf83e|2021-05-15--02-42-51", HYUNDAI.HYUNDAI_ELANTRA_2021), + CarTestRoute("715ac05b594e9c59|2021-06-20--16-21-07", HYUNDAI.HYUNDAI_ELANTRA_HEV_2021), + CarTestRoute("7120aa90bbc3add7|2021-08-02--07-12-31", HYUNDAI.HYUNDAI_SONATA_HYBRID), CarTestRoute("715ac05b594e9c59|2021-10-27--23-24-56", HYUNDAI.GENESIS_G70_2020), CarTestRoute("6b0d44d22df18134|2023-05-06--10-36-55", HYUNDAI.GENESIS_GV80), - CarTestRoute("00c829b1b7613dea|2021-06-24--09-10-10", TOYOTA.ALPHARD_TSS2), - CarTestRoute("912119ebd02c7a42|2022-03-19--07-24-50", TOYOTA.ALPHARD_TSS2), # hybrid - CarTestRoute("000cf3730200c71c|2021-05-24--10-42-05", TOYOTA.AVALON), - CarTestRoute("0bb588106852abb7|2021-05-26--12-22-01", TOYOTA.AVALON_2019), - CarTestRoute("87bef2930af86592|2021-05-30--09-40-54", TOYOTA.AVALON_2019), # hybrid - CarTestRoute("e9966711cfb04ce3|2022-01-11--07-59-43", TOYOTA.AVALON_TSS2), - CarTestRoute("eca1080a91720a54|2022-03-17--13-32-29", TOYOTA.AVALON_TSS2), # hybrid - CarTestRoute("6cdecc4728d4af37|2020-02-23--15-44-18", TOYOTA.CAMRY), - CarTestRoute("2f37c007683e85ba|2023-09-02--14-39-44", TOYOTA.CAMRY), # openpilot longitudinal, with radar CAN filter - CarTestRoute("54034823d30962f5|2021-05-24--06-37-34", TOYOTA.CAMRY), # hybrid - CarTestRoute("3456ad0cd7281b24|2020-12-13--17-45-56", TOYOTA.CAMRY_TSS2), - CarTestRoute("ffccc77938ddbc44|2021-01-04--16-55-41", TOYOTA.CAMRY_TSS2), # hybrid - CarTestRoute("4e45c89c38e8ec4d|2021-05-02--02-49-28", TOYOTA.COROLLA), - CarTestRoute("5f5afb36036506e4|2019-05-14--02-09-54", TOYOTA.COROLLA_TSS2), - CarTestRoute("5ceff72287a5c86c|2019-10-19--10-59-02", TOYOTA.COROLLA_TSS2), # hybrid - CarTestRoute("d2525c22173da58b|2021-04-25--16-47-04", TOYOTA.PRIUS), - CarTestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.RAV4), - CarTestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.RAV4H), - CarTestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.RAV4_TSS2), - CarTestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.RAV4_TSS2_2022), - CarTestRoute("ad5a3fa719bc2f83|2023-10-17--19-48-42", TOYOTA.RAV4_TSS2_2023), - CarTestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.RAV4_TSS2), # hybrid - CarTestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.RAV4_TSS2_2022), # hybrid + CarTestRoute("00c829b1b7613dea|2021-06-24--09-10-10", TOYOTA.TOYOTA_ALPHARD_TSS2), + CarTestRoute("912119ebd02c7a42|2022-03-19--07-24-50", TOYOTA.TOYOTA_ALPHARD_TSS2), # hybrid + CarTestRoute("000cf3730200c71c|2021-05-24--10-42-05", TOYOTA.TOYOTA_AVALON), + CarTestRoute("0bb588106852abb7|2021-05-26--12-22-01", TOYOTA.TOYOTA_AVALON_2019), + CarTestRoute("87bef2930af86592|2021-05-30--09-40-54", TOYOTA.TOYOTA_AVALON_2019), # hybrid + CarTestRoute("e9966711cfb04ce3|2022-01-11--07-59-43", TOYOTA.TOYOTA_AVALON_TSS2), + CarTestRoute("eca1080a91720a54|2022-03-17--13-32-29", TOYOTA.TOYOTA_AVALON_TSS2), # hybrid + CarTestRoute("6cdecc4728d4af37|2020-02-23--15-44-18", TOYOTA.TOYOTA_CAMRY), + CarTestRoute("2f37c007683e85ba|2023-09-02--14-39-44", TOYOTA.TOYOTA_CAMRY), # openpilot longitudinal, with radar CAN filter + CarTestRoute("54034823d30962f5|2021-05-24--06-37-34", TOYOTA.TOYOTA_CAMRY), # hybrid + CarTestRoute("3456ad0cd7281b24|2020-12-13--17-45-56", TOYOTA.TOYOTA_CAMRY_TSS2), + CarTestRoute("ffccc77938ddbc44|2021-01-04--16-55-41", TOYOTA.TOYOTA_CAMRY_TSS2), # hybrid + CarTestRoute("4e45c89c38e8ec4d|2021-05-02--02-49-28", TOYOTA.TOYOTA_COROLLA), + CarTestRoute("5f5afb36036506e4|2019-05-14--02-09-54", TOYOTA.TOYOTA_COROLLA_TSS2), + CarTestRoute("5ceff72287a5c86c|2019-10-19--10-59-02", TOYOTA.TOYOTA_COROLLA_TSS2), # hybrid + CarTestRoute("d2525c22173da58b|2021-04-25--16-47-04", TOYOTA.TOYOTA_PRIUS), + CarTestRoute("b14c5b4742e6fc85|2020-07-28--19-50-11", TOYOTA.TOYOTA_RAV4), + CarTestRoute("32a7df20486b0f70|2020-02-06--16-06-50", TOYOTA.TOYOTA_RAV4H), + CarTestRoute("cdf2f7de565d40ae|2019-04-25--03-53-41", TOYOTA.TOYOTA_RAV4_TSS2), + CarTestRoute("a5c341bb250ca2f0|2022-05-18--16-05-17", TOYOTA.TOYOTA_RAV4_TSS2_2022), + CarTestRoute("ad5a3fa719bc2f83|2023-10-17--19-48-42", TOYOTA.TOYOTA_RAV4_TSS2_2023), + CarTestRoute("7e34a988419b5307|2019-12-18--19-13-30", TOYOTA.TOYOTA_RAV4_TSS2), # hybrid + CarTestRoute("2475fb3eb2ffcc2e|2022-04-29--12-46-23", TOYOTA.TOYOTA_RAV4_TSS2_2022), # hybrid CarTestRoute("7a31f030957b9c85|2023-04-01--14-12-51", TOYOTA.LEXUS_ES), CarTestRoute("37041c500fd30100|2020-12-30--12-17-24", TOYOTA.LEXUS_ES), # hybrid CarTestRoute("e6a24be49a6cd46e|2019-10-29--10-52-42", TOYOTA.LEXUS_ES_TSS2), @@ -211,39 +211,39 @@ routes = [ CarTestRoute("3fd5305f8b6ca765|2021-04-28--19-26-49", TOYOTA.LEXUS_NX_TSS2), CarTestRoute("09ae96064ed85a14|2022-06-09--12-22-31", TOYOTA.LEXUS_NX_TSS2), # hybrid CarTestRoute("4765fbbf59e3cd88|2024-02-06--17-45-32", TOYOTA.LEXUS_LC_TSS2), - CarTestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.HIGHLANDER_TSS2), - CarTestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.HIGHLANDER_TSS2), # hybrid - CarTestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.HIGHLANDER), - CarTestRoute("80d16a262e33d57f|2021-05-23--20-01-43", TOYOTA.HIGHLANDER), # hybrid - CarTestRoute("eb6acd681135480d|2019-06-20--20-00-00", TOYOTA.SIENNA), + CarTestRoute("0a302ffddbb3e3d3|2020-02-08--16-19-08", TOYOTA.TOYOTA_HIGHLANDER_TSS2), + CarTestRoute("437e4d2402abf524|2021-05-25--07-58-50", TOYOTA.TOYOTA_HIGHLANDER_TSS2), # hybrid + CarTestRoute("3183cd9b021e89ce|2021-05-25--10-34-44", TOYOTA.TOYOTA_HIGHLANDER), + CarTestRoute("80d16a262e33d57f|2021-05-23--20-01-43", TOYOTA.TOYOTA_HIGHLANDER), # hybrid + CarTestRoute("eb6acd681135480d|2019-06-20--20-00-00", TOYOTA.TOYOTA_SIENNA), CarTestRoute("2e07163a1ba9a780|2019-08-25--13-15-13", TOYOTA.LEXUS_IS), CarTestRoute("649bf2997ada6e3a|2023-08-08--18-04-22", TOYOTA.LEXUS_IS_TSS2), - CarTestRoute("0a0de17a1e6a2d15|2020-09-21--21-24-41", TOYOTA.PRIUS_TSS2), - CarTestRoute("9b36accae406390e|2021-03-30--10-41-38", TOYOTA.MIRAI), - CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.CHR), - CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.CHR), # hybrid - CarTestRoute("ea8fbe72b96a185c|2023-02-08--15-11-46", TOYOTA.CHR_TSS2), - CarTestRoute("ea8fbe72b96a185c|2023-02-22--09-20-34", TOYOTA.CHR_TSS2), # openpilot longitudinal, with smartDSU - CarTestRoute("6719965b0e1d1737|2023-02-09--22-44-05", TOYOTA.CHR_TSS2), # hybrid - CarTestRoute("6719965b0e1d1737|2023-08-29--06-40-05", TOYOTA.CHR_TSS2), # hybrid, openpilot longitudinal, radar disabled - CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.PRIUS_V), + CarTestRoute("0a0de17a1e6a2d15|2020-09-21--21-24-41", TOYOTA.TOYOTA_PRIUS_TSS2), + CarTestRoute("9b36accae406390e|2021-03-30--10-41-38", TOYOTA.TOYOTA_MIRAI), + CarTestRoute("cd9cff4b0b26c435|2021-05-13--15-12-39", TOYOTA.TOYOTA_CHR), + CarTestRoute("57858ede0369a261|2021-05-18--20-34-20", TOYOTA.TOYOTA_CHR), # hybrid + CarTestRoute("ea8fbe72b96a185c|2023-02-08--15-11-46", TOYOTA.TOYOTA_CHR_TSS2), + CarTestRoute("ea8fbe72b96a185c|2023-02-22--09-20-34", TOYOTA.TOYOTA_CHR_TSS2), # openpilot longitudinal, with smartDSU + CarTestRoute("6719965b0e1d1737|2023-02-09--22-44-05", TOYOTA.TOYOTA_CHR_TSS2), # hybrid + CarTestRoute("6719965b0e1d1737|2023-08-29--06-40-05", TOYOTA.TOYOTA_CHR_TSS2), # hybrid, openpilot longitudinal, radar disabled + CarTestRoute("14623aae37e549f3|2021-10-24--01-20-49", TOYOTA.TOYOTA_PRIUS_V), - CarTestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.ARTEON_MK1), - CarTestRoute("2c68dda277d887ac|2021-05-11--15-22-20", VOLKSWAGEN.ATLAS_MK1), - CarTestRoute("ffcd23abbbd02219|2024-02-28--14-59-38", VOLKSWAGEN.CADDY_MK3), - CarTestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.GOLF_MK7), # Stock ACC - CarTestRoute("3cfdec54aa035f3f|2022-10-13--14-58-58", VOLKSWAGEN.GOLF_MK7), # openpilot longitudinal - CarTestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.JETTA_MK7), - CarTestRoute("4d134e099430fba2|2021-03-26--00-26-06", VOLKSWAGEN.PASSAT_MK8), - CarTestRoute("3cfdec54aa035f3f|2022-07-19--23-45-10", VOLKSWAGEN.PASSAT_NMS), - CarTestRoute("0cd0b7f7e31a3853|2021-11-03--19-30-22", VOLKSWAGEN.POLO_MK6), - CarTestRoute("064d1816e448f8eb|2022-09-29--15-32-34", VOLKSWAGEN.SHARAN_MK2), - CarTestRoute("7d82b2f3a9115f1f|2021-10-21--15-39-42", VOLKSWAGEN.TAOS_MK1), - CarTestRoute("2744c89a8dda9a51|2021-07-24--21-28-06", VOLKSWAGEN.TCROSS_MK1), - CarTestRoute("2cef8a0b898f331a|2021-03-25--20-13-57", VOLKSWAGEN.TIGUAN_MK2), - CarTestRoute("a589dcc642fdb10a|2021-06-14--20-54-26", VOLKSWAGEN.TOURAN_MK2), - CarTestRoute("a459f4556782eba1|2021-09-19--09-48-00", VOLKSWAGEN.TRANSPORTER_T61), - CarTestRoute("0cd0b7f7e31a3853|2021-11-18--00-38-32", VOLKSWAGEN.TROC_MK1), + CarTestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.VOLKSWAGEN_ARTEON_MK1), + CarTestRoute("2c68dda277d887ac|2021-05-11--15-22-20", VOLKSWAGEN.VOLKSWAGEN_ATLAS_MK1), + CarTestRoute("ffcd23abbbd02219|2024-02-28--14-59-38", VOLKSWAGEN.VOLKSWAGEN_CADDY_MK3), + CarTestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.VOLKSWAGEN_GOLF_MK7), # Stock ACC + CarTestRoute("3cfdec54aa035f3f|2022-10-13--14-58-58", VOLKSWAGEN.VOLKSWAGEN_GOLF_MK7), # openpilot longitudinal + CarTestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.VOLKSWAGEN_JETTA_MK7), + CarTestRoute("4d134e099430fba2|2021-03-26--00-26-06", VOLKSWAGEN.VOLKSWAGEN_PASSAT_MK8), + CarTestRoute("3cfdec54aa035f3f|2022-07-19--23-45-10", VOLKSWAGEN.VOLKSWAGEN_PASSAT_NMS), + CarTestRoute("0cd0b7f7e31a3853|2021-11-03--19-30-22", VOLKSWAGEN.VOLKSWAGEN_POLO_MK6), + CarTestRoute("064d1816e448f8eb|2022-09-29--15-32-34", VOLKSWAGEN.VOLKSWAGEN_SHARAN_MK2), + CarTestRoute("7d82b2f3a9115f1f|2021-10-21--15-39-42", VOLKSWAGEN.VOLKSWAGEN_TAOS_MK1), + CarTestRoute("2744c89a8dda9a51|2021-07-24--21-28-06", VOLKSWAGEN.VOLKSWAGEN_TCROSS_MK1), + CarTestRoute("2cef8a0b898f331a|2021-03-25--20-13-57", VOLKSWAGEN.VOLKSWAGEN_TIGUAN_MK2), + CarTestRoute("a589dcc642fdb10a|2021-06-14--20-54-26", VOLKSWAGEN.VOLKSWAGEN_TOURAN_MK2), + CarTestRoute("a459f4556782eba1|2021-09-19--09-48-00", VOLKSWAGEN.VOLKSWAGEN_TRANSPORTER_T61), + CarTestRoute("0cd0b7f7e31a3853|2021-11-18--00-38-32", VOLKSWAGEN.VOLKSWAGEN_TROC_MK1), CarTestRoute("07667b885add75fd|2021-01-23--19-48-42", VOLKSWAGEN.AUDI_A3_MK3), CarTestRoute("6c6b466346192818|2021-06-06--14-17-47", VOLKSWAGEN.AUDI_Q2_MK1), CarTestRoute("0cd0b7f7e31a3853|2021-12-03--03-12-05", VOLKSWAGEN.AUDI_Q3_MK2), @@ -257,44 +257,42 @@ routes = [ CarTestRoute("026b6d18fba6417f|2021-03-26--09-17-04", VOLKSWAGEN.SKODA_SCALA_MK1), CarTestRoute("b2e9858e29db492b|2021-03-26--16-58-42", VOLKSWAGEN.SKODA_SUPERB_MK3), - CarTestRoute("3c8f0c502e119c1c|2020-06-30--12-58-02", SUBARU.ASCENT), - CarTestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.FORESTER), - CarTestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA), - CarTestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020), - CarTestRoute("8de015561e1ea4a0|2023-08-29--17-08-31", SUBARU.IMPREZA), # openpilot longitudinal + CarTestRoute("3c8f0c502e119c1c|2020-06-30--12-58-02", SUBARU.SUBARU_ASCENT), + CarTestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.SUBARU_FORESTER), + CarTestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.SUBARU_IMPREZA), + CarTestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.SUBARU_IMPREZA_2020), + CarTestRoute("8de015561e1ea4a0|2023-08-29--17-08-31", SUBARU.SUBARU_IMPREZA), # openpilot longitudinal # CarTestRoute("c3d1ccb52f5f9d65|2023-07-22--01-23-20", SUBARU.OUTBACK, segment=9), # gen2 longitudinal, eyesight disabled - CarTestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=10), - CarTestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.LEGACY, segment=3), - CarTestRoute("f4e3a0c511a076f4|2022-08-04--16-16-48", SUBARU.CROSSTREK_HYBRID, segment=2), - CarTestRoute("7fd1e4f3a33c1673|2022-12-04--15-09-53", SUBARU.FORESTER_2022, segment=4), - CarTestRoute("f3b34c0d2632aa83|2023-07-23--20-43-25", SUBARU.OUTBACK_2023, segment=7), - CarTestRoute("99437cef6d5ff2ee|2023-03-13--21-21-38", SUBARU.ASCENT_2023, segment=7), + CarTestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.SUBARU_OUTBACK, segment=10), + CarTestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.SUBARU_LEGACY, segment=3), + CarTestRoute("f4e3a0c511a076f4|2022-08-04--16-16-48", SUBARU.SUBARU_CROSSTREK_HYBRID, segment=2), + CarTestRoute("7fd1e4f3a33c1673|2022-12-04--15-09-53", SUBARU.SUBARU_FORESTER_2022, segment=4), + CarTestRoute("f3b34c0d2632aa83|2023-07-23--20-43-25", SUBARU.SUBARU_OUTBACK_2023, segment=7), + CarTestRoute("99437cef6d5ff2ee|2023-03-13--21-21-38", SUBARU.SUBARU_ASCENT_2023, segment=7), # Pre-global, dashcam - CarTestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL), - CarTestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.LEGACY_PREGLOBAL), - CarTestRoute("5ab784f361e19b78|2020-06-08--16-30-41", SUBARU.OUTBACK_PREGLOBAL), - CarTestRoute("e19eb5d5353b1ac1|2020-08-09--14-37-56", SUBARU.OUTBACK_PREGLOBAL_2018), + CarTestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.SUBARU_FORESTER_PREGLOBAL), + CarTestRoute("df5ca7660000fba8|2020-06-16--17-37-19", SUBARU.SUBARU_LEGACY_PREGLOBAL), + CarTestRoute("5ab784f361e19b78|2020-06-08--16-30-41", SUBARU.SUBARU_OUTBACK_PREGLOBAL), + CarTestRoute("e19eb5d5353b1ac1|2020-08-09--14-37-56", SUBARU.SUBARU_OUTBACK_PREGLOBAL_2018), - CarTestRoute("fbbfa6af821552b9|2020-03-03--08-09-43", NISSAN.XTRAIL), - CarTestRoute("5b7c365c50084530|2020-03-25--22-10-13", NISSAN.LEAF), - CarTestRoute("22c3dcce2dd627eb|2020-12-30--16-38-48", NISSAN.LEAF_IC), - CarTestRoute("059ab9162e23198e|2020-05-30--09-41-01", NISSAN.ROGUE), - CarTestRoute("b72d3ec617c0a90f|2020-12-11--15-38-17", NISSAN.ALTIMA), + CarTestRoute("fbbfa6af821552b9|2020-03-03--08-09-43", NISSAN.NISSAN_XTRAIL), + CarTestRoute("5b7c365c50084530|2020-03-25--22-10-13", NISSAN.NISSAN_LEAF), + CarTestRoute("22c3dcce2dd627eb|2020-12-30--16-38-48", NISSAN.NISSAN_LEAF_IC), + CarTestRoute("059ab9162e23198e|2020-05-30--09-41-01", NISSAN.NISSAN_ROGUE), + CarTestRoute("b72d3ec617c0a90f|2020-12-11--15-38-17", NISSAN.NISSAN_ALTIMA), - CarTestRoute("32a319f057902bb3|2020-04-27--15-18-58", MAZDA.CX5), - CarTestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.CX9), - CarTestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA3), - CarTestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA6), - CarTestRoute("f6d5b1a9d7a1c92e|2021-07-08--06-56-59", MAZDA.CX9_2021), - CarTestRoute("a4af1602d8e668ac|2022-02-03--12-17-07", MAZDA.CX5_2022), + CarTestRoute("32a319f057902bb3|2020-04-27--15-18-58", MAZDA.MAZDA_CX5), + CarTestRoute("10b5a4b380434151|2020-08-26--17-11-45", MAZDA.MAZDA_CX9), + CarTestRoute("74f1038827005090|2020-08-26--20-05-50", MAZDA.MAZDA_3), + CarTestRoute("fb53c640f499b73d|2021-06-01--04-17-56", MAZDA.MAZDA_6), + CarTestRoute("f6d5b1a9d7a1c92e|2021-07-08--06-56-59", MAZDA.MAZDA_CX9_2021), + CarTestRoute("a4af1602d8e668ac|2022-02-03--12-17-07", MAZDA.MAZDA_CX5_2022), - CarTestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS), - CarTestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS), - CarTestRoute("66c1699b7697267d/2024-03-03--13-09-53", TESLA.MODELS_RAVEN), + CarTestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.TESLA_AP1_MODELS), + CarTestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.TESLA_AP2_MODELS), + CarTestRoute("66c1699b7697267d/2024-03-03--13-09-53", TESLA.TESLA_MODELS_RAVEN), # Segments that test specific issues - # Controls mismatch due to interceptor threshold - CarTestRoute("cfb32f0fb91b173b|2022-04-06--14-54-45", HONDA.CIVIC, segment=21), # Controls mismatch due to standstill threshold - CarTestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.CRV_HYBRID, segment=22), + CarTestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.HONDA_CRV_HYBRID, segment=22), ] diff --git a/selfdrive/car/tests/test_can_fingerprint.py b/selfdrive/car/tests/test_can_fingerprint.py index 63621b459d..8df7007339 100755 --- a/selfdrive/car/tests/test_can_fingerprint.py +++ b/selfdrive/car/tests/test_can_fingerprint.py @@ -28,7 +28,7 @@ class TestCanFingerprint(unittest.TestCase): def test_timing(self): # just pick any CAN fingerprinting car - car_model = 'CHEVROLET BOLT EUV 2022' + car_model = "CHEVROLET_BOLT_EUV" fingerprint = FINGERPRINTS[car_model][0] cases = [] diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 02a8d60e3c..72c1e27ab9 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -74,10 +74,6 @@ class TestCarInterfaces(unittest.TestCase): self.assertEqual(len(car_params.longitudinalTuning.kiV), len(car_params.longitudinalTuning.kiBP)) self.assertEqual(len(car_params.longitudinalTuning.deadzoneV), len(car_params.longitudinalTuning.deadzoneBP)) - # If we're using the interceptor for gasPressed, we should be commanding gas with it - if car_params.enableGasInterceptor: - self.assertTrue(car_params.openpilotLongitudinalControl) - # Lateral sanity checks if car_params.steerControlType != car.CarParams.SteerControlType.angle: tune = car_params.lateralTuning diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index 0ee35dd92d..143b402d5f 100755 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -6,18 +6,18 @@ import unittest from openpilot.common.basedir import BASEDIR from openpilot.selfdrive.car.car_helpers import interfaces -from openpilot.selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_info +from openpilot.selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_docs from openpilot.selfdrive.car.docs_definitions import Cable, Column, PartType, Star from openpilot.selfdrive.car.honda.values import CAR as HONDA from openpilot.selfdrive.car.values import PLATFORMS -from openpilot.selfdrive.debug.dump_car_info import dump_car_info -from openpilot.selfdrive.debug.print_docs_diff import print_car_info_diff +from openpilot.selfdrive.debug.dump_car_docs import dump_car_docs +from openpilot.selfdrive.debug.print_docs_diff import print_car_docs_diff class TestCarDocs(unittest.TestCase): @classmethod def setUpClass(cls): - cls.all_cars = get_all_car_info() + cls.all_cars = get_all_car_docs() def test_generator(self): generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE) @@ -29,24 +29,24 @@ class TestCarDocs(unittest.TestCase): def test_docs_diff(self): dump_path = os.path.join(BASEDIR, "selfdrive", "car", "tests", "cars_dump") - dump_car_info(dump_path) - print_car_info_diff(dump_path) + dump_car_docs(dump_path) + print_car_docs_diff(dump_path) os.remove(dump_path) def test_duplicate_years(self): make_model_years = defaultdict(list) for car in self.all_cars: - with self.subTest(car_info_name=car.name): + with self.subTest(car_docs_name=car.name): make_model = (car.make, car.model) for year in car.year_list: self.assertNotIn(year, make_model_years[make_model], f"{car.name}: Duplicate model year") make_model_years[make_model].append(year) - def test_missing_car_info(self): - all_car_info_platforms = [name for name, config in PLATFORMS.items()] + def test_missing_car_docs(self): + all_car_docs_platforms = [name for name, config in PLATFORMS.items()] for platform in sorted(interfaces.keys()): with self.subTest(platform=platform): - self.assertTrue(platform in all_car_info_platforms, f"Platform: {platform} doesn't have a CarInfo entry") + self.assertTrue(platform in all_car_docs_platforms, f"Platform: {platform} doesn't have a CarDocs entry") def test_naming_conventions(self): # Asserts market-standard car naming conventions by brand @@ -69,7 +69,7 @@ class TestCarDocs(unittest.TestCase): for car in self.all_cars: with self.subTest(car=car): # honda sanity check, it's the definition of a no torque star - if car.car_fingerprint in (HONDA.ACCORD, HONDA.CIVIC, HONDA.CRV, HONDA.ODYSSEY, HONDA.PILOT): + if car.car_fingerprint in (HONDA.HONDA_ACCORD, HONDA.HONDA_CIVIC, HONDA.HONDA_CRV, HONDA.HONDA_ODYSSEY, HONDA.HONDA_PILOT): self.assertEqual(car.row[Column.STEERING_TORQUE], Star.EMPTY, f"{car.name} has full torque star") elif car.car_name in ("toyota", "hyundai"): self.assertNotEqual(car.row[Column.STEERING_TORQUE], Star.EMPTY, f"{car.name} has no torque star") diff --git a/selfdrive/car/tests/test_fw_fingerprint.py b/selfdrive/car/tests/test_fw_fingerprint.py index cc5496210e..d9bea3b965 100755 --- a/selfdrive/car/tests/test_fw_fingerprint.py +++ b/selfdrive/car/tests/test_fw_fingerprint.py @@ -263,7 +263,7 @@ class TestFwFingerprintTiming(unittest.TestCase): print(f'get_vin {name} case, query time={self.total_time / self.N} seconds') def test_fw_query_timing(self): - total_ref_time = {1: 8.5, 2: 9.4} + total_ref_time = {1: 8.6, 2: 9.5} brand_ref_times = { 1: { 'gm': 1.0, @@ -274,7 +274,7 @@ class TestFwFingerprintTiming(unittest.TestCase): 'hyundai': 1.05, 'mazda': 0.1, 'nissan': 0.8, - 'subaru': 0.55, + 'subaru': 0.65, 'tesla': 0.3, 'toyota': 1.6, 'volkswagen': 0.65, diff --git a/selfdrive/car/tests/test_lateral_limits.py b/selfdrive/car/tests/test_lateral_limits.py index 083cdd5a5e..8f1cee269e 100755 --- a/selfdrive/car/tests/test_lateral_limits.py +++ b/selfdrive/car/tests/test_lateral_limits.py @@ -24,8 +24,8 @@ JERK_MEAS_T = 0.5 # TODO: put these cars within limits ABOVE_LIMITS_CARS = [ - SUBARU.LEGACY, - SUBARU.OUTBACK, + SUBARU.SUBARU_LEGACY, + SUBARU.SUBARU_OUTBACK, ] car_model_jerks: defaultdict[str, dict[str, float]] = defaultdict(dict) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 1ef8c5b676..f561fa2ad8 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -19,7 +19,7 @@ from openpilot.selfdrive.car.fingerprints import all_known_cars from openpilot.selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces from openpilot.selfdrive.car.honda.values import CAR as HONDA, HondaFlags from openpilot.selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute -from openpilot.selfdrive.car.values import PLATFORMS, Platform +from openpilot.selfdrive.car.values import Platform from openpilot.selfdrive.controls.controlsd import Controls from openpilot.selfdrive.test.helpers import read_segment_list from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT @@ -95,7 +95,7 @@ class TestCarModelBase(unittest.TestCase): if msg.carParams.openpilotLongitudinalControl: experimental_long = True if cls.platform is None and not cls.ci: - cls.platform = PLATFORMS.get(msg.carParams.carFingerprint) + cls.platform = msg.carParams.carFingerprint # Log which can frame the panda safety mode left ELM327, for CAN validity checks elif msg.which() == 'pandaStates': @@ -367,7 +367,7 @@ class TestCarModelBase(unittest.TestCase): # TODO: remove this exception once this mismatch is resolved brake_pressed = CS.brakePressed if CS.brakePressed and not self.safety.get_brake_pressed_prev(): - if self.CP.carFingerprint in (HONDA.PILOT, HONDA.RIDGELINE) and CS.brake > 0.05: + if self.CP.carFingerprint in (HONDA.HONDA_PILOT, HONDA.HONDA_RIDGELINE) and CS.brake > 0.05: brake_pressed = False self.assertEqual(brake_pressed, self.safety.get_brake_pressed_prev()) @@ -430,7 +430,7 @@ class TestCarModelBase(unittest.TestCase): # TODO: remove this exception once this mismatch is resolved brake_pressed = CS.brakePressed if CS.brakePressed and not self.safety.get_brake_pressed_prev(): - if self.CP.carFingerprint in (HONDA.PILOT, HONDA.RIDGELINE) and CS.brake > 0.05: + if self.CP.carFingerprint in (HONDA.HONDA_PILOT, HONDA.HONDA_RIDGELINE) and CS.brake > 0.05: brake_pressed = False checks['brakePressed'] += brake_pressed != self.safety.get_brake_pressed_prev() checks['regenBraking'] += CS.regenBraking != self.safety.get_regen_braking_prev() diff --git a/selfdrive/car/tests/test_platform_configs.py b/selfdrive/car/tests/test_platform_configs.py index 0b42a2b289..523c331b9e 100755 --- a/selfdrive/car/tests/test_platform_configs.py +++ b/selfdrive/car/tests/test_platform_configs.py @@ -8,14 +8,16 @@ from openpilot.selfdrive.car.values import PLATFORMS class TestPlatformConfigs(unittest.TestCase): def test_configs(self): - for platform in PLATFORMS.values(): + for name, platform in PLATFORMS.items(): with self.subTest(platform=str(platform)): self.assertTrue(platform.config._frozen) - if platform != "mock": + if platform != "MOCK": self.assertIn("pt", platform.config.dbc_dict) self.assertTrue(len(platform.config.platform_str) > 0) + self.assertEqual(name, platform.config.platform_str) + self.assertIsNotNone(platform.config.specs) diff --git a/selfdrive/car/torque_data/neural_ff_weights.json b/selfdrive/car/torque_data/neural_ff_weights.json index c526f07fa2..251b66efb0 100644 --- a/selfdrive/car/torque_data/neural_ff_weights.json +++ b/selfdrive/car/torque_data/neural_ff_weights.json @@ -1 +1 @@ -{"CHEVROLET BOLT EUV 2022": {"w_1": [[0.3452189564704895, -0.15614677965641022, -0.04062516987323761, -0.5960758328437805, 0.3211185932159424, 0.31732726097106934, -0.04430829733610153, -0.37327295541763306, -0.14118380844593048, 0.12712529301643372, 0.2641555070877075, -0.3451094627380371, -0.005127656273543835, 0.6185108423233032, 0.03725295141339302, 0.3763789236545563], [-0.0708412230014801, 0.3667356073856354, 0.031383827328681946, 0.1740853488445282, -0.04695861041545868, 0.018055908381938934, 0.009072160348296165, -0.23640218377113342, -0.10362917929887772, 0.022628149017691612, -0.224413201212883, 0.20718418061733246, -0.016947750002145767, -0.3872031271457672, -0.15500062704086304, -0.06375953555107117], [-0.0838046595454216, -0.0242826659232378, -0.07765661180019379, 0.028858814388513565, -0.09516210108995438, 0.008368706330657005, 0.1689300835132599, 0.015036891214549541, -0.15121428668498993, 0.1388195902109146, 0.11486363410949707, 0.0651545450091362, 0.13559958338737488, 0.04300367832183838, -0.13856294751167297, -0.058136988431215286], [-0.006249868310987949, 0.08809533715248108, -0.040690965950489044, 0.02359287068247795, -0.00766348373144865, 0.24816390872001648, -0.17360293865203857, -0.03676899895071983, -0.17564819753170013, 0.18998438119888306, -0.050583917647600174, -0.006488069426268339, 0.10649101436138153, -0.024557121098041534, -0.103276826441288, 0.18448011577129364]], "b_1": [0.2935388386249542, 0.10967712104320526, -0.014007942751049995, 0.211833655834198, 0.33605605363845825, 0.37722209095954895, -0.16615016758441925, 0.3134673535823822, 0.06695777177810669, 0.3425212800502777, 0.3769673705101013, 0.23186539113521576, 0.5770409107208252, -0.05929069593548775, 0.01839117519557476, 0.03828774020075798], "w_2": [[-0.06261160969734192, 0.010185074992477894, -0.06083013117313385, -0.04531499370932579, -0.08979734033346176, 0.3432150185108185, -0.019801849499344826, 0.3010321259498596], [0.19698476791381836, -0.009238275699317455, 0.08842222392559052, -0.09516377002000809, -0.05022778362035751, 0.13626104593276978, -0.052890390157699585, 0.15569131076335907], [0.0724768117070198, -0.09018408507108688, 0.06850195676088333, -0.025572121143341064, 0.0680626779794693, -0.07648195326328278, 0.07993496209383011, -0.059752143919467926], [1.267876386642456, -0.05755887180566788, -0.08429178595542908, 0.021366603672504425, -0.0006479775765910745, -1.4292563199996948, -0.08077696710824966, -1.414825439453125], [0.04535430669784546, 0.06555880606174469, -0.027145234867930412, -0.07661093026399612, -0.05702832341194153, 0.23650476336479187, 0.0024587824009358883, 0.20126521587371826], [0.006042032968252897, 0.042880818247795105, 0.002187949838116765, -0.017126334831118584, -0.08352015167474747, 0.19801731407642365, -0.029196614399552345, 0.23713473975658417], [-0.01644900068640709, -0.04358499124646187, 0.014584392309188843, 0.07155826687812805, -0.09354910999536514, -0.033351872116327286, 0.07138452678918839, -0.04755295440554619], [-1.1012420654296875, -0.03534531593322754, 0.02167935110628605, -0.01116552110761404, -0.08436500281095505, 1.1038788557052612, 0.027903547510504723, 1.0676132440567017], [0.03843916580080986, -0.0952216386795044, 0.039226632565259933, 0.002778085647150874, -0.020275786519050598, -0.07848760485649109, 0.04803166165947914, 0.015538203530013561], [0.018385495990514755, -0.025189843028783798, 0.0036680365446954966, -0.02105865254998207, 0.04808586835861206, 0.1575016975402832, 0.02703506126999855, 0.23039312660694122], [-0.0033881019335240126, -0.10210853815078735, -0.04877309128642082, 0.006989633198827505, 0.046798162162303925, 0.38676899671554565, -0.032304272055625916, 0.2345031052827835], [0.22092825174331665, -0.09642873704433441, 0.04499409720301628, 0.05108088254928589, -0.10191166400909424, 0.12818090617656708, -0.021021494641900063, 0.09440375864505768], [0.1212429478764534, -0.028194155544042587, -0.0981956496834755, 0.08226924389600754, 0.055346839129924774, 0.27067816257476807, -0.09064067900180817, 0.12580905854701996], [-1.6740131378173828, -0.02066155895590782, -0.05924689769744873, 0.06347910314798355, -0.07821853458881378, 1.2807466983795166, 0.04589352011680603, 1.310766577720642], [-0.09893272817134857, -0.04093599319458008, -0.02502273954451084, 0.09490344673395157, -0.0211324505507946, -0.09021010994911194, 0.07936318963766098, -0.03593116253614426], [-0.08490308374166489, -0.015558987855911255, -0.048692114651203156, -0.007421435788273811, -0.040531404316425323, 0.25889304280281067, 0.06012800335884094, 0.27946868538856506]], "b_2": [0.07973937690258026, -0.010446485131978989, -0.003066520905122161, -0.031895797699689865, 0.006032303906977177, 0.24106740951538086, -0.008969511836767197, 0.2872662842273712], "w_3": [[-1.364486813545227, -0.11682678014039993, 0.01764785870909691, 0.03926877677440643], [-0.05695437639951706, 0.05472218990325928, 0.1266128271818161, 0.09950875490903854], [0.11415273696184158, -0.10069356113672256, 0.0864749327301979, -0.043946366757154465], [-0.10138195008039474, -0.040128443390131, -0.08937158435583115, -0.0048376512713730335], [-0.0028251828625798225, -0.04743027314543724, 0.06340016424655914, 0.07277824729681015], [0.49482327699661255, -0.06410001963376999, -0.0999293103814125, -0.14250673353672028], [0.042802367359399796, 0.0015462725423276424, -0.05991362780332565, 0.1022040992975235], [0.3523194193840027, 0.07343732565641403, 0.04157765582203865, -0.12358107417821884]], "b_3": [0.2653026282787323, -0.058485131710767746, -0.0744510293006897, 0.012550175189971924], "w_4": [[0.5988775491714478, 0.09668736904859543], [-0.04360569268465042, 0.06491032242774963], [-0.11868984252214432, -0.09601487964391708], [-0.06554870307445526, -0.14189276099205017]], "b_4": [-0.08148707449436188, -2.8251802921295166], "input_norm_mat": [[-3.0, 3.0], [-3.0, 3.0], [0.0, 40.0], [-3.0, 3.0]], "output_norm_mat": [-1.0, 1.0], "temperature": 100.0}} \ No newline at end of file +{"CHEVROLET_BOLT_EUV": {"w_1": [[0.3452189564704895, -0.15614677965641022, -0.04062516987323761, -0.5960758328437805, 0.3211185932159424, 0.31732726097106934, -0.04430829733610153, -0.37327295541763306, -0.14118380844593048, 0.12712529301643372, 0.2641555070877075, -0.3451094627380371, -0.005127656273543835, 0.6185108423233032, 0.03725295141339302, 0.3763789236545563], [-0.0708412230014801, 0.3667356073856354, 0.031383827328681946, 0.1740853488445282, -0.04695861041545868, 0.018055908381938934, 0.009072160348296165, -0.23640218377113342, -0.10362917929887772, 0.022628149017691612, -0.224413201212883, 0.20718418061733246, -0.016947750002145767, -0.3872031271457672, -0.15500062704086304, -0.06375953555107117], [-0.0838046595454216, -0.0242826659232378, -0.07765661180019379, 0.028858814388513565, -0.09516210108995438, 0.008368706330657005, 0.1689300835132599, 0.015036891214549541, -0.15121428668498993, 0.1388195902109146, 0.11486363410949707, 0.0651545450091362, 0.13559958338737488, 0.04300367832183838, -0.13856294751167297, -0.058136988431215286], [-0.006249868310987949, 0.08809533715248108, -0.040690965950489044, 0.02359287068247795, -0.00766348373144865, 0.24816390872001648, -0.17360293865203857, -0.03676899895071983, -0.17564819753170013, 0.18998438119888306, -0.050583917647600174, -0.006488069426268339, 0.10649101436138153, -0.024557121098041534, -0.103276826441288, 0.18448011577129364]], "b_1": [0.2935388386249542, 0.10967712104320526, -0.014007942751049995, 0.211833655834198, 0.33605605363845825, 0.37722209095954895, -0.16615016758441925, 0.3134673535823822, 0.06695777177810669, 0.3425212800502777, 0.3769673705101013, 0.23186539113521576, 0.5770409107208252, -0.05929069593548775, 0.01839117519557476, 0.03828774020075798], "w_2": [[-0.06261160969734192, 0.010185074992477894, -0.06083013117313385, -0.04531499370932579, -0.08979734033346176, 0.3432150185108185, -0.019801849499344826, 0.3010321259498596], [0.19698476791381836, -0.009238275699317455, 0.08842222392559052, -0.09516377002000809, -0.05022778362035751, 0.13626104593276978, -0.052890390157699585, 0.15569131076335907], [0.0724768117070198, -0.09018408507108688, 0.06850195676088333, -0.025572121143341064, 0.0680626779794693, -0.07648195326328278, 0.07993496209383011, -0.059752143919467926], [1.267876386642456, -0.05755887180566788, -0.08429178595542908, 0.021366603672504425, -0.0006479775765910745, -1.4292563199996948, -0.08077696710824966, -1.414825439453125], [0.04535430669784546, 0.06555880606174469, -0.027145234867930412, -0.07661093026399612, -0.05702832341194153, 0.23650476336479187, 0.0024587824009358883, 0.20126521587371826], [0.006042032968252897, 0.042880818247795105, 0.002187949838116765, -0.017126334831118584, -0.08352015167474747, 0.19801731407642365, -0.029196614399552345, 0.23713473975658417], [-0.01644900068640709, -0.04358499124646187, 0.014584392309188843, 0.07155826687812805, -0.09354910999536514, -0.033351872116327286, 0.07138452678918839, -0.04755295440554619], [-1.1012420654296875, -0.03534531593322754, 0.02167935110628605, -0.01116552110761404, -0.08436500281095505, 1.1038788557052612, 0.027903547510504723, 1.0676132440567017], [0.03843916580080986, -0.0952216386795044, 0.039226632565259933, 0.002778085647150874, -0.020275786519050598, -0.07848760485649109, 0.04803166165947914, 0.015538203530013561], [0.018385495990514755, -0.025189843028783798, 0.0036680365446954966, -0.02105865254998207, 0.04808586835861206, 0.1575016975402832, 0.02703506126999855, 0.23039312660694122], [-0.0033881019335240126, -0.10210853815078735, -0.04877309128642082, 0.006989633198827505, 0.046798162162303925, 0.38676899671554565, -0.032304272055625916, 0.2345031052827835], [0.22092825174331665, -0.09642873704433441, 0.04499409720301628, 0.05108088254928589, -0.10191166400909424, 0.12818090617656708, -0.021021494641900063, 0.09440375864505768], [0.1212429478764534, -0.028194155544042587, -0.0981956496834755, 0.08226924389600754, 0.055346839129924774, 0.27067816257476807, -0.09064067900180817, 0.12580905854701996], [-1.6740131378173828, -0.02066155895590782, -0.05924689769744873, 0.06347910314798355, -0.07821853458881378, 1.2807466983795166, 0.04589352011680603, 1.310766577720642], [-0.09893272817134857, -0.04093599319458008, -0.02502273954451084, 0.09490344673395157, -0.0211324505507946, -0.09021010994911194, 0.07936318963766098, -0.03593116253614426], [-0.08490308374166489, -0.015558987855911255, -0.048692114651203156, -0.007421435788273811, -0.040531404316425323, 0.25889304280281067, 0.06012800335884094, 0.27946868538856506]], "b_2": [0.07973937690258026, -0.010446485131978989, -0.003066520905122161, -0.031895797699689865, 0.006032303906977177, 0.24106740951538086, -0.008969511836767197, 0.2872662842273712], "w_3": [[-1.364486813545227, -0.11682678014039993, 0.01764785870909691, 0.03926877677440643], [-0.05695437639951706, 0.05472218990325928, 0.1266128271818161, 0.09950875490903854], [0.11415273696184158, -0.10069356113672256, 0.0864749327301979, -0.043946366757154465], [-0.10138195008039474, -0.040128443390131, -0.08937158435583115, -0.0048376512713730335], [-0.0028251828625798225, -0.04743027314543724, 0.06340016424655914, 0.07277824729681015], [0.49482327699661255, -0.06410001963376999, -0.0999293103814125, -0.14250673353672028], [0.042802367359399796, 0.0015462725423276424, -0.05991362780332565, 0.1022040992975235], [0.3523194193840027, 0.07343732565641403, 0.04157765582203865, -0.12358107417821884]], "b_3": [0.2653026282787323, -0.058485131710767746, -0.0744510293006897, 0.012550175189971924], "w_4": [[0.5988775491714478, 0.09668736904859543], [-0.04360569268465042, 0.06491032242774963], [-0.11868984252214432, -0.09601487964391708], [-0.06554870307445526, -0.14189276099205017]], "b_4": [-0.08148707449436188, -2.8251802921295166], "input_norm_mat": [[-3.0, 3.0], [-3.0, 3.0], [0.0, 40.0], [-3.0, 3.0]], "output_norm_mat": [-1.0, 1.0], "temperature": 100.0}} \ No newline at end of file diff --git a/selfdrive/car/torque_data/override.toml b/selfdrive/car/torque_data/override.toml index 3de33b88db..4d9646a54a 100644 --- a/selfdrive/car/torque_data/override.toml +++ b/selfdrive/car/torque_data/override.toml @@ -1,76 +1,76 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] ### angle control # Nissan appears to have torque -"NISSAN X-TRAIL 2017" = [nan, 1.5, nan] -"NISSAN ALTIMA 2020" = [nan, 1.5, nan] -"NISSAN LEAF 2018 Instrument Cluster" = [nan, 1.5, nan] -"NISSAN LEAF 2018" = [nan, 1.5, nan] -"NISSAN ROGUE 2019" = [nan, 1.5, nan] +"NISSAN_XTRAIL" = [nan, 1.5, nan] +"NISSAN_ALTIMA" = [nan, 1.5, nan] +"NISSAN_LEAF_IC" = [nan, 1.5, nan] +"NISSAN_LEAF" = [nan, 1.5, nan] +"NISSAN_ROGUE" = [nan, 1.5, nan] # New subarus angle based controllers -"SUBARU FORESTER 2022" = [nan, 3.0, nan] -"SUBARU OUTBACK 7TH GEN" = [nan, 3.0, nan] -"SUBARU ASCENT 2023" = [nan, 3.0, nan] +"SUBARU_FORESTER_2022" = [nan, 3.0, nan] +"SUBARU_OUTBACK_2023" = [nan, 3.0, nan] +"SUBARU_ASCENT_2023" = [nan, 3.0, nan] # Toyota LTA also has torque -"TOYOTA RAV4 2023" = [nan, 3.0, nan] +"TOYOTA_RAV4_TSS2_2023" = [nan, 3.0, nan] # Tesla has high torque -"TESLA AP1 MODEL S" = [nan, 2.5, nan] -"TESLA AP2 MODEL S" = [nan, 2.5, nan] -"TESLA MODEL S RAVEN" = [nan, 2.5, nan] +"TESLA_AP1_MODELS" = [nan, 2.5, nan] +"TESLA_AP2_MODELS" = [nan, 2.5, nan] +"TESLA_MODELS_RAVEN" = [nan, 2.5, nan] # Guess -"FORD BRONCO SPORT 1ST GEN" = [nan, 1.5, nan] -"FORD ESCAPE 4TH GEN" = [nan, 1.5, nan] -"FORD EXPLORER 6TH GEN" = [nan, 1.5, nan] -"FORD F-150 14TH GEN" = [nan, 1.5, nan] -"FORD FOCUS 4TH GEN" = [nan, 1.5, nan] -"FORD MAVERICK 1ST GEN" = [nan, 1.5, nan] -"FORD F-150 LIGHTNING 1ST GEN" = [nan, 1.5, nan] -"FORD MUSTANG MACH-E 1ST GEN" = [nan, 1.5, nan] +"FORD_BRONCO_SPORT_MK1" = [nan, 1.5, nan] +"FORD_ESCAPE_MK4" = [nan, 1.5, nan] +"FORD_EXPLORER_MK6" = [nan, 1.5, nan] +"FORD_F_150_MK14" = [nan, 1.5, nan] +"FORD_FOCUS_MK4" = [nan, 1.5, nan] +"FORD_MAVERICK_MK1" = [nan, 1.5, nan] +"FORD_F_150_LIGHTNING_MK1" = [nan, 1.5, nan] +"FORD_MUSTANG_MACH_E_MK1" = [nan, 1.5, nan] ### # No steering wheel -"COMMA BODY" = [nan, 1000, nan] +"COMMA_BODY" = [nan, 1000, nan] # Totally new cars -"RAM 1500 5TH GEN" = [2.0, 2.0, 0.05] -"RAM HD 5TH GEN" = [1.4, 1.4, 0.05] -"SUBARU OUTBACK 6TH GEN" = [2.0, 2.0, 0.2] -"CADILLAC ESCALADE 2017" = [1.899999976158142, 1.842270016670227, 0.1120000034570694] -"CADILLAC ESCALADE ESV 2019" = [1.15, 1.3, 0.2] -"CHEVROLET BOLT EUV 2022" = [2.0, 2.0, 0.05] -"CHEVROLET SILVERADO 1500 2020" = [1.9, 1.9, 0.112] -"CHEVROLET TRAILBLAZER 2021" = [1.33, 1.9, 0.16] -"CHEVROLET EQUINOX 2019" = [2.5, 2.5, 0.05] -"VOLKSWAGEN CADDY 3RD GEN" = [1.2, 1.2, 0.1] -"VOLKSWAGEN PASSAT NMS" = [2.5, 2.5, 0.1] -"VOLKSWAGEN SHARAN 2ND GEN" = [2.5, 2.5, 0.1] -"HYUNDAI SANTA CRUZ 1ST GEN" = [2.7, 2.7, 0.1] -"KIA SPORTAGE 5TH GEN" = [2.6, 2.6, 0.1] -"GENESIS GV70 1ST GEN" = [2.42, 2.42, 0.1] -"GENESIS GV60 ELECTRIC 1ST GEN" = [2.5, 2.5, 0.1] -"KIA SORENTO 4TH GEN" = [2.5, 2.5, 0.1] -"KIA SORENTO HYBRID 4TH GEN" = [2.5, 2.5, 0.1] -"KIA NIRO HYBRID 2ND GEN" = [2.42, 2.5, 0.12] -"KIA NIRO EV 2ND GEN" = [2.05, 2.5, 0.14] -"GENESIS GV80 2023" = [2.5, 2.5, 0.1] -"KIA CARNIVAL 4TH GEN" = [1.75, 1.75, 0.15] -"GMC ACADIA DENALI 2018" = [1.6, 1.6, 0.2] -"LEXUS IS 2023" = [2.0, 2.0, 0.1] -"HYUNDAI KONA ELECTRIC 2ND GEN" = [2.5, 2.5, 0.1] -"HYUNDAI IONIQ 6 2023" = [2.5, 2.5, 0.1] -"HYUNDAI AZERA 6TH GEN" = [1.8, 1.8, 0.1] -"HYUNDAI AZERA HYBRID 6TH GEN" = [1.8, 1.8, 0.1] -"KIA K8 HYBRID 1ST GEN" = [2.5, 2.5, 0.1] -"HYUNDAI CUSTIN 1ST GEN" = [2.5, 2.5, 0.1] -"LEXUS GS F 2016" = [2.5, 2.5, 0.08] -"HYUNDAI STARIA 4TH GEN" = [1.8, 2.0, 0.15] +"RAM_1500_5TH_GEN" = [2.0, 2.0, 0.05] +"RAM_HD_5TH_GEN" = [1.4, 1.4, 0.05] +"SUBARU_OUTBACK" = [2.0, 2.0, 0.2] +"CADILLAC_ESCALADE" = [1.899999976158142, 1.842270016670227, 0.1120000034570694] +"CADILLAC_ESCALADE_ESV_2019" = [1.15, 1.3, 0.2] +"CHEVROLET_BOLT_EUV" = [2.0, 2.0, 0.05] +"CHEVROLET_SILVERADO" = [1.9, 1.9, 0.112] +"CHEVROLET_TRAILBLAZER" = [1.33, 1.9, 0.16] +"CHEVROLET_EQUINOX" = [2.5, 2.5, 0.05] +"VOLKSWAGEN_CADDY_MK3" = [1.2, 1.2, 0.1] +"VOLKSWAGEN_PASSAT_NMS" = [2.5, 2.5, 0.1] +"VOLKSWAGEN_SHARAN_MK2" = [2.5, 2.5, 0.1] +"HYUNDAI_SANTA_CRUZ_1ST_GEN" = [2.7, 2.7, 0.1] +"KIA_SPORTAGE_5TH_GEN" = [2.6, 2.6, 0.1] +"GENESIS_GV70_1ST_GEN" = [2.42, 2.42, 0.1] +"GENESIS_GV60_EV_1ST_GEN" = [2.5, 2.5, 0.1] +"KIA_SORENTO_4TH_GEN" = [2.5, 2.5, 0.1] +"KIA_SORENTO_HEV_4TH_GEN" = [2.5, 2.5, 0.1] +"KIA_NIRO_HEV_2ND_GEN" = [2.42, 2.5, 0.12] +"KIA_NIRO_EV_2ND_GEN" = [2.05, 2.5, 0.14] +"GENESIS_GV80" = [2.5, 2.5, 0.1] +"KIA_CARNIVAL_4TH_GEN" = [1.75, 1.75, 0.15] +"GMC_ACADIA" = [1.6, 1.6, 0.2] +"LEXUS_IS_TSS2" = [2.0, 2.0, 0.1] +"HYUNDAI_KONA_EV_2ND_GEN" = [2.5, 2.5, 0.1] +"HYUNDAI_IONIQ_6" = [2.5, 2.5, 0.1] +"HYUNDAI_AZERA_6TH_GEN" = [1.8, 1.8, 0.1] +"HYUNDAI_AZERA_HEV_6TH_GEN" = [1.8, 1.8, 0.1] +"KIA_K8_HEV_1ST_GEN" = [2.5, 2.5, 0.1] +"HYUNDAI_CUSTIN_1ST_GEN" = [2.5, 2.5, 0.1] +"LEXUS_GS_F" = [2.5, 2.5, 0.08] +"HYUNDAI_STARIA_4TH_GEN" = [1.8, 2.0, 0.15] # Dashcam or fallback configured as ideal car -"mock" = [10.0, 10, 0.0] +"MOCK" = [10.0, 10, 0.0] # Manually checked -"HONDA CIVIC 2022" = [2.5, 1.2, 0.15] -"HONDA HR-V 2023" = [2.5, 1.2, 0.2] +"HONDA_CIVIC_2022" = [2.5, 1.2, 0.15] +"HONDA_HRV_3G" = [2.5, 1.2, 0.2] diff --git a/selfdrive/car/torque_data/params.toml b/selfdrive/car/torque_data/params.toml index 142332b220..f91bc3abab 100644 --- a/selfdrive/car/torque_data/params.toml +++ b/selfdrive/car/torque_data/params.toml @@ -1,85 +1,82 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] -"ACURA ILX 2016" = [1.524988973896102, 0.519011053086259, 0.34236219253028] -"ACURA RDX 2018" = [0.9987728568686902, 0.5323765166196301, 0.303218805715844] -"ACURA RDX 2020" = [1.4314459806646749, 0.33874701282109954, 0.18048847083897598] -"AUDI A3 3RD GEN" = [1.5122414863077502, 1.7443517531719404, 0.15194151892450905] -"AUDI Q3 2ND GEN" = [1.4439223359448605, 1.2254955789112076, 0.1413798895978097] -"CHEVROLET VOLT PREMIER 2017" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158] -"CHRYSLER PACIFICA 2018" = [2.07140, 1.3366521181047952, 0.13776367250652022] -"CHRYSLER PACIFICA 2020" = [1.86206, 1.509076559398423, 0.14328246159386085] -"CHRYSLER PACIFICA HYBRID 2017" = [1.79422, 1.06831764583744, 0.116237] -"CHRYSLER PACIFICA HYBRID 2018" = [2.08887, 1.2943025830995154, 0.114818] -"CHRYSLER PACIFICA HYBRID 2019" = [1.90120, 1.1958788168371808, 0.131520] -"GENESIS G70 2018" = [3.8520195946707947, 2.354697063349854, 0.06830285485626221] -"HONDA ACCORD 2018" = [1.6893333799149202, 0.3246749081720698, 0.2120497022936265] -"HONDA CIVIC (BOSCH) 2019" = [1.691708637466905, 0.40132900729454185, 0.25460295304024094] -"HONDA CIVIC 2016" = [1.6528895627785531, 0.4018518740819229, 0.25458812851328544] -"HONDA CR-V 2016" = [0.7667141440182675, 0.5927571534745969, 0.40909087636157127] -"HONDA CR-V 2017" = [2.01323205142022, 0.2700612209345081, 0.2238412881331528] -"HONDA CR-V HYBRID 2019" = [2.072034634644233, 0.7152085160516978, 0.20237105008376083] -"HONDA FIT 2018" = [1.5719981427109775, 0.5712761407108976, 0.110773383324281] -"HONDA HRV 2019" = [2.0661212805710205, 0.7521343418694775, 0.17760375789242094] -"HONDA INSIGHT 2019" = [1.5201671214069354, 0.5660229120683284, 0.25808042580281876] -"HONDA ODYSSEY 2018" = [1.8774809275211801, 0.8394431662987996, 0.2096978613792822] -"HONDA PILOT 2017" = [1.7262026201812795, 0.9470005614967523, 0.21351430733218763] -"HONDA RIDGELINE 2017" = [1.4146525028237624, 0.7356572861629564, 0.23307177552211328] -"HYUNDAI ELANTRA 2021" = [3.169, 2.1259108157250735, 0.0819] -"HYUNDAI GENESIS 2015-2016" = [2.7807965280270794, 2.325, 0.0984484465421171] -"HYUNDAI IONIQ 5 2022" = [3.172929, 2.713050, 0.096019] -"HYUNDAI IONIQ ELECTRIC LIMITED 2019" = [1.7662975472852054, 1.613755614526594, 0.17087579756306276] -"HYUNDAI IONIQ PHEV 2020" = [3.2928700076638537, 2.1193482926455656, 0.12463700961468778] -"HYUNDAI IONIQ PLUG-IN HYBRID 2019" = [2.970807902012267, 1.6312321830002083, 0.1088964990357482] -"HYUNDAI KONA ELECTRIC 2019" = [3.078814714619148, 2.307336938253934, 0.12359762054065548] -"HYUNDAI PALISADE 2020" = [2.544642494803999, 1.8721703683337008, 0.1301424599248651] -"HYUNDAI SANTA FE 2019" = [3.0787027729757632, 2.6173437483495565, 0.1207019341823945] -"HYUNDAI SANTA FE HYBRID 2022" = [3.501877602644835, 2.729064118456137, 0.10384068104538963] -"HYUNDAI SANTA FE PlUG-IN HYBRID 2022" = [1.6953050513611045, 1.5837614296206861, 0.12672855941458458] -"HYUNDAI SONATA 2019" = [2.2200457811703953, 1.2967330275895228, 0.14039920986586393] -"HYUNDAI SONATA 2020" = [2.9638737459977467, 2.1259108157250735, 0.07813665616927593] -"HYUNDAI SONATA HYBRID 2021" = [2.8990264092395734, 2.061410192222139, 0.0899805488717382] -"HYUNDAI TUCSON 4TH GEN" = [2.960174, 2.860284, 0.108745] -"JEEP GRAND CHEROKEE 2019" = [2.30972, 1.289689569171081, 0.117048] -"JEEP GRAND CHEROKEE V6 2018" = [2.27116, 1.4057367824262523, 0.11725947414922003] -"KIA EV6 2022" = [3.2, 2.093457, 0.05] -"KIA K5 2021" = [2.405339728085138, 1.460032270828705, 0.11650989850813716] -"KIA NIRO EV 2020" = [2.9215954981365337, 2.1500583840260044, 0.09236802474810267] -"KIA SORENTO GT LINE 2018" = [2.464854685101844, 1.5335274218367956, 0.12056170567599558] -"KIA STINGER GT2 2018" = [2.7499043387418967, 1.849652021986449, 0.12048334239559202] -"LEXUS ES 2019" = [2.0357564999999997, 1.999082295195227, 0.101533] -"LEXUS NX 2018" = [2.3525924753753613, 1.9731412277641067, 0.15168101064205927] -"LEXUS NX 2020" = [2.4331999786982936, 2.1045680431705414, 0.14099899317761067] -"LEXUS RX 2016" = [1.6430539050086406, 1.181960058934143, 0.19768806040843034] -"LEXUS RX 2020" = [1.5375561442049257, 1.343166476215164, 0.1931062001527557] -"MAZDA CX-9 2021" = [1.7601682915983443, 1.0889677335154337, 0.17713792194297195] -"SKODA SUPERB 3RD GEN" = [1.166437404652981, 1.1686163012668165, 0.12194533036948708] -"SUBARU FORESTER 2019" = [3.6617001649776793, 2.342197172531713, 0.11075960785398745] -"SUBARU IMPREZA LIMITED 2019" = [1.0670704910352047, 0.8234374840709592, 0.20986563268614938] -"SUBARU IMPREZA SPORT 2020" = [2.6068223389108303, 2.134872342760203, 0.15261513193561627] -"TOYOTA AVALON 2016" = [2.5185770183845646, 1.7153346784214922, 0.10603968787111022] -"TOYOTA AVALON 2019" = [1.7036141952825095, 1.239619084240008, 0.08459830394899492] -"TOYOTA AVALON 2022" = [2.3154403649717357, 2.7777922854327124, 0.11453999639164605] -"TOYOTA C-HR 2018" = [1.5591084333664578, 1.271271459066948, 0.20259087058453193] -"TOYOTA C-HR 2021" = [1.7678810166088303, 1.3742176337919942, 0.2319674583741509] -"TOYOTA CAMRY 2018" = [2.0568162685952505, 1.7576185169559122, 0.108878753] -"TOYOTA CAMRY 2021" = [2.3548324999999997, 2.368900128946771, 0.118436] -"TOYOTA COROLLA 2017" = [3.117154369115421, 1.8438132575043773, 0.12289685869250652] -"TOYOTA COROLLA TSS2 2019" = [1.991132339206426, 1.868866242720403, 0.19570063298031432] -"TOYOTA HIGHLANDER 2017" = [1.8108348718624456, 1.6348421600679828, 0.15972686105120398] -"TOYOTA HIGHLANDER 2020" = [1.9617570834136164, 1.8611643317268927, 0.14519673256119725] -"TOYOTA MIRAI 2021" = [2.506899832157829, 1.7417213930750164, 0.20182618449440565] -"TOYOTA PRIUS 2017" = [1.60, 1.5023147650693636, 0.151515] -"TOYOTA PRIUS TSS2 2021" = [1.972600, 1.9104337425537743, 0.170968] -"TOYOTA RAV4 2017" = [2.085695074355425, 2.2142832316984733, 0.13339165270103975] -"TOYOTA RAV4 2019" = [2.279239424615458, 2.087101966779332, 0.13682208413446817] -"TOYOTA RAV4 2019 8965" = [2.3080951748210854, 2.1189367835820603, 0.12942102328134028] -"TOYOTA RAV4 2019 x02" = [2.762293266024922, 2.243615865975329, 0.11113568178327986] -"TOYOTA RAV4 HYBRID 2017" = [1.9796257271652042, 1.7503987331707576, 0.14628860048885406] -"TOYOTA RAV4 2022" = [2.241883248393209, 1.9304407208090029, 0.112174] -"TOYOTA RAV4 2022 x02" = [3.044930631831037, 2.3979189796380918, 0.14023209146703736] -"TOYOTA SIENNA 2018" = [1.689726, 1.3208264576110418, 0.140456] -"VOLKSWAGEN ARTEON 1ST GEN" = [1.45136518053819, 1.3639364049316804, 0.23806361745695032] -"VOLKSWAGEN ATLAS 1ST GEN" = [1.4677006726964945, 1.6733266634075656, 0.12959584092073367] -"VOLKSWAGEN GOLF 7TH GEN" = [1.3750394140491293, 1.5814743077200641, 0.2018321939386586] -"VOLKSWAGEN JETTA 7TH GEN" = [1.2271623034089392, 1.216955117387, 0.19437384688370712] -"VOLKSWAGEN PASSAT 8TH GEN" = [1.3432120736752917, 1.7087275587362314, 0.19444383787326647] -"VOLKSWAGEN TIGUAN 2ND GEN" = [0.9711965500094828, 1.0001565939459098, 0.1465626137072916] +"ACURA_ILX" = [1.524988973896102, 0.519011053086259, 0.34236219253028] +"ACURA_RDX" = [0.9987728568686902, 0.5323765166196301, 0.303218805715844] +"ACURA_RDX_3G" = [1.4314459806646749, 0.33874701282109954, 0.18048847083897598] +"AUDI_A3_MK3" = [1.5122414863077502, 1.7443517531719404, 0.15194151892450905] +"AUDI_Q3_MK2" = [1.4439223359448605, 1.2254955789112076, 0.1413798895978097] +"CHEVROLET_VOLT" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158] +"CHRYSLER_PACIFICA_2018" = [2.07140, 1.3366521181047952, 0.13776367250652022] +"CHRYSLER_PACIFICA_2020" = [1.86206, 1.509076559398423, 0.14328246159386085] +"CHRYSLER_PACIFICA_2017_HYBRID" = [1.79422, 1.06831764583744, 0.116237] +"CHRYSLER_PACIFICA_2018_HYBRID" = [2.08887, 1.2943025830995154, 0.114818] +"CHRYSLER_PACIFICA_2019_HYBRID" = [1.90120, 1.1958788168371808, 0.131520] +"GENESIS_G70" = [3.8520195946707947, 2.354697063349854, 0.06830285485626221] +"HONDA_ACCORD" = [1.6893333799149202, 0.3246749081720698, 0.2120497022936265] +"HONDA_CIVIC_BOSCH" = [1.691708637466905, 0.40132900729454185, 0.25460295304024094] +"HONDA_CIVIC" = [1.6528895627785531, 0.4018518740819229, 0.25458812851328544] +"HONDA_CRV" = [0.7667141440182675, 0.5927571534745969, 0.40909087636157127] +"HONDA_CRV_5G" = [2.01323205142022, 0.2700612209345081, 0.2238412881331528] +"HONDA_CRV_HYBRID" = [2.072034634644233, 0.7152085160516978, 0.20237105008376083] +"HONDA_FIT" = [1.5719981427109775, 0.5712761407108976, 0.110773383324281] +"HONDA_HRV" = [2.0661212805710205, 0.7521343418694775, 0.17760375789242094] +"HONDA_INSIGHT" = [1.5201671214069354, 0.5660229120683284, 0.25808042580281876] +"HONDA_ODYSSEY" = [1.8774809275211801, 0.8394431662987996, 0.2096978613792822] +"HONDA_PILOT" = [1.7262026201812795, 0.9470005614967523, 0.21351430733218763] +"HONDA_RIDGELINE" = [1.4146525028237624, 0.7356572861629564, 0.23307177552211328] +"HYUNDAI_ELANTRA_2021" = [3.169, 2.1259108157250735, 0.0819] +"HYUNDAI_GENESIS" = [2.7807965280270794, 2.325, 0.0984484465421171] +"HYUNDAI_IONIQ_5" = [3.172929, 2.713050, 0.096019] +"HYUNDAI_IONIQ_EV_LTD" = [1.7662975472852054, 1.613755614526594, 0.17087579756306276] +"HYUNDAI_IONIQ_PHEV" = [3.2928700076638537, 2.1193482926455656, 0.12463700961468778] +"HYUNDAI_IONIQ_PHEV_2019" = [2.970807902012267, 1.6312321830002083, 0.1088964990357482] +"HYUNDAI_KONA_EV" = [3.078814714619148, 2.307336938253934, 0.12359762054065548] +"HYUNDAI_PALISADE" = [2.544642494803999, 1.8721703683337008, 0.1301424599248651] +"HYUNDAI_SANTA_FE" = [3.0787027729757632, 2.6173437483495565, 0.1207019341823945] +"HYUNDAI_SANTA_FE_HEV_2022" = [3.501877602644835, 2.729064118456137, 0.10384068104538963] +"HYUNDAI_SANTA_FE_PHEV_2022" = [1.6953050513611045, 1.5837614296206861, 0.12672855941458458] +"HYUNDAI_SONATA_LF" = [2.2200457811703953, 1.2967330275895228, 0.14039920986586393] +"HYUNDAI_SONATA" = [2.9638737459977467, 2.1259108157250735, 0.07813665616927593] +"HYUNDAI_SONATA_HYBRID" = [2.8990264092395734, 2.061410192222139, 0.0899805488717382] +"HYUNDAI_TUCSON_4TH_GEN" = [2.960174, 2.860284, 0.108745] +"JEEP_GRAND_CHEROKEE_2019" = [2.30972, 1.289689569171081, 0.117048] +"JEEP_GRAND_CHEROKEE" = [2.27116, 1.4057367824262523, 0.11725947414922003] +"KIA_EV6" = [3.2, 2.093457, 0.05] +"KIA_K5_2021" = [2.405339728085138, 1.460032270828705, 0.11650989850813716] +"KIA_NIRO_EV" = [2.9215954981365337, 2.1500583840260044, 0.09236802474810267] +"KIA_SORENTO" = [2.464854685101844, 1.5335274218367956, 0.12056170567599558] +"KIA_STINGER" = [2.7499043387418967, 1.849652021986449, 0.12048334239559202] +"LEXUS_ES_TSS2" = [2.0357564999999997, 1.999082295195227, 0.101533] +"LEXUS_NX" = [2.3525924753753613, 1.9731412277641067, 0.15168101064205927] +"LEXUS_NX_TSS2" = [2.4331999786982936, 2.1045680431705414, 0.14099899317761067] +"LEXUS_RX" = [1.6430539050086406, 1.181960058934143, 0.19768806040843034] +"LEXUS_RX_TSS2" = [1.5375561442049257, 1.343166476215164, 0.1931062001527557] +"MAZDA_CX9_2021" = [1.7601682915983443, 1.0889677335154337, 0.17713792194297195] +"SKODA_SUPERB_MK3" = [1.166437404652981, 1.1686163012668165, 0.12194533036948708] +"SUBARU_FORESTER" = [3.6617001649776793, 2.342197172531713, 0.11075960785398745] +"SUBARU_IMPREZA" = [1.0670704910352047, 0.8234374840709592, 0.20986563268614938] +"SUBARU_IMPREZA_2020" = [2.6068223389108303, 2.134872342760203, 0.15261513193561627] +"TOYOTA_AVALON" = [2.5185770183845646, 1.7153346784214922, 0.10603968787111022] +"TOYOTA_AVALON_2019" = [1.7036141952825095, 1.239619084240008, 0.08459830394899492] +"TOYOTA_AVALON_TSS2" = [2.3154403649717357, 2.7777922854327124, 0.11453999639164605] +"TOYOTA_CHR" = [1.5591084333664578, 1.271271459066948, 0.20259087058453193] +"TOYOTA_CHR_TSS2" = [1.7678810166088303, 1.3742176337919942, 0.2319674583741509] +"TOYOTA_CAMRY" = [2.0568162685952505, 1.7576185169559122, 0.108878753] +"TOYOTA_CAMRY_TSS2" = [2.3548324999999997, 2.368900128946771, 0.118436] +"TOYOTA_COROLLA" = [3.117154369115421, 1.8438132575043773, 0.12289685869250652] +"TOYOTA_COROLLA_TSS2" = [1.991132339206426, 1.868866242720403, 0.19570063298031432] +"TOYOTA_HIGHLANDER" = [1.8108348718624456, 1.6348421600679828, 0.15972686105120398] +"TOYOTA_HIGHLANDER_TSS2" = [1.9617570834136164, 1.8611643317268927, 0.14519673256119725] +"TOYOTA_MIRAI" = [2.506899832157829, 1.7417213930750164, 0.20182618449440565] +"TOYOTA_PRIUS" = [1.60, 1.5023147650693636, 0.151515] +"TOYOTA_PRIUS_TSS2" = [1.972600, 1.9104337425537743, 0.170968] +"TOYOTA_RAV4" = [2.085695074355425, 2.2142832316984733, 0.13339165270103975] +"TOYOTA_RAV4_TSS2" = [2.279239424615458, 2.087101966779332, 0.13682208413446817] +"TOYOTA_RAV4H" = [1.9796257271652042, 1.7503987331707576, 0.14628860048885406] +"TOYOTA_RAV4_TSS2_2022" = [2.241883248393209, 1.9304407208090029, 0.112174] +"TOYOTA_SIENNA" = [1.689726, 1.3208264576110418, 0.140456] +"VOLKSWAGEN_ARTEON_MK1" = [1.45136518053819, 1.3639364049316804, 0.23806361745695032] +"VOLKSWAGEN_ATLAS_MK1" = [1.4677006726964945, 1.6733266634075656, 0.12959584092073367] +"VOLKSWAGEN_GOLF_MK7" = [1.3750394140491293, 1.5814743077200641, 0.2018321939386586] +"VOLKSWAGEN_JETTA_MK7" = [1.2271623034089392, 1.216955117387, 0.19437384688370712] +"VOLKSWAGEN_PASSAT_MK8" = [1.3432120736752917, 1.7087275587362314, 0.19444383787326647] +"VOLKSWAGEN_TIGUAN_MK2" = [0.9711965500094828, 1.0001565939459098, 0.1465626137072916] diff --git a/selfdrive/car/torque_data/substitute.toml b/selfdrive/car/torque_data/substitute.toml index 6822ef437b..22ee134ae3 100644 --- a/selfdrive/car/torque_data/substitute.toml +++ b/selfdrive/car/torque_data/substitute.toml @@ -1,85 +1,85 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] -"MAZDA 3" = "MAZDA CX-9 2021" -"MAZDA 6" = "MAZDA CX-9 2021" -"MAZDA CX-5" = "MAZDA CX-9 2021" -"MAZDA CX-5 2022" = "MAZDA CX-9 2021" -"MAZDA CX-9" = "MAZDA CX-9 2021" +"MAZDA_3" = "MAZDA_CX9_2021" +"MAZDA_6" = "MAZDA_CX9_2021" +"MAZDA_CX5" = "MAZDA_CX9_2021" +"MAZDA_CX5_2022" = "MAZDA_CX9_2021" +"MAZDA_CX9" = "MAZDA_CX9_2021" -"DODGE DURANGO 2021" = "CHRYSLER PACIFICA 2020" +"DODGE_DURANGO" = "CHRYSLER_PACIFICA_2020" -"TOYOTA ALPHARD 2020" = "TOYOTA SIENNA 2018" -"TOYOTA PRIUS v 2017" = "TOYOTA PRIUS 2017" -"LEXUS IS 2018" = "LEXUS NX 2018" -"LEXUS CT HYBRID 2018" = "LEXUS NX 2018" -"LEXUS ES 2018" = "TOYOTA CAMRY 2018" -"LEXUS RC 2020" = "LEXUS NX 2020" -"LEXUS LC 2024" = "LEXUS NX 2020" +"TOYOTA_ALPHARD_TSS2" = "TOYOTA_SIENNA" +"TOYOTA_PRIUS_V" = "TOYOTA_PRIUS" +"LEXUS_IS" = "LEXUS_NX" +"LEXUS_CTH" = "LEXUS_NX" +"LEXUS_ES" = "TOYOTA_CAMRY" +"LEXUS_RC" = "LEXUS_NX_TSS2" +"LEXUS_LC_TSS2" = "LEXUS_NX_TSS2" -"KIA OPTIMA 4TH GEN" = "HYUNDAI SONATA 2020" -"KIA OPTIMA 4TH GEN FACELIFT" = "HYUNDAI SONATA 2020" -"KIA OPTIMA HYBRID 2017 & SPORTS 2019" = "HYUNDAI SONATA 2020" -"KIA OPTIMA HYBRID 4TH GEN FACELIFT" = "HYUNDAI SONATA 2020" -"KIA FORTE E 2018 & GT 2021" = "HYUNDAI SONATA 2020" -"KIA CEED INTRO ED 2019" = "HYUNDAI SONATA 2020" -"KIA SELTOS 2021" = "HYUNDAI SONATA 2020" -"KIA NIRO HYBRID 2019" = "KIA NIRO EV 2020" -"KIA NIRO PLUG-IN HYBRID 2022" = "KIA NIRO EV 2020" -"KIA NIRO HYBRID 2021" = "KIA NIRO EV 2020" -"HYUNDAI VELOSTER 2019" = "HYUNDAI SONATA 2019" -"HYUNDAI KONA 2020" = "HYUNDAI KONA ELECTRIC 2019" -"HYUNDAI KONA HYBRID 2020" = "HYUNDAI KONA ELECTRIC 2019" -"HYUNDAI KONA ELECTRIC 2022" = "HYUNDAI KONA ELECTRIC 2019" -"HYUNDAI IONIQ HYBRID 2017-2019" = "HYUNDAI IONIQ PLUG-IN HYBRID 2019" -"HYUNDAI IONIQ HYBRID 2020-2022" = "HYUNDAI IONIQ PLUG-IN HYBRID 2019" -"HYUNDAI IONIQ ELECTRIC 2020" = "HYUNDAI IONIQ PLUG-IN HYBRID 2019" -"HYUNDAI ELANTRA 2017" = "HYUNDAI SONATA 2019" -"HYUNDAI I30 N LINE 2019 & GT 2018 DCT" = "HYUNDAI SONATA 2019" -"HYUNDAI ELANTRA HYBRID 2021" = "HYUNDAI SONATA 2020" -"HYUNDAI TUCSON 2019" = "HYUNDAI SANTA FE 2019" -"HYUNDAI SANTA FE 2022" = "HYUNDAI SANTA FE HYBRID 2022" -"KIA K5 HYBRID 2020" = "KIA K5 2021" -"KIA STINGER 2022" = "KIA STINGER GT2 2018" -"GENESIS G90 2017" = "GENESIS G70 2018" -"GENESIS G80 2017" = "GENESIS G70 2018" -"GENESIS G70 2020" = "HYUNDAI SONATA 2020" +"KIA_OPTIMA_G4" = "HYUNDAI_SONATA" +"KIA_OPTIMA_G4_FL" = "HYUNDAI_SONATA" +"KIA_OPTIMA_H" = "HYUNDAI_SONATA" +"KIA_OPTIMA_H_G4_FL" = "HYUNDAI_SONATA" +"KIA_FORTE" = "HYUNDAI_SONATA" +"KIA_CEED" = "HYUNDAI_SONATA" +"KIA_SELTOS" = "HYUNDAI_SONATA" +"KIA_NIRO_PHEV" = "KIA_NIRO_EV" +"KIA_NIRO_PHEV_2022" = "KIA_NIRO_EV" +"KIA_NIRO_HEV_2021" = "KIA_NIRO_EV" +"HYUNDAI_VELOSTER" = "HYUNDAI_SONATA_LF" +"HYUNDAI_KONA" = "HYUNDAI_KONA_EV" +"HYUNDAI_KONA_HEV" = "HYUNDAI_KONA_EV" +"HYUNDAI_KONA_EV_2022" = "HYUNDAI_KONA_EV" +"HYUNDAI_IONIQ" = "HYUNDAI_IONIQ_PHEV_2019" +"HYUNDAI_IONIQ_HEV_2022" = "HYUNDAI_IONIQ_PHEV_2019" +"HYUNDAI_IONIQ_EV_2020" = "HYUNDAI_IONIQ_PHEV_2019" +"HYUNDAI_ELANTRA" = "HYUNDAI_SONATA_LF" +"HYUNDAI_ELANTRA_GT_I30" = "HYUNDAI_SONATA_LF" +"HYUNDAI_ELANTRA_HEV_2021" = "HYUNDAI_SONATA" +"HYUNDAI_TUCSON" = "HYUNDAI_SANTA_FE" +"HYUNDAI_SANTA_FE_2022" = "HYUNDAI_SANTA_FE_HEV_2022" +"KIA_K5_HEV_2020" = "KIA_K5_2021" +"KIA_STINGER_2022" = "KIA_STINGER" +"GENESIS_G90" = "GENESIS_G70" +"GENESIS_G80" = "GENESIS_G70" +"GENESIS_G70_2020" = "HYUNDAI_SONATA" -"HONDA FREED 2020" = "HONDA ODYSSEY 2018" -"HONDA CR-V EU 2016" = "HONDA CR-V 2016" -"HONDA CIVIC SEDAN 1.6 DIESEL 2019" = "HONDA CIVIC (BOSCH) 2019" -"HONDA E 2020" = "HONDA CIVIC (BOSCH) 2019" -"HONDA ODYSSEY CHN 2019" = "HONDA ODYSSEY 2018" +"HONDA_FREED" = "HONDA_ODYSSEY" +"HONDA_CRV_EU" = "HONDA_CRV" +"HONDA_CIVIC_BOSCH_DIESEL" = "HONDA_CIVIC_BOSCH" +"HONDA_E" = "HONDA_CIVIC_BOSCH" +"HONDA_ODYSSEY_CHN" = "HONDA_ODYSSEY" -"BUICK LACROSSE 2017" = "CHEVROLET VOLT PREMIER 2017" -"BUICK REGAL ESSENCE 2018" = "CHEVROLET VOLT PREMIER 2017" -"CADILLAC ESCALADE ESV 2016" = "CHEVROLET VOLT PREMIER 2017" -"CADILLAC ATS Premium Performance 2018" = "CHEVROLET VOLT PREMIER 2017" -"CHEVROLET MALIBU PREMIER 2017" = "CHEVROLET VOLT PREMIER 2017" -"HOLDEN ASTRA RS-V BK 2017" = "CHEVROLET VOLT PREMIER 2017" +"BUICK_LACROSSE" = "CHEVROLET_VOLT" +"BUICK_REGAL" = "CHEVROLET_VOLT" +"CADILLAC_ESCALADE_ESV" = "CHEVROLET_VOLT" +"CADILLAC_ATS" = "CHEVROLET_VOLT" +"CHEVROLET_MALIBU" = "CHEVROLET_VOLT" +"HOLDEN_ASTRA" = "CHEVROLET_VOLT" -"SKODA FABIA 4TH GEN" = "VOLKSWAGEN GOLF 7TH GEN" -"SKODA OCTAVIA 3RD GEN" = "SKODA SUPERB 3RD GEN" -"SKODA SCALA 1ST GEN" = "SKODA SUPERB 3RD GEN" -"SKODA KODIAQ 1ST GEN" = "SKODA SUPERB 3RD GEN" -"SKODA KAROQ 1ST GEN" = "SKODA SUPERB 3RD GEN" -"SKODA KAMIQ 1ST GEN" = "SKODA SUPERB 3RD GEN" -"VOLKSWAGEN CRAFTER 2ND GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN T-ROC 1ST GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN T-CROSS 1ST GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN TOURAN 2ND GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN TRANSPORTER T6.1" = "VOLKSWAGEN TIGUAN 2ND GEN" -"AUDI Q2 1ST GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN TAOS 1ST GEN" = "VOLKSWAGEN TIGUAN 2ND GEN" -"VOLKSWAGEN POLO 6TH GEN" = "VOLKSWAGEN GOLF 7TH GEN" -"SEAT LEON 3RD GEN" = "VOLKSWAGEN GOLF 7TH GEN" -"SEAT ATECA 1ST GEN" = "VOLKSWAGEN GOLF 7TH GEN" +"SKODA_FABIA_MK4" = "VOLKSWAGEN_GOLF_MK7" +"SKODA_OCTAVIA_MK3" = "SKODA_SUPERB_MK3" +"SKODA_SCALA_MK1" = "SKODA_SUPERB_MK3" +"SKODA_KODIAQ_MK1" = "SKODA_SUPERB_MK3" +"SKODA_KAROQ_MK1" = "SKODA_SUPERB_MK3" +"SKODA_KAMIQ_MK1" = "SKODA_SUPERB_MK3" +"VOLKSWAGEN_CRAFTER_MK2" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_TROC_MK1" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_TCROSS_MK1" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_TOURAN_MK2" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_TRANSPORTER_T61" = "VOLKSWAGEN_TIGUAN_MK2" +"AUDI_Q2_MK1" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_TAOS_MK1" = "VOLKSWAGEN_TIGUAN_MK2" +"VOLKSWAGEN_POLO_MK6" = "VOLKSWAGEN_GOLF_MK7" +"SEAT_LEON_MK3" = "VOLKSWAGEN_GOLF_MK7" +"SEAT_ATECA_MK1" = "VOLKSWAGEN_GOLF_MK7" -"SUBARU CROSSTREK HYBRID 2020" = "SUBARU IMPREZA SPORT 2020" -"SUBARU FORESTER HYBRID 2020" = "SUBARU IMPREZA SPORT 2020" -"SUBARU LEGACY 7TH GEN" = "SUBARU OUTBACK 6TH GEN" +"SUBARU_CROSSTREK_HYBRID" = "SUBARU_IMPREZA_2020" +"SUBARU_FORESTER_HYBRID" = "SUBARU_IMPREZA_2020" +"SUBARU_LEGACY" = "SUBARU_OUTBACK" # Old subarus don't have much data guessing it's like low torque impreza" -"SUBARU OUTBACK 2018 - 2019" = "SUBARU IMPREZA LIMITED 2019" -"SUBARU OUTBACK 2015 - 2017" = "SUBARU IMPREZA LIMITED 2019" -"SUBARU FORESTER 2017 - 2018" = "SUBARU IMPREZA LIMITED 2019" -"SUBARU LEGACY 2015 - 2018" = "SUBARU IMPREZA LIMITED 2019" -"SUBARU ASCENT LIMITED 2019" = "SUBARU FORESTER 2019" +"SUBARU_OUTBACK_PREGLOBAL_2018" = "SUBARU_IMPREZA" +"SUBARU_OUTBACK_PREGLOBAL" = "SUBARU_IMPREZA" +"SUBARU_FORESTER_PREGLOBAL" = "SUBARU_IMPREZA" +"SUBARU_LEGACY_PREGLOBAL" = "SUBARU_IMPREZA" +"SUBARU_ASCENT" = "SUBARU_FORESTER" diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 8e8e0292f2..f2d8a4a7bc 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -1,11 +1,10 @@ from cereal import car -from openpilot.common.numpy_fast import clip, interp -from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \ - create_gas_interceptor_command, make_can_msg +from openpilot.common.numpy_fast import clip +from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, make_can_msg from openpilot.selfdrive.car.interfaces import CarControllerBase from openpilot.selfdrive.car.toyota import toyotacan from openpilot.selfdrive.car.toyota.values import CAR, STATIC_DSU_MSGS, NO_STOP_TIMER_CAR, TSS2_CAR, \ - MIN_ACC_SPEED, PEDAL_TRANSITION, CarControllerParams, ToyotaFlags, \ + CarControllerParams, ToyotaFlags, \ UNSUPPORTED_DSU_CAR from opendbc.can.packer import CANPacker @@ -101,21 +100,6 @@ class CarController(CarControllerBase): lta_active, self.frame // 2, torque_wind_down)) # *** gas and brake *** - if self.CP.enableGasInterceptor and CC.longActive: - MAX_INTERCEPTOR_GAS = 0.5 - # RAV4 has very sensitive gas pedal - if self.CP.carFingerprint in (CAR.RAV4, CAR.RAV4H, CAR.HIGHLANDER): - PEDAL_SCALE = interp(CS.out.vEgo, [0.0, MIN_ACC_SPEED, MIN_ACC_SPEED + PEDAL_TRANSITION], [0.15, 0.3, 0.0]) - elif self.CP.carFingerprint in (CAR.COROLLA,): - PEDAL_SCALE = interp(CS.out.vEgo, [0.0, MIN_ACC_SPEED, MIN_ACC_SPEED + PEDAL_TRANSITION], [0.3, 0.4, 0.0]) - else: - PEDAL_SCALE = interp(CS.out.vEgo, [0.0, MIN_ACC_SPEED, MIN_ACC_SPEED + PEDAL_TRANSITION], [0.4, 0.5, 0.0]) - # offset for creep and windbrake - pedal_offset = interp(CS.out.vEgo, [0.0, 2.3, MIN_ACC_SPEED + PEDAL_TRANSITION], [-.4, 0.0, 0.2]) - pedal_command = PEDAL_SCALE * (actuators.accel + pedal_offset) - interceptor_gas_cmd = clip(pedal_command, 0., MAX_INTERCEPTOR_GAS) - else: - interceptor_gas_cmd = 0. pcm_accel_cmd = clip(actuators.accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX) # TODO: probably can delete this. CS.pcm_acc_status uses a different signal @@ -124,7 +108,7 @@ class CarController(CarControllerBase): pcm_cancel_cmd = 1 # on entering standstill, send standstill request - if CS.out.standstill and not self.last_standstill and (self.CP.carFingerprint not in NO_STOP_TIMER_CAR or self.CP.enableGasInterceptor): + if CS.out.standstill and not self.last_standstill and (self.CP.carFingerprint not in NO_STOP_TIMER_CAR): self.standstill_req = True if CS.pcm_acc_status != 8: # pcm entered standstill or it's disabled @@ -141,9 +125,9 @@ class CarController(CarControllerBase): lead = hud_control.leadVisible or CS.out.vEgo < 12. # at low speed we always assume the lead is present so ACC can be engaged # Press distance button until we are at the correct bar length. Only change while enabled to avoid skipping startup popup - if self.frame % 6 == 0: - if CS.pcm_follow_distance_values.get(CS.pcm_follow_distance, "UNKNOWN") != "FAR" and CS.out.cruiseState.enabled and \ - self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR: + if self.frame % 6 == 0 and self.CP.openpilotLongitudinalControl: + desired_distance = 4 - hud_control.leadDistanceBars + if CS.out.cruiseState.enabled and CS.pcm_follow_distance != desired_distance: self.distance_button = not self.distance_button else: self.distance_button = 0 @@ -158,14 +142,8 @@ class CarController(CarControllerBase): else: can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False, self.distance_button)) - if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl: - # send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd. - # This prevents unexpected pedal range rescaling - can_sends.append(create_gas_interceptor_command(self.packer, interceptor_gas_cmd, self.frame // 2)) - self.gas = interceptor_gas_cmd - # *** hud ui *** - if self.CP.carFingerprint != CAR.PRIUS_V: + if self.CP.carFingerprint != CAR.TOYOTA_PRIUS_V: # ui mesg is at 1Hz but we send asap if: # - there is something to display # - there is something to stop displaying diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 65fced80f4..0efa065dc2 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -44,7 +44,6 @@ class CarState(CarStateBase): self.distance_button = 0 self.pcm_follow_distance = 0 - self.pcm_follow_distance_values = can_define.dv['PCM_CRUISE_2']['PCM_FOLLOW_DISTANCE'] self.low_speed_lockout = False self.acc_type = 1 @@ -60,12 +59,8 @@ class CarState(CarStateBase): ret.brakePressed = cp.vl["BRAKE_MODULE"]["BRAKE_PRESSED"] != 0 ret.brakeHoldActive = cp.vl["ESP_CONTROL"]["BRAKE_HOLD_ACTIVE"] == 1 - if self.CP.enableGasInterceptor: - ret.gas = (cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) // 2 - ret.gasPressed = ret.gas > 805 - else: - # TODO: find a common gas pedal percentage signal - ret.gasPressed = cp.vl["PCM_CRUISE"]["GAS_RELEASED"] == 0 + + ret.gasPressed = cp.vl["PCM_CRUISE"]["GAS_RELEASED"] == 0 ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["WHEEL_SPEEDS"]["WHEEL_SPEED_FL"], @@ -101,7 +96,7 @@ class CarState(CarStateBase): ret.leftBlinker = cp.vl["BLINKERS_STATE"]["TURN_SIGNALS"] == 1 ret.rightBlinker = cp.vl["BLINKERS_STATE"]["TURN_SIGNALS"] == 2 - if self.CP.carFingerprint != CAR.MIRAI: + if self.CP.carFingerprint != CAR.TOYOTA_MIRAI: ret.engineRpm = cp.vl["ENGINE_RPM"]["RPM"] ret.steeringTorque = cp.vl["STEER_TORQUE_SENSOR"]["STEER_TORQUE_DRIVER"] @@ -166,7 +161,7 @@ class CarState(CarStateBase): ret.leftBlindspot = (cp.vl["BSM"]["L_ADJACENT"] == 1) or (cp.vl["BSM"]["L_APPROACHING"] == 1) ret.rightBlindspot = (cp.vl["BSM"]["R_ADJACENT"] == 1) or (cp.vl["BSM"]["R_APPROACHING"] == 1) - if self.CP.carFingerprint != CAR.PRIUS_V: + if self.CP.carFingerprint != CAR.TOYOTA_PRIUS_V: self.lkas_hud = copy.copy(cp_cam.vl["LKAS_HUD"]) if self.CP.carFingerprint not in UNSUPPORTED_DSU_CAR: @@ -200,7 +195,7 @@ class CarState(CarStateBase): ("STEER_TORQUE_SENSOR", 50), ] - if CP.carFingerprint != CAR.MIRAI: + if CP.carFingerprint != CAR.TOYOTA_MIRAI: messages.append(("ENGINE_RPM", 42)) if CP.carFingerprint in UNSUPPORTED_DSU_CAR: @@ -209,10 +204,6 @@ class CarState(CarStateBase): else: messages.append(("PCM_CRUISE_2", 33)) - # add gas interceptor reading if we are using it - if CP.enableGasInterceptor: - messages.append(("GAS_SENSOR", 50)) - if CP.enableBsm: messages.append(("BSM", 1)) @@ -241,7 +232,7 @@ class CarState(CarStateBase): def get_cam_can_parser(CP): messages = [] - if CP.carFingerprint != CAR.PRIUS_V: + if CP.carFingerprint != CAR.TOYOTA_PRIUS_V: messages += [ ("LKAS_HUD", 1), ] diff --git a/selfdrive/car/toyota/fingerprints.py b/selfdrive/car/toyota/fingerprints.py index 86d45532fa..1803b00255 100644 --- a/selfdrive/car/toyota/fingerprints.py +++ b/selfdrive/car/toyota/fingerprints.py @@ -4,7 +4,7 @@ from openpilot.selfdrive.car.toyota.values import CAR Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.AVALON: { + CAR.TOYOTA_AVALON: { (Ecu.abs, 0x7b0, None): [ b'F152607060\x00\x00\x00\x00\x00\x00', ], @@ -30,7 +30,7 @@ FW_VERSIONS = { b'8646F0703000\x00\x00\x00\x00', ], }, - CAR.AVALON_2019: { + CAR.TOYOTA_AVALON_2019: { (Ecu.abs, 0x7b0, None): [ b'F152607110\x00\x00\x00\x00\x00\x00', b'F152607140\x00\x00\x00\x00\x00\x00', @@ -71,7 +71,7 @@ FW_VERSIONS = { b'8646F0702100\x00\x00\x00\x00', ], }, - CAR.AVALON_TSS2: { + CAR.TOYOTA_AVALON_TSS2: { (Ecu.abs, 0x7b0, None): [ b'\x01F152607240\x00\x00\x00\x00\x00\x00', b'\x01F152607250\x00\x00\x00\x00\x00\x00', @@ -95,7 +95,7 @@ FW_VERSIONS = { b'\x028646F4104100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', ], }, - CAR.CAMRY: { + CAR.TOYOTA_CAMRY: { (Ecu.engine, 0x700, None): [ b'\x018966306L3100\x00\x00\x00\x00', b'\x018966306L4200\x00\x00\x00\x00', @@ -222,7 +222,7 @@ FW_VERSIONS = { b'8646F0607100 ', ], }, - CAR.CAMRY_TSS2: { + CAR.TOYOTA_CAMRY_TSS2: { (Ecu.eps, 0x7a1, None): [ b'8965B33630\x00\x00\x00\x00\x00\x00', b'8965B33640\x00\x00\x00\x00\x00\x00', @@ -268,7 +268,7 @@ FW_VERSIONS = { b'\x028646F3305500\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, - CAR.CHR: { + CAR.TOYOTA_CHR: { (Ecu.engine, 0x700, None): [ b'\x01896631017100\x00\x00\x00\x00', b'\x01896631017200\x00\x00\x00\x00', @@ -353,7 +353,7 @@ FW_VERSIONS = { b'8646FF407100 ', ], }, - CAR.CHR_TSS2: { + CAR.TOYOTA_CHR_TSS2: { (Ecu.abs, 0x7b0, None): [ b'F152610041\x00\x00\x00\x00\x00\x00', b'F152610260\x00\x00\x00\x00\x00\x00', @@ -385,7 +385,7 @@ FW_VERSIONS = { b'\x028646FF413100\x00\x00\x00\x008646GF411100\x00\x00\x00\x00', ], }, - CAR.COROLLA: { + CAR.TOYOTA_COROLLA: { (Ecu.engine, 0x7e0, None): [ b'\x0230ZC2000\x00\x00\x00\x00\x00\x00\x00\x0050212000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0230ZC2100\x00\x00\x00\x00\x00\x00\x00\x0050212000\x00\x00\x00\x00\x00\x00\x00\x00', @@ -419,7 +419,7 @@ FW_VERSIONS = { b'8646F0201200\x00\x00\x00\x00', ], }, - CAR.COROLLA_TSS2: { + CAR.TOYOTA_COROLLA_TSS2: { (Ecu.engine, 0x700, None): [ b'\x01896630A22000\x00\x00\x00\x00', b'\x01896630ZG2000\x00\x00\x00\x00', @@ -594,7 +594,7 @@ FW_VERSIONS = { b'\x028646F7605100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, - CAR.HIGHLANDER: { + CAR.TOYOTA_HIGHLANDER: { (Ecu.engine, 0x700, None): [ b'\x01896630E09000\x00\x00\x00\x00', b'\x01896630E43000\x00\x00\x00\x00', @@ -639,6 +639,7 @@ FW_VERSIONS = { (Ecu.dsu, 0x791, None): [ b'881510E01100\x00\x00\x00\x00', b'881510E01200\x00\x00\x00\x00', + b'881510E02200\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'8821F4702100\x00\x00\x00\x00', @@ -649,7 +650,7 @@ FW_VERSIONS = { b'8646F0E01300\x00\x00\x00\x00', ], }, - CAR.HIGHLANDER_TSS2: { + CAR.TOYOTA_HIGHLANDER_TSS2: { (Ecu.eps, 0x7a1, None): [ b'8965B48241\x00\x00\x00\x00\x00\x00', b'8965B48310\x00\x00\x00\x00\x00\x00', @@ -686,6 +687,7 @@ FW_VERSIONS = { b'\x01896630EB1000\x00\x00\x00\x00', b'\x01896630EB1100\x00\x00\x00\x00', b'\x01896630EB1200\x00\x00\x00\x00', + b'\x01896630EB1300\x00\x00\x00\x00', b'\x01896630EB2000\x00\x00\x00\x00', b'\x01896630EB2100\x00\x00\x00\x00', b'\x01896630EB2200\x00\x00\x00\x00', @@ -794,7 +796,7 @@ FW_VERSIONS = { b'\x028646F5303400\x00\x00\x00\x008646G3304000\x00\x00\x00\x00', ], }, - CAR.PRIUS: { + CAR.TOYOTA_PRIUS: { (Ecu.engine, 0x700, None): [ b'\x02896634761000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x02896634761100\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', @@ -892,7 +894,7 @@ FW_VERSIONS = { b'8646F4705200\x00\x00\x00\x00', ], }, - CAR.PRIUS_V: { + CAR.TOYOTA_PRIUS_V: { (Ecu.abs, 0x7b0, None): [ b'F152647280\x00\x00\x00\x00\x00\x00', ], @@ -909,7 +911,7 @@ FW_VERSIONS = { b'8646F4703300\x00\x00\x00\x00', ], }, - CAR.RAV4: { + CAR.TOYOTA_RAV4: { (Ecu.engine, 0x7e0, None): [ b'\x02342Q1000\x00\x00\x00\x00\x00\x00\x00\x0054212000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x02342Q1100\x00\x00\x00\x00\x00\x00\x00\x0054212000\x00\x00\x00\x00\x00\x00\x00\x00', @@ -950,7 +952,7 @@ FW_VERSIONS = { b'8646F4204000\x00\x00\x00\x00', ], }, - CAR.RAV4H: { + CAR.TOYOTA_RAV4H: { (Ecu.engine, 0x7e0, None): [ b'\x02342N9000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x02342N9100\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', @@ -987,7 +989,7 @@ FW_VERSIONS = { b'8646F4204000\x00\x00\x00\x00', ], }, - CAR.RAV4_TSS2: { + CAR.TOYOTA_RAV4_TSS2: { (Ecu.engine, 0x700, None): [ b'\x01896630R58000\x00\x00\x00\x00', b'\x01896630R58100\x00\x00\x00\x00', @@ -1097,7 +1099,7 @@ FW_VERSIONS = { b'\x028646F4203800\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', ], }, - CAR.RAV4_TSS2_2022: { + CAR.TOYOTA_RAV4_TSS2_2022: { (Ecu.abs, 0x7b0, None): [ b'\x01F15260R350\x00\x00\x00\x00\x00\x00', b'\x01F15260R361\x00\x00\x00\x00\x00\x00', @@ -1133,7 +1135,7 @@ FW_VERSIONS = { b'\x028646F0R02100\x00\x00\x00\x008646G0R01100\x00\x00\x00\x00', ], }, - CAR.RAV4_TSS2_2023: { + CAR.TOYOTA_RAV4_TSS2_2023: { (Ecu.abs, 0x7b0, None): [ b'\x01F15260R450\x00\x00\x00\x00\x00\x00', b'\x01F15260R51000\x00\x00\x00\x00', @@ -1141,6 +1143,7 @@ FW_VERSIONS = { b'\x01F15264283300\x00\x00\x00\x00', b'\x01F152642F1000\x00\x00\x00\x00', b'\x01F152642F8000\x00\x00\x00\x00', + b'\x01F152642F8100\x00\x00\x00\x00', ], (Ecu.eps, 0x7a1, None): [ b'\x028965B0R11000\x00\x00\x00\x008965B0R12000\x00\x00\x00\x00', @@ -1153,6 +1156,7 @@ FW_VERSIONS = { b'\x01896634AF0000\x00\x00\x00\x00', b'\x01896634AJ2000\x00\x00\x00\x00', b'\x01896634AL5000\x00\x00\x00\x00', + b'\x01896634AL6000\x00\x00\x00\x00', ], (Ecu.fwdRadar, 0x750, 0xf): [ b'\x018821F0R03100\x00\x00\x00\x00', @@ -1163,7 +1167,7 @@ FW_VERSIONS = { b'\x028646F0R11000\x00\x00\x00\x008646G0R04000\x00\x00\x00\x00', ], }, - CAR.SIENNA: { + CAR.TOYOTA_SIENNA: { (Ecu.engine, 0x700, None): [ b'\x01896630832100\x00\x00\x00\x00', b'\x01896630832200\x00\x00\x00\x00', @@ -1543,6 +1547,7 @@ FW_VERSIONS = { b'\x018966348W5100\x00\x00\x00\x00', b'\x018966348W9000\x00\x00\x00\x00', b'\x018966348X0000\x00\x00\x00\x00', + b'\x01896634D11000\x00\x00\x00\x00', b'\x01896634D12000\x00\x00\x00\x00', b'\x01896634D12100\x00\x00\x00\x00', b'\x01896634D43000\x00\x00\x00\x00', @@ -1586,7 +1591,7 @@ FW_VERSIONS = { b'\x028646F4810400\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', ], }, - CAR.PRIUS_TSS2: { + CAR.TOYOTA_PRIUS_TSS2: { (Ecu.engine, 0x700, None): [ b'\x028966347B1000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', b'\x028966347C4000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00', @@ -1617,7 +1622,7 @@ FW_VERSIONS = { b'\x028646F4712000\x00\x00\x00\x008646G2601500\x00\x00\x00\x00', ], }, - CAR.MIRAI: { + CAR.TOYOTA_MIRAI: { (Ecu.abs, 0x7d1, None): [ b'\x01898A36203000\x00\x00\x00\x00', ], @@ -1635,7 +1640,7 @@ FW_VERSIONS = { b'\x028646F6201400\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', ], }, - CAR.ALPHARD_TSS2: { + CAR.TOYOTA_ALPHARD_TSS2: { (Ecu.engine, 0x7e0, None): [ b'\x0235870000\x00\x00\x00\x00\x00\x00\x00\x00A0202000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0235879000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00', diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 7ad9feed3d..3ea05f9fef 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -57,7 +57,7 @@ class CarInterface(CarInterfaceBase): ret.enableDsu = len(found_ecus) > 0 and Ecu.dsu not in found_ecus and candidate not in (NO_DSU_CAR | UNSUPPORTED_DSU_CAR) \ and not (ret.flags & ToyotaFlags.SMART_DSU) - if candidate == CAR.PRIUS: + if candidate == CAR.TOYOTA_PRIUS: stop_and_go = True # Only give steer angle deadzone to for bad angle sensor prius for fw in car_fw: @@ -69,12 +69,12 @@ class CarInterface(CarInterfaceBase): stop_and_go = True ret.wheelSpeedFactor = 1.035 - elif candidate in (CAR.AVALON, CAR.AVALON_2019, CAR.AVALON_TSS2): + elif candidate in (CAR.TOYOTA_AVALON, CAR.TOYOTA_AVALON_2019, CAR.TOYOTA_AVALON_TSS2): # starting from 2019, all Avalon variants have stop and go # https://engage.toyota.com/static/images/toyota_safety_sense/TSS_Applicability_Chart.pdf - stop_and_go = candidate != CAR.AVALON + stop_and_go = candidate != CAR.TOYOTA_AVALON - elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023): + elif candidate in (CAR.TOYOTA_RAV4_TSS2, CAR.TOYOTA_RAV4_TSS2_2022, CAR.TOYOTA_RAV4_TSS2_2023): ret.lateralTuning.init('pid') ret.lateralTuning.pid.kiBP = [0.0] ret.lateralTuning.pid.kpBP = [0.0] @@ -91,7 +91,7 @@ class CarInterface(CarInterfaceBase): ret.lateralTuning.pid.kf = 0.00004 break - elif candidate in (CAR.RAV4H, CAR.CHR, CAR.CAMRY, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_NX): + elif candidate in (CAR.TOYOTA_CHR, CAR.TOYOTA_CAMRY, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_NX): # TODO: Some of these platforms are not advertised to have full range ACC, are they similar to SNG_WITHOUT_DSU cars? stop_and_go = True @@ -133,22 +133,18 @@ class CarInterface(CarInterfaceBase): # - TSS-P DSU-less cars w/ CAN filter installed (no radar parser yet) ret.openpilotLongitudinalControl = use_sdsu or ret.enableDsu or candidate in (TSS2_CAR - RADAR_ACC_CAR) or bool(ret.flags & ToyotaFlags.DISABLE_RADAR.value) ret.autoResumeSng = ret.openpilotLongitudinalControl and candidate in NO_STOP_TIMER_CAR - ret.enableGasInterceptor = 0x201 in fingerprint[0] and ret.openpilotLongitudinalControl if not ret.openpilotLongitudinalControl: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL - if ret.enableGasInterceptor: - ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_GAS_INTERCEPTOR - # min speed to enable ACC. if car can do stop and go, then set enabling speed # to a negative value, so it won't matter. - ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptor) else MIN_ACC_SPEED + ret.minEnableSpeed = -1. if stop_and_go else MIN_ACC_SPEED tune = ret.longitudinalTuning tune.deadzoneBP = [0., 9.] tune.deadzoneV = [.0, .15] - if candidate in TSS2_CAR or ret.enableGasInterceptor: + if candidate in TSS2_CAR: tune.kpBP = [0., 5., 20.] tune.kpV = [1.3, 1.0, 0.7] tune.kiBP = [0., 5., 12., 20., 27.] @@ -188,7 +184,7 @@ class CarInterface(CarInterfaceBase): events.add(EventName.vehicleSensorsInvalid) if self.CP.openpilotLongitudinalControl: - if ret.cruiseState.standstill and not ret.brakePressed and not self.CP.enableGasInterceptor: + if ret.cruiseState.standstill and not ret.brakePressed: events.add(EventName.resumeRequired) if self.CS.low_speed_lockout: events.add(EventName.lowSpeedLockout) @@ -204,8 +200,3 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() return ret - - # pass in a car.CarControl - # to be called @ 100hz - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) diff --git a/selfdrive/car/toyota/tests/test_toyota.py b/selfdrive/car/toyota/tests/test_toyota.py index d9d4fe087f..ba131a0185 100755 --- a/selfdrive/car/toyota/tests/test_toyota.py +++ b/selfdrive/car/toyota/tests/test_toyota.py @@ -13,6 +13,10 @@ Ecu = car.CarParams.Ecu ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} +def check_fw_version(fw_version: bytes) -> bool: + return b'?' not in fw_version + + class TestToyotaInterfaces(unittest.TestCase): def test_car_sets(self): self.assertTrue(len(ANGLE_CONTROL_CAR - TSS2_CAR) == 0) @@ -20,7 +24,7 @@ class TestToyotaInterfaces(unittest.TestCase): def test_lta_platforms(self): # At this time, only RAV4 2023 is expected to use LTA/angle control - self.assertEqual(ANGLE_CONTROL_CAR, {CAR.RAV4_TSS2_2023}) + self.assertEqual(ANGLE_CONTROL_CAR, {CAR.TOYOTA_RAV4_TSS2_2023}) def test_tss2_dbc(self): # We make some assumptions about TSS2 platforms, @@ -39,13 +43,13 @@ class TestToyotaInterfaces(unittest.TestCase): self.assertEqual(len(missing_ecus), 0) # Some exceptions for other common ECUs - if car_model not in (CAR.ALPHARD_TSS2,): + if car_model not in (CAR.TOYOTA_ALPHARD_TSS2,): self.assertIn(Ecu.abs, present_ecus) - if car_model not in (CAR.MIRAI,): + if car_model not in (CAR.TOYOTA_MIRAI,): self.assertIn(Ecu.engine, present_ecus) - if car_model not in (CAR.PRIUS_V, CAR.LEXUS_CTH): + if car_model not in (CAR.TOYOTA_PRIUS_V, CAR.LEXUS_CTH): self.assertIn(Ecu.eps, present_ecus) @@ -59,6 +63,14 @@ class TestToyotaFingerprint(unittest.TestCase): car_model in FW_QUERY_CONFIG.non_essential_ecus[Ecu.engine], f"Car model unexpectedly {'not ' if len(engine_ecus) > 1 else ''}in non-essential list") + def test_valid_fw_versions(self): + # Asserts all FW versions are valid + for car_model, ecus in FW_VERSIONS.items(): + with self.subTest(car_model=car_model.value): + for fws in ecus.values(): + for fw in fws: + self.assertTrue(check_fw_version(fw), fw) + # Tests for part numbers, platform codes, and sub-versions which Toyota will use to fuzzy # fingerprint in the absence of full FW matches: @settings(max_examples=100) @@ -73,9 +85,9 @@ class TestToyotaFingerprint(unittest.TestCase): for car_model, ecus in FW_VERSIONS.items(): with self.subTest(car_model=car_model.value): for platform_code_ecu in PLATFORM_CODE_ECUS: - if platform_code_ecu == Ecu.eps and car_model in (CAR.PRIUS_V, CAR.LEXUS_CTH,): + if platform_code_ecu == Ecu.eps and car_model in (CAR.TOYOTA_PRIUS_V, CAR.LEXUS_CTH,): continue - if platform_code_ecu == Ecu.abs and car_model in (CAR.ALPHARD_TSS2,): + if platform_code_ecu == Ecu.abs and car_model in (CAR.TOYOTA_ALPHARD_TSS2,): continue self.assertIn(platform_code_ecu, [e[0] for e in ecus]) diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index 2be7ca1865..179e3f97e3 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -7,7 +7,7 @@ from cereal import car from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms from openpilot.selfdrive.car import AngleRateLimit, dbc_dict -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, CarParts, CarHarness +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarDocs, Column, CarParts, CarHarness from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu @@ -67,7 +67,7 @@ class Footnote(Enum): @dataclass -class ToyotaCarInfo(CarInfo): +class ToyotaCarDocs(CarDocs): package: str = "All" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.toyota_a])) @@ -85,194 +85,173 @@ class ToyotaTSS2PlatformConfig(PlatformConfig): class CAR(Platforms): # Toyota - ALPHARD_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA ALPHARD 2020", + TOYOTA_ALPHARD_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota Alphard 2019-20"), - ToyotaCarInfo("Toyota Alphard Hybrid 2021"), + ToyotaCarDocs("Toyota Alphard 2019-20"), + ToyotaCarDocs("Toyota Alphard Hybrid 2021"), ], CarSpecs(mass=4305. * CV.LB_TO_KG, wheelbase=3.0, steerRatio=14.2, tireStiffnessFactor=0.444), ) - AVALON = PlatformConfig( - "TOYOTA AVALON 2016", + TOYOTA_AVALON = PlatformConfig( [ - ToyotaCarInfo("Toyota Avalon 2016", "Toyota Safety Sense P"), - ToyotaCarInfo("Toyota Avalon 2017-18"), + ToyotaCarDocs("Toyota Avalon 2016", "Toyota Safety Sense P"), + ToyotaCarDocs("Toyota Avalon 2017-18"), ], CarSpecs(mass=3505. * CV.LB_TO_KG, wheelbase=2.82, steerRatio=14.8, tireStiffnessFactor=0.7983), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), ) - AVALON_2019 = PlatformConfig( - "TOYOTA AVALON 2019", + TOYOTA_AVALON_2019 = PlatformConfig( [ - ToyotaCarInfo("Toyota Avalon 2019-21"), - ToyotaCarInfo("Toyota Avalon Hybrid 2019-21"), + ToyotaCarDocs("Toyota Avalon 2019-21"), + ToyotaCarDocs("Toyota Avalon Hybrid 2019-21"), ], - AVALON.specs, + TOYOTA_AVALON.specs, dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), ) - AVALON_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA AVALON 2022", # TSS 2.5 + TOYOTA_AVALON_TSS2 = ToyotaTSS2PlatformConfig( # TSS 2.5 [ - ToyotaCarInfo("Toyota Avalon 2022"), - ToyotaCarInfo("Toyota Avalon Hybrid 2022"), + ToyotaCarDocs("Toyota Avalon 2022"), + ToyotaCarDocs("Toyota Avalon Hybrid 2022"), ], - AVALON.specs, + TOYOTA_AVALON.specs, ) - CAMRY = PlatformConfig( - "TOYOTA CAMRY 2018", + TOYOTA_CAMRY = PlatformConfig( [ - ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]), - ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"), + ToyotaCarDocs("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]), + ToyotaCarDocs("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"), ], CarSpecs(mass=3400. * CV.LB_TO_KG, wheelbase=2.82448, steerRatio=13.7, tireStiffnessFactor=0.7933), dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), flags=ToyotaFlags.NO_DSU, ) - CAMRY_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA CAMRY 2021", # TSS 2.5 + TOYOTA_CAMRY_TSS2 = ToyotaTSS2PlatformConfig( # TSS 2.5 [ - ToyotaCarInfo("Toyota Camry 2021-24", footnotes=[Footnote.CAMRY]), - ToyotaCarInfo("Toyota Camry Hybrid 2021-24"), + ToyotaCarDocs("Toyota Camry 2021-24", footnotes=[Footnote.CAMRY]), + ToyotaCarDocs("Toyota Camry Hybrid 2021-24"), ], - CAMRY.specs, + TOYOTA_CAMRY.specs, ) - CHR = PlatformConfig( - "TOYOTA C-HR 2018", + TOYOTA_CHR = PlatformConfig( [ - ToyotaCarInfo("Toyota C-HR 2017-20"), - ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"), + ToyotaCarDocs("Toyota C-HR 2017-20"), + ToyotaCarDocs("Toyota C-HR Hybrid 2017-20"), ], CarSpecs(mass=3300. * CV.LB_TO_KG, wheelbase=2.63906, steerRatio=13.6, tireStiffnessFactor=0.7933), dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), flags=ToyotaFlags.NO_DSU, ) - CHR_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA C-HR 2021", + TOYOTA_CHR_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota C-HR 2021"), - ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"), + ToyotaCarDocs("Toyota C-HR 2021"), + ToyotaCarDocs("Toyota C-HR Hybrid 2021-22"), ], - CHR.specs, + TOYOTA_CHR.specs, flags=ToyotaFlags.RADAR_ACC, ) - COROLLA = PlatformConfig( - "TOYOTA COROLLA 2017", - ToyotaCarInfo("Toyota Corolla 2017-19"), + TOYOTA_COROLLA = PlatformConfig( + [ToyotaCarDocs("Toyota Corolla 2017-19")], CarSpecs(mass=2860. * CV.LB_TO_KG, wheelbase=2.7, steerRatio=18.27, tireStiffnessFactor=0.444), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), ) # LSS2 Lexus UX Hybrid is same as a TSS2 Corolla Hybrid - COROLLA_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA COROLLA TSS2 2019", + TOYOTA_COROLLA_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), - ToyotaCarInfo("Toyota Corolla Cross (Non-US only) 2020-23", min_enable_speed=7.5), - ToyotaCarInfo("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), + ToyotaCarDocs("Toyota Corolla 2020-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), + ToyotaCarDocs("Toyota Corolla Cross (Non-US only) 2020-23", min_enable_speed=7.5), + ToyotaCarDocs("Toyota Corolla Hatchback 2019-22", video_link="https://www.youtube.com/watch?v=_66pXk0CBYA"), # Hybrid platforms - ToyotaCarInfo("Toyota Corolla Hybrid 2020-22"), - ToyotaCarInfo("Toyota Corolla Hybrid (Non-US only) 2020-23", min_enable_speed=7.5), - ToyotaCarInfo("Toyota Corolla Cross Hybrid (Non-US only) 2020-22", min_enable_speed=7.5), - ToyotaCarInfo("Lexus UX Hybrid 2019-23"), + ToyotaCarDocs("Toyota Corolla Hybrid 2020-22"), + ToyotaCarDocs("Toyota Corolla Hybrid (Non-US only) 2020-23", min_enable_speed=7.5), + ToyotaCarDocs("Toyota Corolla Cross Hybrid (Non-US only) 2020-22", min_enable_speed=7.5), + ToyotaCarDocs("Lexus UX Hybrid 2019-23"), ], CarSpecs(mass=3060. * CV.LB_TO_KG, wheelbase=2.67, steerRatio=13.9, tireStiffnessFactor=0.444), ) - HIGHLANDER = PlatformConfig( - "TOYOTA HIGHLANDER 2017", + TOYOTA_HIGHLANDER = PlatformConfig( [ - ToyotaCarInfo("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo"), - ToyotaCarInfo("Toyota Highlander Hybrid 2017-19"), + ToyotaCarDocs("Toyota Highlander 2017-19", video_link="https://www.youtube.com/watch?v=0wS0wXSLzoo"), + ToyotaCarDocs("Toyota Highlander Hybrid 2017-19"), ], CarSpecs(mass=4516. * CV.LB_TO_KG, wheelbase=2.8194, steerRatio=16.0, tireStiffnessFactor=0.8), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), flags=ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.SNG_WITHOUT_DSU, ) - HIGHLANDER_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA HIGHLANDER 2020", + TOYOTA_HIGHLANDER_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota Highlander 2020-23"), - ToyotaCarInfo("Toyota Highlander Hybrid 2020-23"), + ToyotaCarDocs("Toyota Highlander 2020-23"), + ToyotaCarDocs("Toyota Highlander Hybrid 2020-23"), ], - HIGHLANDER.specs, + TOYOTA_HIGHLANDER.specs, ) - PRIUS = PlatformConfig( - "TOYOTA PRIUS 2017", + TOYOTA_PRIUS = PlatformConfig( [ - ToyotaCarInfo("Toyota Prius 2016", "Toyota Safety Sense P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), - ToyotaCarInfo("Toyota Prius 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), - ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), + ToyotaCarDocs("Toyota Prius 2016", "Toyota Safety Sense P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), + ToyotaCarDocs("Toyota Prius 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), + ToyotaCarDocs("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0"), ], CarSpecs(mass=3045. * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.74, tireStiffnessFactor=0.6371), dbc_dict('toyota_nodsu_pt_generated', 'toyota_adas'), ) - PRIUS_V = PlatformConfig( - "TOYOTA PRIUS v 2017", - ToyotaCarInfo("Toyota Prius v 2017", "Toyota Safety Sense P", min_enable_speed=MIN_ACC_SPEED), + TOYOTA_PRIUS_V = PlatformConfig( + [ToyotaCarDocs("Toyota Prius v 2017", "Toyota Safety Sense P", min_enable_speed=MIN_ACC_SPEED)], CarSpecs(mass=3340. * CV.LB_TO_KG, wheelbase=2.78, steerRatio=17.4, tireStiffnessFactor=0.5533), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), flags=ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.SNG_WITHOUT_DSU, ) - PRIUS_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA PRIUS TSS2 2021", + TOYOTA_PRIUS_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), - ToyotaCarInfo("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), + ToyotaCarDocs("Toyota Prius 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), + ToyotaCarDocs("Toyota Prius Prime 2021-22", video_link="https://www.youtube.com/watch?v=J58TvCpUd4U"), ], CarSpecs(mass=3115. * CV.LB_TO_KG, wheelbase=2.70002, steerRatio=13.4, tireStiffnessFactor=0.6371), ) - RAV4 = PlatformConfig( - "TOYOTA RAV4 2017", + TOYOTA_RAV4 = PlatformConfig( [ - ToyotaCarInfo("Toyota RAV4 2016", "Toyota Safety Sense P"), - ToyotaCarInfo("Toyota RAV4 2017-18") + ToyotaCarDocs("Toyota RAV4 2016", "Toyota Safety Sense P"), + ToyotaCarDocs("Toyota RAV4 2017-18") ], CarSpecs(mass=3650. * CV.LB_TO_KG, wheelbase=2.65, steerRatio=16.88, tireStiffnessFactor=0.5533), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), ) - RAV4H = PlatformConfig( - "TOYOTA RAV4 HYBRID 2017", + TOYOTA_RAV4H = PlatformConfig( [ - ToyotaCarInfo("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26"), - ToyotaCarInfo("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26") + ToyotaCarDocs("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26"), + ToyotaCarDocs("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26") ], - RAV4.specs, + TOYOTA_RAV4.specs, dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), - flags=ToyotaFlags.NO_STOP_TIMER, + # Note that the ICE RAV4 does not respect positive acceleration commands under 19 mph + flags=ToyotaFlags.NO_STOP_TIMER | ToyotaFlags.SNG_WITHOUT_DSU, ) - RAV4_TSS2 = ToyotaTSS2PlatformConfig( - "TOYOTA RAV4 2019", + TOYOTA_RAV4_TSS2 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), - ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), + ToyotaCarDocs("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"), + ToyotaCarDocs("Toyota RAV4 Hybrid 2019-21"), ], CarSpecs(mass=3585. * CV.LB_TO_KG, wheelbase=2.68986, steerRatio=14.3, tireStiffnessFactor=0.7933), ) - RAV4_TSS2_2022 = ToyotaTSS2PlatformConfig( - "TOYOTA RAV4 2022", + TOYOTA_RAV4_TSS2_2022 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota RAV4 2022"), - ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"), + ToyotaCarDocs("Toyota RAV4 2022"), + ToyotaCarDocs("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"), ], - RAV4_TSS2.specs, + TOYOTA_RAV4_TSS2.specs, flags=ToyotaFlags.RADAR_ACC, ) - RAV4_TSS2_2023 = ToyotaTSS2PlatformConfig( - "TOYOTA RAV4 2023", + TOYOTA_RAV4_TSS2_2023 = ToyotaTSS2PlatformConfig( [ - ToyotaCarInfo("Toyota RAV4 2023-24"), - ToyotaCarInfo("Toyota RAV4 Hybrid 2023-24"), + ToyotaCarDocs("Toyota RAV4 2023-24"), + ToyotaCarDocs("Toyota RAV4 Hybrid 2023-24"), ], - RAV4_TSS2.specs, + TOYOTA_RAV4_TSS2.specs, flags=ToyotaFlags.RADAR_ACC | ToyotaFlags.ANGLE_CONTROL, ) - MIRAI = ToyotaTSS2PlatformConfig( - "TOYOTA MIRAI 2021", # TSS 2.5 - ToyotaCarInfo("Toyota Mirai 2021"), + TOYOTA_MIRAI = ToyotaTSS2PlatformConfig( # TSS 2.5 + [ToyotaCarDocs("Toyota Mirai 2021")], CarSpecs(mass=4300. * CV.LB_TO_KG, wheelbase=2.91, steerRatio=14.8, tireStiffnessFactor=0.8), ) - SIENNA = PlatformConfig( - "TOYOTA SIENNA 2018", - ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED), + TOYOTA_SIENNA = PlatformConfig( + [ToyotaCarDocs("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED)], CarSpecs(mass=4590. * CV.LB_TO_KG, wheelbase=3.03, steerRatio=15.5, tireStiffnessFactor=0.444), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), flags=ToyotaFlags.NO_STOP_TIMER, @@ -280,92 +259,80 @@ class CAR(Platforms): # Lexus LEXUS_CTH = PlatformConfig( - "LEXUS CT HYBRID 2018", - ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+"), + [ToyotaCarDocs("Lexus CT Hybrid 2017-18", "Lexus Safety System+")], CarSpecs(mass=3108. * CV.LB_TO_KG, wheelbase=2.6, steerRatio=18.6, tireStiffnessFactor=0.517), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), ) LEXUS_ES = PlatformConfig( - "LEXUS ES 2018", [ - ToyotaCarInfo("Lexus ES 2017-18"), - ToyotaCarInfo("Lexus ES Hybrid 2017-18"), + ToyotaCarDocs("Lexus ES 2017-18"), + ToyotaCarDocs("Lexus ES Hybrid 2017-18"), ], CarSpecs(mass=3677. * CV.LB_TO_KG, wheelbase=2.8702, steerRatio=16.0, tireStiffnessFactor=0.444), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), ) LEXUS_ES_TSS2 = ToyotaTSS2PlatformConfig( - "LEXUS ES 2019", [ - ToyotaCarInfo("Lexus ES 2019-24"), - ToyotaCarInfo("Lexus ES Hybrid 2019-24", video_link="https://youtu.be/BZ29osRVJeg?t=12"), + ToyotaCarDocs("Lexus ES 2019-24"), + ToyotaCarDocs("Lexus ES Hybrid 2019-24", video_link="https://youtu.be/BZ29osRVJeg?t=12"), ], LEXUS_ES.specs, ) LEXUS_IS = PlatformConfig( - "LEXUS IS 2018", - ToyotaCarInfo("Lexus IS 2017-19"), + [ToyotaCarDocs("Lexus IS 2017-19")], CarSpecs(mass=3736.8 * CV.LB_TO_KG, wheelbase=2.79908, steerRatio=13.3, tireStiffnessFactor=0.444), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), flags=ToyotaFlags.UNSUPPORTED_DSU, ) LEXUS_IS_TSS2 = ToyotaTSS2PlatformConfig( - "LEXUS IS 2023", - ToyotaCarInfo("Lexus IS 2022-23"), + [ToyotaCarDocs("Lexus IS 2022-23")], LEXUS_IS.specs, ) LEXUS_NX = PlatformConfig( - "LEXUS NX 2018", [ - ToyotaCarInfo("Lexus NX 2018-19"), - ToyotaCarInfo("Lexus NX Hybrid 2018-19"), + ToyotaCarDocs("Lexus NX 2018-19"), + ToyotaCarDocs("Lexus NX Hybrid 2018-19"), ], CarSpecs(mass=4070. * CV.LB_TO_KG, wheelbase=2.66, steerRatio=14.7, tireStiffnessFactor=0.444), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), ) LEXUS_NX_TSS2 = ToyotaTSS2PlatformConfig( - "LEXUS NX 2020", [ - ToyotaCarInfo("Lexus NX 2020-21"), - ToyotaCarInfo("Lexus NX Hybrid 2020-21"), + ToyotaCarDocs("Lexus NX 2020-21"), + ToyotaCarDocs("Lexus NX Hybrid 2020-21"), ], LEXUS_NX.specs, ) LEXUS_LC_TSS2 = ToyotaTSS2PlatformConfig( - "LEXUS LC 2024", - ToyotaCarInfo("Lexus LC 2024"), + [ToyotaCarDocs("Lexus LC 2024")], CarSpecs(mass=4500. * CV.LB_TO_KG, wheelbase=2.87, steerRatio=13.0, tireStiffnessFactor=0.444), ) LEXUS_RC = PlatformConfig( - "LEXUS RC 2020", - ToyotaCarInfo("Lexus RC 2018-20"), + [ToyotaCarDocs("Lexus RC 2018-20")], LEXUS_IS.specs, dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), flags=ToyotaFlags.UNSUPPORTED_DSU, ) LEXUS_RX = PlatformConfig( - "LEXUS RX 2016", [ - ToyotaCarInfo("Lexus RX 2016", "Lexus Safety System+"), - ToyotaCarInfo("Lexus RX 2017-19"), + ToyotaCarDocs("Lexus RX 2016", "Lexus Safety System+"), + ToyotaCarDocs("Lexus RX 2017-19"), # Hybrid platforms - ToyotaCarInfo("Lexus RX Hybrid 2016", "Lexus Safety System+"), - ToyotaCarInfo("Lexus RX Hybrid 2017-19"), + ToyotaCarDocs("Lexus RX Hybrid 2016", "Lexus Safety System+"), + ToyotaCarDocs("Lexus RX Hybrid 2017-19"), ], CarSpecs(mass=4481. * CV.LB_TO_KG, wheelbase=2.79, steerRatio=16., tireStiffnessFactor=0.5533), dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'), ) LEXUS_RX_TSS2 = ToyotaTSS2PlatformConfig( - "LEXUS RX 2020", [ - ToyotaCarInfo("Lexus RX 2020-22"), - ToyotaCarInfo("Lexus RX Hybrid 2020-22"), + ToyotaCarDocs("Lexus RX 2020-22"), + ToyotaCarDocs("Lexus RX Hybrid 2020-22"), ], LEXUS_RX.specs, ) LEXUS_GS_F = PlatformConfig( - "LEXUS GS F 2016", - ToyotaCarInfo("Lexus GS F 2016"), + [ToyotaCarDocs("Lexus GS F 2016")], CarSpecs(mass=4034. * CV.LB_TO_KG, wheelbase=2.84988, steerRatio=13.3, tireStiffnessFactor=0.444), dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'), flags=ToyotaFlags.UNSUPPORTED_DSU, @@ -374,32 +341,33 @@ class CAR(Platforms): # (addr, cars, bus, 1/freq*100, vl) STATIC_DSU_MSGS = [ - (0x128, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON), 1, 3, b'\xf4\x01\x90\x83\x00\x37'), - (0x128, (CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES), 1, 3, b'\x03\x00\x20\x00\x00\x52'), - (0x141, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, - CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 1, 2, b'\x00\x00\x00\x46'), - (0x160, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, - CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 1, 7, b'\x00\x00\x08\x12\x01\x31\x9c\x51'), - (0x161, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.AVALON, CAR.PRIUS_V), + (0x128, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_AVALON), \ + 1, 3, b'\xf4\x01\x90\x83\x00\x37'), + (0x128, (CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES), 1, 3, b'\x03\x00\x20\x00\x00\x52'), + (0x141, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_AVALON, + CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 1, 2, b'\x00\x00\x00\x46'), + (0x160, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_AVALON, + CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 1, 7, b'\x00\x00\x08\x12\x01\x31\x9c\x51'), + (0x161, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_AVALON, CAR.TOYOTA_PRIUS_V), 1, 7, b'\x00\x1e\x00\x00\x00\x80\x07'), - (0X161, (CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES), 1, 7, b'\x00\x1e\x00\xd4\x00\x00\x5b'), - (0x283, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, - CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 0, 3, b'\x00\x00\x00\x00\x00\x00\x8c'), - (0x2E6, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX), 0, 3, b'\xff\xf8\x00\x08\x7f\xe0\x00\x4e'), - (0x2E7, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX), 0, 3, b'\xa8\x9c\x31\x9c\x00\x00\x00\x02'), - (0x33E, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX), 0, 20, b'\x0f\xff\x26\x40\x00\x1f\x00'), - (0x344, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, - CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 0, 5, b'\x00\x00\x01\x00\x00\x00\x00\x50'), - (0x365, (CAR.PRIUS, CAR.LEXUS_NX, CAR.HIGHLANDER), 0, 20, b'\x00\x00\x00\x80\x03\x00\x08'), - (0x365, (CAR.RAV4, CAR.RAV4H, CAR.COROLLA, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_RX, - CAR.PRIUS_V), 0, 20, b'\x00\x00\x00\x80\xfc\x00\x08'), - (0x366, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.HIGHLANDER), 0, 20, b'\x00\x00\x4d\x82\x40\x02\x00'), - (0x366, (CAR.RAV4, CAR.COROLLA, CAR.AVALON, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), + (0X161, (CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES), 1, 7, b'\x00\x1e\x00\xd4\x00\x00\x5b'), + (0x283, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_AVALON, + CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 0, 3, b'\x00\x00\x00\x00\x00\x00\x8c'), + (0x2E6, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX), 0, 3, b'\xff\xf8\x00\x08\x7f\xe0\x00\x4e'), + (0x2E7, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX), 0, 3, b'\xa8\x9c\x31\x9c\x00\x00\x00\x02'), + (0x33E, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX), 0, 20, b'\x0f\xff\x26\x40\x00\x1f\x00'), + (0x344, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_AVALON, + CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 0, 5, b'\x00\x00\x01\x00\x00\x00\x00\x50'), + (0x365, (CAR.TOYOTA_PRIUS, CAR.LEXUS_NX, CAR.TOYOTA_HIGHLANDER), 0, 20, b'\x00\x00\x00\x80\x03\x00\x08'), + (0x365, (CAR.TOYOTA_RAV4, CAR.TOYOTA_RAV4H, CAR.TOYOTA_COROLLA, CAR.TOYOTA_AVALON, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.LEXUS_RX, + CAR.TOYOTA_PRIUS_V), 0, 20, b'\x00\x00\x00\x80\xfc\x00\x08'), + (0x366, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_HIGHLANDER), 0, 20, b'\x00\x00\x4d\x82\x40\x02\x00'), + (0x366, (CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_AVALON, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 0, 20, b'\x00\x72\x07\xff\x09\xfe\x00'), - (0x470, (CAR.PRIUS, CAR.LEXUS_RX), 1, 100, b'\x00\x00\x02\x7a'), - (0x470, (CAR.HIGHLANDER, CAR.RAV4H, CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 1, 100, b'\x00\x00\x01\x79'), - (0x4CB, (CAR.PRIUS, CAR.RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.AVALON, - CAR.SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.PRIUS_V), 0, 100, b'\x0c\x00\x00\x00\x00\x00\x00\x00'), + (0x470, (CAR.TOYOTA_PRIUS, CAR.LEXUS_RX), 1, 100, b'\x00\x00\x02\x7a'), + (0x470, (CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_RAV4H, CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 1, 100, b'\x00\x00\x01\x79'), + (0x4CB, (CAR.TOYOTA_PRIUS, CAR.TOYOTA_RAV4H, CAR.LEXUS_RX, CAR.LEXUS_NX, CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_AVALON, + CAR.TOYOTA_SIENNA, CAR.LEXUS_CTH, CAR.LEXUS_ES, CAR.TOYOTA_PRIUS_V), 0, 100, b'\x0c\x00\x00\x00\x00\x00\x00\x00'), ] @@ -547,9 +515,9 @@ FW_QUERY_CONFIG = FwQueryConfig( ], non_essential_ecus={ # FIXME: On some models, abs can sometimes be missing - Ecu.abs: [CAR.RAV4, CAR.COROLLA, CAR.HIGHLANDER, CAR.SIENNA, CAR.LEXUS_IS, CAR.ALPHARD_TSS2], + Ecu.abs: [CAR.TOYOTA_RAV4, CAR.TOYOTA_COROLLA, CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_SIENNA, CAR.LEXUS_IS, CAR.TOYOTA_ALPHARD_TSS2], # On some models, the engine can show on two different addresses - Ecu.engine: [CAR.HIGHLANDER, CAR.CAMRY, CAR.COROLLA_TSS2, CAR.CHR, CAR.CHR_TSS2, CAR.LEXUS_IS, + Ecu.engine: [CAR.TOYOTA_HIGHLANDER, CAR.TOYOTA_CAMRY, CAR.TOYOTA_COROLLA_TSS2, CAR.TOYOTA_CHR, CAR.TOYOTA_CHR_TSS2, CAR.LEXUS_IS, CAR.LEXUS_IS_TSS2, CAR.LEXUS_RC, CAR.LEXUS_NX, CAR.LEXUS_NX_TSS2, CAR.LEXUS_RX, CAR.LEXUS_RX_TSS2], }, extra_ecus=[ @@ -591,7 +559,8 @@ FW_QUERY_CONFIG = FwQueryConfig( STEER_THRESHOLD = 100 # These cars have non-standard EPS torque scale factors. All others are 73 -EPS_SCALE = defaultdict(lambda: 73, {CAR.PRIUS: 66, CAR.COROLLA: 88, CAR.LEXUS_IS: 77, CAR.LEXUS_RC: 77, CAR.LEXUS_CTH: 100, CAR.PRIUS_V: 100}) +EPS_SCALE = defaultdict(lambda: 73, + {CAR.TOYOTA_PRIUS: 66, CAR.TOYOTA_COROLLA: 88, CAR.LEXUS_IS: 77, CAR.LEXUS_RC: 77, CAR.LEXUS_CTH: 100, CAR.TOYOTA_PRIUS_V: 100}) # Toyota/Lexus Safety Sense 2.0 and 2.5 TSS2_CAR = CAR.with_flags(ToyotaFlags.TSS2) diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 1b1858703d..37a4ed36b8 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -18,6 +18,7 @@ class CarController(CarControllerBase): self.CCP = CarControllerParams(CP) self.CCS = pqcan if CP.flags & VolkswagenFlags.PQ else mqbcan self.packer_pt = CANPacker(dbc_name) + self.ext_bus = CANBUS.pt if CP.networkLocation == car.CarParams.NetworkLocation.fwdCamera else CANBUS.cam self.apply_steer_last = 0 self.gra_acc_counter_last = None @@ -26,7 +27,7 @@ class CarController(CarControllerBase): self.hca_frame_timer_running = 0 self.hca_frame_same_torque = 0 - def update(self, CC, CS, ext_bus, now_nanos): + def update(self, CC, CS, now_nanos): actuators = CC.actuators hud_control = CC.hudControl can_sends = [] @@ -102,13 +103,13 @@ class CarController(CarControllerBase): # FIXME: follow the recent displayed-speed updates, also use mph_kmh toggle to fix display rounding problem? set_speed = hud_control.setSpeed * CV.MS_TO_KPH can_sends.append(self.CCS.create_acc_hud_control(self.packer_pt, CANBUS.pt, acc_hud_status, set_speed, - lead_distance)) + lead_distance, hud_control.leadDistanceBars)) # **** Stock ACC Button Controls **************************************** # gra_send_ready = self.CP.pcmCruise and CS.gra_stock_values["COUNTER"] != self.gra_acc_counter_last if gra_send_ready and (CC.cruiseControl.cancel or CC.cruiseControl.resume): - can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, + can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, self.ext_bus, CS.gra_stock_values, cancel=CC.cruiseControl.cancel, resume=CC.cruiseControl.resume)) new_actuators = actuators.copy() @@ -117,4 +118,4 @@ class CarController(CarControllerBase): self.gra_acc_counter_last = CS.gra_stock_values["COUNTER"] self.frame += 1 - return new_actuators, can_sends, self.eps_timer_soft_disable_alert + return new_actuators, can_sends diff --git a/selfdrive/car/volkswagen/fingerprints.py b/selfdrive/car/volkswagen/fingerprints.py index f6b3c49982..71aee67815 100644 --- a/selfdrive/car/volkswagen/fingerprints.py +++ b/selfdrive/car/volkswagen/fingerprints.py @@ -7,7 +7,7 @@ Ecu = car.CarParams.Ecu FW_VERSIONS = { - CAR.ARTEON_MK1: { + CAR.VOLKSWAGEN_ARTEON_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x873G0906259AH\xf1\x890001', b'\xf1\x873G0906259F \xf1\x890004', @@ -49,7 +49,7 @@ FW_VERSIONS = { b'\xf1\x875Q0907572R \xf1\x890771', ], }, - CAR.ATLAS_MK1: { + CAR.VOLKSWAGEN_ATLAS_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8703H906026AA\xf1\x899970', b'\xf1\x8703H906026AG\xf1\x899973', @@ -80,6 +80,7 @@ FW_VERSIONS = { b'\xf1\x873Q0959655BN\xf1\x890713\xf1\x82\x0e2214152212001105141122052900', b'\xf1\x873Q0959655DB\xf1\x890720\xf1\x82\x0e1114151112001105111122052900', b'\xf1\x873Q0959655DB\xf1\x890720\xf1\x82\x0e2214152212001105141122052900', + b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1114151112001105111122052J00', b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1114151112001105161122052J00', b'\xf1\x873Q0959655DM\xf1\x890732\xf1\x82\x0e1115151112001105171122052J00', ], @@ -87,6 +88,7 @@ FW_VERSIONS = { b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B60924A1', b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6G920A1', b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6M921A1', + b'\xf1\x873QF909144B \xf1\x891582\xf1\x82\x0571B6N920A1', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6080105', b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820528B6090105', ], @@ -99,7 +101,7 @@ FW_VERSIONS = { b'\xf1\x875Q0907572P \xf1\x890682', ], }, - CAR.CADDY_MK3: { + CAR.VOLKSWAGEN_CADDY_MK3: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906027T \xf1\x892363', ], @@ -110,7 +112,7 @@ FW_VERSIONS = { b'\xf1\x877N0907572C \xf1\x890211\xf1\x82\x0155', ], }, - CAR.CRAFTER_MK2: { + CAR.VOLKSWAGEN_CRAFTER_MK2: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704L906056BP\xf1\x894729', b'\xf1\x8704L906056EK\xf1\x896391', @@ -132,7 +134,7 @@ FW_VERSIONS = { b'\xf1\x872Q0907572M \xf1\x890233', ], }, - CAR.GOLF_MK7: { + CAR.VOLKSWAGEN_GOLF_MK7: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906016A \xf1\x897697', b'\xf1\x8704E906016AD\xf1\x895758', @@ -175,6 +177,7 @@ FW_VERSIONS = { b'\xf1\x875G0906259T \xf1\x890003', b'\xf1\x878V0906259H \xf1\x890002', b'\xf1\x878V0906259J \xf1\x890003', + b'\xf1\x878V0906259J \xf1\x890103', b'\xf1\x878V0906259K \xf1\x890001', b'\xf1\x878V0906259K \xf1\x890003', b'\xf1\x878V0906259P \xf1\x890001', @@ -220,6 +223,7 @@ FW_VERSIONS = { b'\xf1\x870DD300046F \xf1\x891601', b'\xf1\x870GC300012A \xf1\x891401', b'\xf1\x870GC300012A \xf1\x891403', + b'\xf1\x870GC300012M \xf1\x892301', b'\xf1\x870GC300014B \xf1\x892401', b'\xf1\x870GC300014B \xf1\x892403', b'\xf1\x870GC300014B \xf1\x892405', @@ -238,6 +242,7 @@ FW_VERSIONS = { b'\xf1\x875Q0959655AR\xf1\x890317\xf1\x82\x13141500111233003142114A2131219333313100', b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\x1314160011123300314211012230229333423100', b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\x1314160011123300314211012230229333463100', + b'\xf1\x875Q0959655BJ\xf1\x890339\xf1\x82\x13141600111233003142115A2232229333463100', b'\xf1\x875Q0959655BS\xf1\x890403\xf1\x82\x1314160011123300314240012250229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2251229333463100', b'\xf1\x875Q0959655BT\xf1\x890403\xf1\x82\x13141600111233003142404A2252229333463100', @@ -320,7 +325,7 @@ FW_VERSIONS = { b'\xf1\x875Q0907572S \xf1\x890780', ], }, - CAR.JETTA_MK7: { + CAR.VOLKSWAGEN_JETTA_MK7: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906024AK\xf1\x899937', b'\xf1\x8704E906024AS\xf1\x899912', @@ -328,6 +333,7 @@ FW_VERSIONS = { b'\xf1\x8704E906024BC\xf1\x899971', b'\xf1\x8704E906024BG\xf1\x891057', b'\xf1\x8704E906024C \xf1\x899970', + b'\xf1\x8704E906024C \xf1\x899971', b'\xf1\x8704E906024L \xf1\x895595', b'\xf1\x8704E906024L \xf1\x899970', b'\xf1\x8704E906027MS\xf1\x896223', @@ -371,7 +377,7 @@ FW_VERSIONS = { b'\xf1\x875Q0907572R \xf1\x890771', ], }, - CAR.PASSAT_MK8: { + CAR.VOLKSWAGEN_PASSAT_MK8: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8703N906026E \xf1\x892114', b'\xf1\x8704E906023AH\xf1\x893379', @@ -381,6 +387,7 @@ FW_VERSIONS = { b'\xf1\x8704L906026FP\xf1\x892012', b'\xf1\x8704L906026GA\xf1\x892013', b'\xf1\x8704L906026KD\xf1\x894798', + b'\xf1\x8705L906022A \xf1\x890827', b'\xf1\x873G0906259 \xf1\x890004', b'\xf1\x873G0906259B \xf1\x890002', b'\xf1\x873G0906264 \xf1\x890004', @@ -400,6 +407,7 @@ FW_VERSIONS = { b'\xf1\x870DL300011H \xf1\x895201', b'\xf1\x870GC300042H \xf1\x891404', b'\xf1\x870GC300043 \xf1\x892301', + b'\xf1\x870GC300046P \xf1\x892805', ], (Ecu.srs, 0x715, None): [ b'\xf1\x873Q0959655AE\xf1\x890195\xf1\x82\r56140056130012416612124111', @@ -415,6 +423,7 @@ FW_VERSIONS = { b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e5915005914001354701311542900', b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e5915005914001305701311052900', b'\xf1\x875Q0959655S \xf1\x890870\xf1\x82\x1315120011111200631145171716121691132111', + b'\xf1\x875QF959655S \xf1\x890639\xf1\x82\x13131100131300111111000120----2211114A48', ], (Ecu.eps, 0x712, None): [ b'\xf1\x873Q0909144J \xf1\x895063\xf1\x82\x0566B00611A1', @@ -441,7 +450,7 @@ FW_VERSIONS = { b'\xf1\x875Q0907572R \xf1\x890771', ], }, - CAR.PASSAT_NMS: { + CAR.VOLKSWAGEN_PASSAT_NMS: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8706K906016C \xf1\x899609', b'\xf1\x8706K906016E \xf1\x899830', @@ -463,7 +472,7 @@ FW_VERSIONS = { b'\xf1\x877N0907572C \xf1\x890211\xf1\x82\x0152', ], }, - CAR.POLO_MK6: { + CAR.VOLKSWAGEN_POLO_MK6: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704C906025H \xf1\x895177', b'\xf1\x8705C906032J \xf1\x891702', @@ -487,7 +496,7 @@ FW_VERSIONS = { b'\xf1\x872Q0907572R \xf1\x890372', ], }, - CAR.SHARAN_MK2: { + CAR.VOLKSWAGEN_SHARAN_MK2: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704L906016HE\xf1\x894635', ], @@ -498,7 +507,7 @@ FW_VERSIONS = { b'\xf1\x877N0907572C \xf1\x890211\xf1\x82\x0153', ], }, - CAR.TAOS_MK1: { + CAR.VOLKSWAGEN_TAOS_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704E906025CK\xf1\x892228', b'\xf1\x8704E906027NJ\xf1\x891445', @@ -528,7 +537,7 @@ FW_VERSIONS = { b'\xf1\x872Q0907572T \xf1\x890383', ], }, - CAR.TCROSS_MK1: { + CAR.VOLKSWAGEN_TCROSS_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704C906025AK\xf1\x897053', ], @@ -545,7 +554,7 @@ FW_VERSIONS = { b'\xf1\x872Q0907572T \xf1\x890383', ], }, - CAR.TIGUAN_MK2: { + CAR.VOLKSWAGEN_TIGUAN_MK2: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8703N906026D \xf1\x893680', b'\xf1\x8704E906024AP\xf1\x891461', @@ -575,6 +584,7 @@ FW_VERSIONS = { b'\xf1\x8709G927158GM\xf1\x893936', b'\xf1\x8709G927158GN\xf1\x893938', b'\xf1\x8709G927158HB\xf1\x894069', + b'\xf1\x8709G927158HC\xf1\x894070', b'\xf1\x870D9300043 \xf1\x895202', b'\xf1\x870DD300046K \xf1\x892302', b'\xf1\x870DL300011N \xf1\x892001', @@ -631,29 +641,37 @@ FW_VERSIONS = { b'\xf1\x872Q0907572T \xf1\x890383', ], }, - CAR.TOURAN_MK2: { + CAR.VOLKSWAGEN_TOURAN_MK2: { (Ecu.engine, 0x7e0, None): [ + b'\xf1\x8704E906025BE\xf1\x890720', + b'\xf1\x8704E906027HQ\xf1\x893746', b'\xf1\x8704L906026HM\xf1\x893017', b'\xf1\x8705E906018CQ\xf1\x890808', ], (Ecu.transmission, 0x7e1, None): [ + b'\xf1\x870CW300020A \xf1\x891936', b'\xf1\x870CW300041E \xf1\x891005', + b'\xf1\x870CW300041Q \xf1\x891606', b'\xf1\x870CW300051M \xf1\x891926', ], (Ecu.srs, 0x715, None): [ + b'\xf1\x875Q0959655AS\xf1\x890318\xf1\x82\x1336350021353335314132014730479333313100', b'\xf1\x875Q0959655AS\xf1\x890318\xf1\x82\x13363500213533353141324C4732479333313100', b'\xf1\x875Q0959655CH\xf1\x890421\xf1\x82\x1336350021353336314740025250529333613100', + b'\xf1\x875QD959655AJ\xf1\x890421\xf1\x82\x1336350021313300314240023330339333663100', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820531B0062105', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567A8090400', + b'\xf1\x875QD909144F \xf1\x891082\xf1\x82\x0521A00642A1', ], (Ecu.fwdRadar, 0x757, None): [ b'\xf1\x872Q0907572AA\xf1\x890396', b'\xf1\x873Q0907572C \xf1\x890195', + b'\xf1\x875Q0907572R \xf1\x890771', ], }, - CAR.TRANSPORTER_T61: { + CAR.VOLKSWAGEN_TRANSPORTER_T61: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8704L906056AG\xf1\x899970', b'\xf1\x8704L906056AL\xf1\x899970', @@ -685,7 +703,7 @@ FW_VERSIONS = { b'\xf1\x872Q0907572R \xf1\x890372', ], }, - CAR.TROC_MK1: { + CAR.VOLKSWAGEN_TROC_MK1: { (Ecu.engine, 0x7e0, None): [ b'\xf1\x8705E906018AT\xf1\x899640', b'\xf1\x8705E906018CK\xf1\x890863', @@ -990,7 +1008,9 @@ FW_VERSIONS = { b'\xf1\x8704L906026HT\xf1\x893617', b'\xf1\x8705E906018DJ\xf1\x890915', b'\xf1\x8705E906018DJ\xf1\x891903', + b'\xf1\x8705L906022GM\xf1\x893411', b'\xf1\x875NA906259E \xf1\x890003', + b'\xf1\x875NA907115D \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890003', b'\xf1\x875NA907115E \xf1\x890005', b'\xf1\x8783A907115E \xf1\x890001', @@ -999,14 +1019,17 @@ FW_VERSIONS = { b'\xf1\x870D9300014S \xf1\x895201', b'\xf1\x870D9300043 \xf1\x895202', b'\xf1\x870DL300011N \xf1\x892014', + b'\xf1\x870DL300012G \xf1\x892006', b'\xf1\x870DL300012M \xf1\x892107', b'\xf1\x870DL300012N \xf1\x892110', b'\xf1\x870DL300013G \xf1\x892119', b'\xf1\x870GC300014N \xf1\x892801', + b'\xf1\x870GC300018S \xf1\x892803', b'\xf1\x870GC300019H \xf1\x892806', b'\xf1\x870GC300046Q \xf1\x892802', ], (Ecu.srs, 0x715, None): [ + b'\xf1\x873Q0959655AN\xf1\x890306\xf1\x82\r11110011110011031111310311', b'\xf1\x873Q0959655AP\xf1\x890306\xf1\x82\r11110011110011421111314211', b'\xf1\x873Q0959655BH\xf1\x890703\xf1\x82\x0e1213001211001205212111052100', b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100', @@ -1015,6 +1038,7 @@ FW_VERSIONS = { b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111', b'\xf1\x873Q0959655DJ\xf1\x890731\xf1\x82\x0e1513001511001205232113052J00', b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100010200--1121240749', + b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100010200--1121246149', ], (Ecu.eps, 0x712, None): [ b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6050405', @@ -1022,6 +1046,7 @@ FW_VERSIONS = { b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6070405', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G500', b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G600', + b'\xf1\x875TA907145F \xf1\x891063\xf1\x82\x0025T6BA25OM', b'\xf1\x875TA907145F \xf1\x891063\xf1\x82\x002LT61A2LOM', ], (Ecu.fwdRadar, 0x757, None): [ @@ -1040,6 +1065,7 @@ FW_VERSIONS = { b'\xf1\x8704E906027HD\xf1\x893742', b'\xf1\x8704E906027MH\xf1\x894786', b'\xf1\x8704L906021DT\xf1\x898127', + b'\xf1\x8704L906021ER\xf1\x898361', b'\xf1\x8704L906026BP\xf1\x897608', b'\xf1\x8704L906026BS\xf1\x891541', b'\xf1\x875G0906259C \xf1\x890002', @@ -1049,6 +1075,7 @@ FW_VERSIONS = { b'\xf1\x870CW300041N \xf1\x891605', b'\xf1\x870CW300043B \xf1\x891601', b'\xf1\x870CW300043P \xf1\x891605', + b'\xf1\x870D9300012H \xf1\x894518', b'\xf1\x870D9300041C \xf1\x894936', b'\xf1\x870D9300041H \xf1\x895220', b'\xf1\x870D9300041J \xf1\x894902', @@ -1074,6 +1101,7 @@ FW_VERSIONS = { b'\xf1\x875QD909144E \xf1\x891081\xf1\x82\x0521T00503A1', ], (Ecu.fwdRadar, 0x757, None): [ + b'\xf1\x875Q0907567P \xf1\x890100\xf1\x82\x0101', b'\xf1\x875Q0907572D \xf1\x890304\xf1\x82\x0101', b'\xf1\x875Q0907572F \xf1\x890400\xf1\x82\x0101', b'\xf1\x875Q0907572H \xf1\x890620', diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 43a8bcdddc..83a8cde9a8 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -19,8 +19,6 @@ class CarInterface(CarInterfaceBase): self.ext_bus = CANBUS.cam self.cp_ext = self.cp_cam - self.eps_timer_soft_disable_alert = False - @staticmethod def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs): ret.carName = "volkswagen" @@ -126,13 +124,10 @@ class CarInterface(CarInterfaceBase): if c.enabled and ret.vEgo < self.CP.minEnableSpeed: events.add(EventName.speedTooLow) - if self.eps_timer_soft_disable_alert: + if self.CC.eps_timer_soft_disable_alert: events.add(EventName.steerTimeLimit) ret.events = events.to_msg() return ret - def apply(self, c, now_nanos): - new_actuators, can_sends, self.eps_timer_soft_disable_alert = self.CC.update(c, self.CS, self.ext_bus, now_nanos) - return new_actuators, can_sends diff --git a/selfdrive/car/volkswagen/mqbcan.py b/selfdrive/car/volkswagen/mqbcan.py index 787c7de530..6043533acf 100644 --- a/selfdrive/car/volkswagen/mqbcan.py +++ b/selfdrive/car/volkswagen/mqbcan.py @@ -125,11 +125,11 @@ def create_acc_accel_control(packer, bus, acc_type, acc_enabled, accel, acc_cont return commands -def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance): +def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance, distance): values = { "ACC_Status_Anzeige": acc_hud_status, "ACC_Wunschgeschw_02": set_speed if set_speed < 250 else 327.36, - "ACC_Gesetzte_Zeitluecke": 3, + "ACC_Gesetzte_Zeitluecke": distance + 2, "ACC_Display_Prio": 3, "ACC_Abstandsindex": lead_distance, } diff --git a/selfdrive/car/volkswagen/pqcan.py b/selfdrive/car/volkswagen/pqcan.py index f42c3cf781..307aaaa2a7 100644 --- a/selfdrive/car/volkswagen/pqcan.py +++ b/selfdrive/car/volkswagen/pqcan.py @@ -91,10 +91,10 @@ def create_acc_accel_control(packer, bus, acc_type, acc_enabled, accel, acc_cont return commands -def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance): +def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance, distance): values = { "ACA_StaACC": acc_hud_status, - "ACA_Zeitluecke": 2, + "ACA_Zeitluecke": distance + 2, "ACA_V_Wunsch": set_speed, "ACA_gemZeitl": lead_distance, "ACA_PrioDisp": 3, diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index a45ddf431f..ab4008d643 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -7,7 +7,7 @@ from panda.python import uds from opendbc.can.can_define import CANDefine from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms -from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column, \ +from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \ Device from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16 @@ -158,7 +158,7 @@ class Footnote(Enum): @dataclass -class VWCarInfo(CarInfo): +class VWCarDocs(CarDocs): package: str = "Adaptive Cruise Control (ACC) & Lane Assist" car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.j533])) @@ -167,7 +167,7 @@ class VWCarInfo(CarInfo): if "SKODA" in CP.carFingerprint: self.footnotes.append(Footnote.SKODA_HEATED_WINDSHIELD) - if CP.carFingerprint in (CAR.CRAFTER_MK2, CAR.TRANSPORTER_T61): + if CP.carFingerprint in (CAR.VOLKSWAGEN_CRAFTER_MK2, CAR.VOLKSWAGEN_TRANSPORTER_T61): self.car_parts = CarParts([Device.threex_angled_mount, CarHarness.j533]) @@ -177,200 +177,172 @@ class VWCarInfo(CarInfo): # Exception: SEAT Leon and SEAT Ateca share a chassis code class CAR(Platforms): - ARTEON_MK1 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN ARTEON 1ST GEN", # Chassis AN + VOLKSWAGEN_ARTEON_MK1 = VolkswagenMQBPlatformConfig( # Chassis AN [ - VWCarInfo("Volkswagen Arteon 2018-23", video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen Arteon R 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen Arteon eHybrid 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen CC 2018-22", video_link="https://youtu.be/FAomFKPFlDA"), + VWCarDocs("Volkswagen Arteon 2018-23", video_link="https://youtu.be/FAomFKPFlDA"), + VWCarDocs("Volkswagen Arteon R 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), + VWCarDocs("Volkswagen Arteon eHybrid 2020-23", video_link="https://youtu.be/FAomFKPFlDA"), + VWCarDocs("Volkswagen CC 2018-22", video_link="https://youtu.be/FAomFKPFlDA"), ], VolkswagenCarSpecs(mass=1733, wheelbase=2.84), ) - ATLAS_MK1 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN ATLAS 1ST GEN", # Chassis CA + VOLKSWAGEN_ATLAS_MK1 = VolkswagenMQBPlatformConfig( # Chassis CA [ - VWCarInfo("Volkswagen Atlas 2018-23"), - VWCarInfo("Volkswagen Atlas Cross Sport 2020-22"), - VWCarInfo("Volkswagen Teramont 2018-22"), - VWCarInfo("Volkswagen Teramont Cross Sport 2021-22"), - VWCarInfo("Volkswagen Teramont X 2021-22"), + VWCarDocs("Volkswagen Atlas 2018-23"), + VWCarDocs("Volkswagen Atlas Cross Sport 2020-22"), + VWCarDocs("Volkswagen Teramont 2018-22"), + VWCarDocs("Volkswagen Teramont Cross Sport 2021-22"), + VWCarDocs("Volkswagen Teramont X 2021-22"), ], VolkswagenCarSpecs(mass=2011, wheelbase=2.98), ) - CADDY_MK3 = VolkswagenPQPlatformConfig( - "VOLKSWAGEN CADDY 3RD GEN", # Chassis 2K + VOLKSWAGEN_CADDY_MK3 = VolkswagenPQPlatformConfig( # Chassis 2K [ - VWCarInfo("Volkswagen Caddy 2019"), - VWCarInfo("Volkswagen Caddy Maxi 2019"), + VWCarDocs("Volkswagen Caddy 2019"), + VWCarDocs("Volkswagen Caddy Maxi 2019"), ], VolkswagenCarSpecs(mass=1613, wheelbase=2.6, minSteerSpeed=21 * CV.KPH_TO_MS), ) - CRAFTER_MK2 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN CRAFTER 2ND GEN", # Chassis SY/SZ + VOLKSWAGEN_CRAFTER_MK2 = VolkswagenMQBPlatformConfig( # Chassis SY/SZ [ - VWCarInfo("Volkswagen Crafter 2017-23", video_link="https://youtu.be/4100gLeabmo"), - VWCarInfo("Volkswagen e-Crafter 2018-23", video_link="https://youtu.be/4100gLeabmo"), - VWCarInfo("Volkswagen Grand California 2019-23", video_link="https://youtu.be/4100gLeabmo"), - VWCarInfo("MAN TGE 2017-23", video_link="https://youtu.be/4100gLeabmo"), - VWCarInfo("MAN eTGE 2020-23", video_link="https://youtu.be/4100gLeabmo"), + VWCarDocs("Volkswagen Crafter 2017-23", video_link="https://youtu.be/4100gLeabmo"), + VWCarDocs("Volkswagen e-Crafter 2018-23", video_link="https://youtu.be/4100gLeabmo"), + VWCarDocs("Volkswagen Grand California 2019-23", video_link="https://youtu.be/4100gLeabmo"), + VWCarDocs("MAN TGE 2017-23", video_link="https://youtu.be/4100gLeabmo"), + VWCarDocs("MAN eTGE 2020-23", video_link="https://youtu.be/4100gLeabmo"), ], VolkswagenCarSpecs(mass=2100, wheelbase=3.64, minSteerSpeed=50 * CV.KPH_TO_MS), ) - GOLF_MK7 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN GOLF 7TH GEN", # Chassis 5G/AU/BA/BE + VOLKSWAGEN_GOLF_MK7 = VolkswagenMQBPlatformConfig( # Chassis 5G/AU/BA/BE [ - VWCarInfo("Volkswagen e-Golf 2014-20"), - VWCarInfo("Volkswagen Golf 2015-20", auto_resume=False), - VWCarInfo("Volkswagen Golf Alltrack 2015-19", auto_resume=False), - VWCarInfo("Volkswagen Golf GTD 2015-20"), - VWCarInfo("Volkswagen Golf GTE 2015-20"), - VWCarInfo("Volkswagen Golf GTI 2015-21", auto_resume=False), - VWCarInfo("Volkswagen Golf R 2015-19"), - VWCarInfo("Volkswagen Golf SportsVan 2015-20"), + VWCarDocs("Volkswagen e-Golf 2014-20"), + VWCarDocs("Volkswagen Golf 2015-20", auto_resume=False), + VWCarDocs("Volkswagen Golf Alltrack 2015-19", auto_resume=False), + VWCarDocs("Volkswagen Golf GTD 2015-20"), + VWCarDocs("Volkswagen Golf GTE 2015-20"), + VWCarDocs("Volkswagen Golf GTI 2015-21", auto_resume=False), + VWCarDocs("Volkswagen Golf R 2015-19"), + VWCarDocs("Volkswagen Golf SportsVan 2015-20"), ], VolkswagenCarSpecs(mass=1397, wheelbase=2.62), ) - JETTA_MK7 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN JETTA 7TH GEN", # Chassis BU + VOLKSWAGEN_JETTA_MK7 = VolkswagenMQBPlatformConfig( # Chassis BU [ - VWCarInfo("Volkswagen Jetta 2018-24"), - VWCarInfo("Volkswagen Jetta GLI 2021-24"), + VWCarDocs("Volkswagen Jetta 2018-24"), + VWCarDocs("Volkswagen Jetta GLI 2021-24"), ], VolkswagenCarSpecs(mass=1328, wheelbase=2.71), ) - PASSAT_MK8 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN PASSAT 8TH GEN", # Chassis 3G + VOLKSWAGEN_PASSAT_MK8 = VolkswagenMQBPlatformConfig( # Chassis 3G [ - VWCarInfo("Volkswagen Passat 2015-22", footnotes=[Footnote.PASSAT]), - VWCarInfo("Volkswagen Passat Alltrack 2015-22"), - VWCarInfo("Volkswagen Passat GTE 2015-22"), + VWCarDocs("Volkswagen Passat 2015-22", footnotes=[Footnote.PASSAT]), + VWCarDocs("Volkswagen Passat Alltrack 2015-22"), + VWCarDocs("Volkswagen Passat GTE 2015-22"), ], VolkswagenCarSpecs(mass=1551, wheelbase=2.79), ) - PASSAT_NMS = VolkswagenPQPlatformConfig( - "VOLKSWAGEN PASSAT NMS", # Chassis A3 - VWCarInfo("Volkswagen Passat NMS 2017-22"), + VOLKSWAGEN_PASSAT_NMS = VolkswagenPQPlatformConfig( # Chassis A3 + [VWCarDocs("Volkswagen Passat NMS 2017-22")], VolkswagenCarSpecs(mass=1503, wheelbase=2.80, minSteerSpeed=50*CV.KPH_TO_MS, minEnableSpeed=20*CV.KPH_TO_MS), ) - POLO_MK6 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN POLO 6TH GEN", # Chassis AW + VOLKSWAGEN_POLO_MK6 = VolkswagenMQBPlatformConfig( # Chassis AW [ - VWCarInfo("Volkswagen Polo 2018-23", footnotes=[Footnote.VW_MQB_A0]), - VWCarInfo("Volkswagen Polo GTI 2018-23", footnotes=[Footnote.VW_MQB_A0]), + VWCarDocs("Volkswagen Polo 2018-23", footnotes=[Footnote.VW_MQB_A0]), + VWCarDocs("Volkswagen Polo GTI 2018-23", footnotes=[Footnote.VW_MQB_A0]), ], VolkswagenCarSpecs(mass=1230, wheelbase=2.55), ) - SHARAN_MK2 = VolkswagenPQPlatformConfig( - "VOLKSWAGEN SHARAN 2ND GEN", # Chassis 7N + VOLKSWAGEN_SHARAN_MK2 = VolkswagenPQPlatformConfig( # Chassis 7N [ - VWCarInfo("Volkswagen Sharan 2018-22"), - VWCarInfo("SEAT Alhambra 2018-20"), + VWCarDocs("Volkswagen Sharan 2018-22"), + VWCarDocs("SEAT Alhambra 2018-20"), ], VolkswagenCarSpecs(mass=1639, wheelbase=2.92, minSteerSpeed=50*CV.KPH_TO_MS), ) - TAOS_MK1 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN TAOS 1ST GEN", # Chassis B2 - VWCarInfo("Volkswagen Taos 2022-23"), + VOLKSWAGEN_TAOS_MK1 = VolkswagenMQBPlatformConfig( # Chassis B2 + [VWCarDocs("Volkswagen Taos 2022-23")], VolkswagenCarSpecs(mass=1498, wheelbase=2.69), ) - TCROSS_MK1 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN T-CROSS 1ST GEN", # Chassis C1 - VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_MQB_A0]), + VOLKSWAGEN_TCROSS_MK1 = VolkswagenMQBPlatformConfig( # Chassis C1 + [VWCarDocs("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_MQB_A0])], VolkswagenCarSpecs(mass=1150, wheelbase=2.60), ) - TIGUAN_MK2 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN TIGUAN 2ND GEN", # Chassis AD/BW + VOLKSWAGEN_TIGUAN_MK2 = VolkswagenMQBPlatformConfig( # Chassis AD/BW [ - VWCarInfo("Volkswagen Tiguan 2018-24"), - VWCarInfo("Volkswagen Tiguan eHybrid 2021-23"), + VWCarDocs("Volkswagen Tiguan 2018-24"), + VWCarDocs("Volkswagen Tiguan eHybrid 2021-23"), ], VolkswagenCarSpecs(mass=1715, wheelbase=2.74), ) - TOURAN_MK2 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN TOURAN 2ND GEN", # Chassis 1T - VWCarInfo("Volkswagen Touran 2016-23"), + VOLKSWAGEN_TOURAN_MK2 = VolkswagenMQBPlatformConfig( # Chassis 1T + [VWCarDocs("Volkswagen Touran 2016-23")], VolkswagenCarSpecs(mass=1516, wheelbase=2.79), ) - TRANSPORTER_T61 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN TRANSPORTER T6.1", # Chassis 7H/7L + VOLKSWAGEN_TRANSPORTER_T61 = VolkswagenMQBPlatformConfig( # Chassis 7H/7L [ - VWCarInfo("Volkswagen Caravelle 2020"), - VWCarInfo("Volkswagen California 2021-23"), + VWCarDocs("Volkswagen Caravelle 2020"), + VWCarDocs("Volkswagen California 2021-23"), ], VolkswagenCarSpecs(mass=1926, wheelbase=3.00, minSteerSpeed=14.0), ) - TROC_MK1 = VolkswagenMQBPlatformConfig( - "VOLKSWAGEN T-ROC 1ST GEN", # Chassis A1 - VWCarInfo("Volkswagen T-Roc 2018-22", footnotes=[Footnote.VW_MQB_A0]), + VOLKSWAGEN_TROC_MK1 = VolkswagenMQBPlatformConfig( # Chassis A1 + [VWCarDocs("Volkswagen T-Roc 2018-22", footnotes=[Footnote.VW_MQB_A0])], VolkswagenCarSpecs(mass=1413, wheelbase=2.63), ) - AUDI_A3_MK3 = VolkswagenMQBPlatformConfig( - "AUDI A3 3RD GEN", # Chassis 8V/FF + AUDI_A3_MK3 = VolkswagenMQBPlatformConfig( # Chassis 8V/FF [ - VWCarInfo("Audi A3 2014-19"), - VWCarInfo("Audi A3 Sportback e-tron 2017-18"), - VWCarInfo("Audi RS3 2018"), - VWCarInfo("Audi S3 2015-17"), + VWCarDocs("Audi A3 2014-19"), + VWCarDocs("Audi A3 Sportback e-tron 2017-18"), + VWCarDocs("Audi RS3 2018"), + VWCarDocs("Audi S3 2015-17"), ], VolkswagenCarSpecs(mass=1335, wheelbase=2.61), ) - AUDI_Q2_MK1 = VolkswagenMQBPlatformConfig( - "AUDI Q2 1ST GEN", # Chassis GA - VWCarInfo("Audi Q2 2018"), + AUDI_Q2_MK1 = VolkswagenMQBPlatformConfig( # Chassis GA + [VWCarDocs("Audi Q2 2018")], VolkswagenCarSpecs(mass=1205, wheelbase=2.61), ) - AUDI_Q3_MK2 = VolkswagenMQBPlatformConfig( - "AUDI Q3 2ND GEN", # Chassis 8U/F3/FS - VWCarInfo("Audi Q3 2019-23"), + AUDI_Q3_MK2 = VolkswagenMQBPlatformConfig( # Chassis 8U/F3/FS + [VWCarDocs("Audi Q3 2019-23")], VolkswagenCarSpecs(mass=1623, wheelbase=2.68), ) - SEAT_ATECA_MK1 = VolkswagenMQBPlatformConfig( - "SEAT ATECA 1ST GEN", # Chassis 5F - VWCarInfo("SEAT Ateca 2018"), + SEAT_ATECA_MK1 = VolkswagenMQBPlatformConfig( # Chassis 5F + [VWCarDocs("SEAT Ateca 2018")], VolkswagenCarSpecs(mass=1900, wheelbase=2.64), ) - SEAT_LEON_MK3 = VolkswagenMQBPlatformConfig( - "SEAT LEON 3RD GEN", # Chassis 5F - VWCarInfo("SEAT Leon 2014-20"), + SEAT_LEON_MK3 = VolkswagenMQBPlatformConfig( # Chassis 5F + [VWCarDocs("SEAT Leon 2014-20")], VolkswagenCarSpecs(mass=1227, wheelbase=2.64), ) - SKODA_FABIA_MK4 = VolkswagenMQBPlatformConfig( - "SKODA FABIA 4TH GEN", # Chassis PJ - VWCarInfo("Škoda Fabia 2022-23", footnotes=[Footnote.VW_MQB_A0]), + SKODA_FABIA_MK4 = VolkswagenMQBPlatformConfig( # Chassis PJ + [VWCarDocs("Škoda Fabia 2022-23", footnotes=[Footnote.VW_MQB_A0])], VolkswagenCarSpecs(mass=1266, wheelbase=2.56), ) - SKODA_KAMIQ_MK1 = VolkswagenMQBPlatformConfig( - "SKODA KAMIQ 1ST GEN", # Chassis NW - VWCarInfo("Škoda Kamiq 2021-23", footnotes=[Footnote.VW_MQB_A0, Footnote.KAMIQ]), + SKODA_KAMIQ_MK1 = VolkswagenMQBPlatformConfig( # Chassis NW + [VWCarDocs("Škoda Kamiq 2021-23", footnotes=[Footnote.VW_MQB_A0, Footnote.KAMIQ])], VolkswagenCarSpecs(mass=1265, wheelbase=2.66), ) - SKODA_KAROQ_MK1 = VolkswagenMQBPlatformConfig( - "SKODA KAROQ 1ST GEN", # Chassis NU - VWCarInfo("Škoda Karoq 2019-23"), + SKODA_KAROQ_MK1 = VolkswagenMQBPlatformConfig( # Chassis NU + [VWCarDocs("Škoda Karoq 2019-23")], VolkswagenCarSpecs(mass=1278, wheelbase=2.66), ) - SKODA_KODIAQ_MK1 = VolkswagenMQBPlatformConfig( - "SKODA KODIAQ 1ST GEN", # Chassis NS - VWCarInfo("Škoda Kodiaq 2017-23"), + SKODA_KODIAQ_MK1 = VolkswagenMQBPlatformConfig( # Chassis NS + [VWCarDocs("Škoda Kodiaq 2017-23")], VolkswagenCarSpecs(mass=1569, wheelbase=2.79), ) - SKODA_OCTAVIA_MK3 = VolkswagenMQBPlatformConfig( - "SKODA OCTAVIA 3RD GEN", # Chassis NE + SKODA_OCTAVIA_MK3 = VolkswagenMQBPlatformConfig( # Chassis NE [ - VWCarInfo("Škoda Octavia 2015-19"), - VWCarInfo("Škoda Octavia RS 2016"), + VWCarDocs("Škoda Octavia 2015-19"), + VWCarDocs("Škoda Octavia RS 2016"), ], VolkswagenCarSpecs(mass=1388, wheelbase=2.68), ) - SKODA_SCALA_MK1 = VolkswagenMQBPlatformConfig( - "SKODA SCALA 1ST GEN", # Chassis NW - VWCarInfo("Škoda Scala 2020-23", footnotes=[Footnote.VW_MQB_A0]), + SKODA_SCALA_MK1 = VolkswagenMQBPlatformConfig( # Chassis NW + [VWCarDocs("Škoda Scala 2020-23", footnotes=[Footnote.VW_MQB_A0])], VolkswagenCarSpecs(mass=1192, wheelbase=2.65), ) - SKODA_SUPERB_MK3 = VolkswagenMQBPlatformConfig( - "SKODA SUPERB 3RD GEN", # Chassis 3V/NP - VWCarInfo("Škoda Superb 2015-22"), + SKODA_SUPERB_MK3 = VolkswagenMQBPlatformConfig( # Chassis 3V/NP + [VWCarDocs("Škoda Superb 2015-22")], VolkswagenCarSpecs(mass=1505, wheelbase=2.84), ) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index e4f2542ea5..e6f91130b9 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -12,6 +12,7 @@ from cereal.visionipc import VisionIpcClient, VisionStreamType from openpilot.common.conversions import Conversions as CV +from openpilot.common.git import get_short_branch from openpilot.common.numpy_fast import clip from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper, DT_CTRL @@ -30,7 +31,6 @@ from openpilot.selfdrive.controls.lib.longcontrol import LongControl from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel from openpilot.system.hardware import HARDWARE -from openpilot.system.version import get_short_branch SOFT_DISABLE_TIME = 3 # seconds LDW_MIN_SPEED = 31 * CV.MPH_TO_MS @@ -142,10 +142,10 @@ class Controls: self.current_alert_types = [ET.PERMANENT] self.logged_comm_issue = None self.not_running_prev = None - self.last_actuators = car.CarControl.Actuators.new_message() self.steer_limited = False self.desired_curvature = 0.0 self.experimental_mode = False + self.personality = self.read_personality_param() self.v_cruise_helper = VCruiseHelper(self.CP) self.recalibrating_seen = False @@ -620,7 +620,7 @@ class Controls: undershooting = abs(lac_log.desiredLateralAccel) / abs(1e-3 + lac_log.actualLateralAccel) > 1.2 turning = abs(lac_log.desiredLateralAccel) > 1.0 good_speed = CS.vEgo > 5 - max_torque = abs(self.last_actuators.steer) > 0.99 + max_torque = abs(actuators.steer) > 0.99 if undershooting and turning and good_speed and max_torque: lac_log.active and self.events.add(EventName.steerSaturated) elif lac_log.saturated: @@ -650,6 +650,12 @@ class Controls: cloudlog.error(f"actuators.{p} not finite {actuators.to_dict()}") setattr(actuators, p, 0.0) + # decrement personality on distance button press + if self.CP.openpilotLongitudinalControl: + if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents): + self.personality = (self.personality - 1) % 3 + self.params.put_nonblocking('LongitudinalPersonality', str(self.personality)) + return CC, lac_log def publish_logs(self, CS, start_time, CC, lac_log): @@ -680,6 +686,7 @@ class Controls: hudControl.speedVisible = self.enabled hudControl.lanesVisible = self.enabled hudControl.leadVisible = self.sm['longitudinalPlan'].hasLead + hudControl.leadDistanceBars = self.personality + 1 hudControl.rightLaneVisible = True hudControl.leftLaneVisible = True @@ -768,6 +775,7 @@ class Controls: controlsState.forceDecel = bool(force_decel) controlsState.canErrorCounter = self.card.can_rcv_cum_timeout_counter controlsState.experimentalMode = self.experimental_mode + controlsState.personality = self.personality lat_tuning = self.CP.lateralTuning.which() if self.joystick_mode: @@ -820,10 +828,17 @@ class Controls: self.CS_prev = CS + def read_personality_param(self): + try: + return int(self.params.get('LongitudinalPersonality')) + except (ValueError, TypeError): + return log.LongitudinalPersonality.standard + def params_thread(self, evt): while not evt.is_set(): self.is_metric = self.params.get_bool("IsMetric") self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl + self.personality = self.read_personality_param() if self.CP.notCar: self.joystick_mode = self.params.get_bool("JoystickDebugMode") time.sleep(0.1) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index c5228ef7f2..c6e9504f35 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -7,9 +7,9 @@ from collections.abc import Callable from cereal import log, car import cereal.messaging as messaging from openpilot.common.conversions import Conversions as CV +from openpilot.common.git import get_short_branch from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER -from openpilot.system.version import get_short_branch AlertSize = log.ControlsState.AlertSize AlertStatus = log.ControlsState.AlertStatus diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index ee65c4a69e..2dd3390bb0 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -10,8 +10,6 @@ LongCtrlState = car.CarControl.Actuators.LongControlState def long_control_state_trans(CP, active, long_control_state, v_ego, v_target, v_target_1sec, brake_pressed, cruise_standstill): - # Ignore cruise standstill if car has a gas interceptor - cruise_standstill = cruise_standstill and not CP.enableGasInterceptor accelerating = v_target_1sec > v_target planned_stop = (v_target < CP.vEgoStopping and v_target_1sec < CP.vEgoStopping and diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 2b1fd01112..6cc6e80d3d 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -2,8 +2,6 @@ import math import numpy as np from openpilot.common.numpy_fast import clip, interp -from openpilot.common.params import Params -from cereal import log import cereal.messaging as messaging from openpilot.common.conversions import Conversions as CV @@ -61,16 +59,6 @@ class LongitudinalPlanner: self.a_desired_trajectory = np.zeros(CONTROL_N) self.j_desired_trajectory = np.zeros(CONTROL_N) self.solverExecutionTime = 0.0 - self.params = Params() - self.param_read_counter = 0 - self.personality = log.LongitudinalPersonality.standard - self.read_param() - - def read_param(self): - try: - self.personality = int(self.params.get('LongitudinalPersonality')) - except (ValueError, TypeError): - self.personality = log.LongitudinalPersonality.standard @staticmethod def parse_model(model_msg, model_error): @@ -89,9 +77,6 @@ class LongitudinalPlanner: return x, v, a, j def update(self, sm): - if self.param_read_counter % 50 == 0: - self.read_param() - self.param_read_counter += 1 self.mpc.mode = 'blended' if sm['controlsState'].experimentalMode else 'acc' v_ego = sm['carState'].vEgo @@ -130,11 +115,11 @@ class LongitudinalPlanner: accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05) accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05) - self.mpc.set_weights(prev_accel_constraint, personality=self.personality) + self.mpc.set_weights(prev_accel_constraint, personality=sm['controlsState'].personality) self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1]) self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired) x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error) - self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=self.personality) + self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['controlsState'].personality) self.v_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.v_solution) self.a_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.a_solution) @@ -170,6 +155,5 @@ class LongitudinalPlanner: longitudinalPlan.fcw = self.fcw longitudinalPlan.solverExecutionTime = self.mpc.solve_time - longitudinalPlan.personality = self.personality pm.send('longitudinalPlan', plan_send) diff --git a/selfdrive/controls/lib/tests/test_latcontrol.py b/selfdrive/controls/lib/tests/test_latcontrol.py index 866270ca60..838023af72 100755 --- a/selfdrive/controls/lib/tests/test_latcontrol.py +++ b/selfdrive/controls/lib/tests/test_latcontrol.py @@ -17,7 +17,7 @@ from openpilot.common.mock.generators import generate_liveLocationKalman class TestLatControl(unittest.TestCase): - @parameterized.expand([(HONDA.CIVIC, LatControlPID), (TOYOTA.RAV4, LatControlTorque), (NISSAN.LEAF, LatControlAngle)]) + @parameterized.expand([(HONDA.HONDA_CIVIC, LatControlPID), (TOYOTA.TOYOTA_RAV4, LatControlTorque), (NISSAN.NISSAN_LEAF, LatControlAngle)]) def test_saturation(self, car_name, controller): CarInterface, CarController, CarState = interfaces[car_name] CP = CarInterface.get_non_essential_params(car_name) diff --git a/selfdrive/controls/lib/tests/test_vehicle_model.py b/selfdrive/controls/lib/tests/test_vehicle_model.py index d016e87527..c3997afdf3 100755 --- a/selfdrive/controls/lib/tests/test_vehicle_model.py +++ b/selfdrive/controls/lib/tests/test_vehicle_model.py @@ -12,7 +12,7 @@ from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel, dyn_ss_ class TestVehicleModel(unittest.TestCase): def setUp(self): - CP = CarInterface.get_non_essential_params(CAR.CIVIC) + CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC) self.VM = VehicleModel(CP) def test_round_trip_yaw_rate(self): diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 4de4208e9d..16c9e0635c 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -133,7 +133,7 @@ def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, tracks prob_y = laplacian_pdf(c.yRel, -lead.y[0], lead.yStd[0]) prob_v = laplacian_pdf(c.vRel + v_ego, lead.v[0], lead.vStd[0]) - # This is isn't exactly right, but good heuristic + # This isn't exactly right, but it's a good heuristic return prob_d * prob_y * prob_v track = max(tracks.values(), key=prob) diff --git a/selfdrive/controls/tests/test_cruise_speed.py b/selfdrive/controls/tests/test_cruise_speed.py index 76a2222e85..c46d03ad1e 100755 --- a/selfdrive/controls/tests/test_cruise_speed.py +++ b/selfdrive/controls/tests/test_cruise_speed.py @@ -5,7 +5,6 @@ import unittest from parameterized import parameterized_class from cereal import log -from openpilot.common.params import Params from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_INITIAL, IMPERIAL_INCREMENT from cereal import car from openpilot.common.conversions import Conversions as CV @@ -15,7 +14,7 @@ ButtonEvent = car.CarState.ButtonEvent ButtonType = car.CarState.ButtonEvent.Type -def run_cruise_simulation(cruise, e2e, t_end=20.): +def run_cruise_simulation(cruise, e2e, personality, t_end=20.): man = Maneuver( '', duration=t_end, @@ -26,6 +25,7 @@ def run_cruise_simulation(cruise, e2e, t_end=20.): prob_lead_values=[0.0], breakpoints=[0.], e2e=e2e, + personality=personality, ) valid, output = man.evaluate() assert valid @@ -38,12 +38,10 @@ def run_cruise_simulation(cruise, e2e, t_end=20.): [5,35])) # speed class TestCruiseSpeed(unittest.TestCase): def test_cruise_speed(self): - params = Params() - params.put("LongitudinalPersonality", str(self.personality)) print(f'Testing {self.speed} m/s') cruise_speed = float(self.speed) - simulation_steady_state = run_cruise_simulation(cruise_speed, self.e2e) + simulation_steady_state = run_cruise_simulation(cruise_speed, self.e2e, self.personality) self.assertAlmostEqual(simulation_steady_state, cruise_speed, delta=.01, msg=f'Did not reach {self.speed} m/s') diff --git a/selfdrive/controls/tests/test_following_distance.py b/selfdrive/controls/tests/test_following_distance.py index 3b31632721..f58e6383c4 100755 --- a/selfdrive/controls/tests/test_following_distance.py +++ b/selfdrive/controls/tests/test_following_distance.py @@ -3,14 +3,13 @@ import unittest import itertools from parameterized import parameterized_class -from openpilot.common.params import Params from cereal import log from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import desired_follow_distance, get_T_FOLLOW from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver -def run_following_distance_simulation(v_lead, t_end=100.0, e2e=False): +def run_following_distance_simulation(v_lead, t_end=100.0, e2e=False, personality=0): man = Maneuver( '', duration=t_end, @@ -20,6 +19,7 @@ def run_following_distance_simulation(v_lead, t_end=100.0, e2e=False): speed_lead_values=[v_lead], breakpoints=[0.], e2e=e2e, + personality=personality, ) valid, output = man.evaluate() assert valid @@ -34,10 +34,8 @@ def run_following_distance_simulation(v_lead, t_end=100.0, e2e=False): [0,10,35])) # speed class TestFollowingDistance(unittest.TestCase): def test_following_distance(self): - params = Params() - params.put("LongitudinalPersonality", str(self.personality)) v_lead = float(self.speed) - simulation_steady_state = run_following_distance_simulation(v_lead, e2e=self.e2e) + simulation_steady_state = run_following_distance_simulation(v_lead, e2e=self.e2e, personality=self.personality) correct_steady_state = desired_follow_distance(v_lead, v_lead, get_T_FOLLOW(self.personality)) err_ratio = 0.2 if self.e2e else 0.1 self.assertAlmostEqual(simulation_steady_state, correct_steady_state, delta=(err_ratio * correct_steady_state + .5)) diff --git a/selfdrive/controls/tests/test_leads.py b/selfdrive/controls/tests/test_leads.py index 268d9c47a7..a06387a087 100755 --- a/selfdrive/controls/tests/test_leads.py +++ b/selfdrive/controls/tests/test_leads.py @@ -25,7 +25,7 @@ class TestLeads(unittest.TestCase): return msgs msgs = [m for _ in range(3) for m in single_iter_pkg()] - out = replay_process_with_name("radard", msgs, fingerprint=TOYOTA.COROLLA_TSS2) + out = replay_process_with_name("radard", msgs, fingerprint=TOYOTA.TOYOTA_COROLLA_TSS2) states = [m for m in out if m.which() == "radarState"] failures = [not state.valid and len(state.radarState.radarErrors) for state in states] diff --git a/selfdrive/controls/tests/test_startup.py b/selfdrive/controls/tests/test_startup.py index 34d14fbb39..23cc96a2e4 100644 --- a/selfdrive/controls/tests/test_startup.py +++ b/selfdrive/controls/tests/test_startup.py @@ -39,12 +39,12 @@ CX5_FW_VERSIONS = [ # TODO: test EventName.startup for release branches # officially supported car - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS, "toyota"), - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS, "toyota"), + (EventName.startupMaster, TOYOTA.TOYOTA_COROLLA, COROLLA_FW_VERSIONS, "toyota"), + (EventName.startupMaster, TOYOTA.TOYOTA_COROLLA, COROLLA_FW_VERSIONS, "toyota"), # dashcamOnly car - (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS, "mazda"), - (EventName.startupNoControl, MAZDA.CX5, CX5_FW_VERSIONS, "mazda"), + (EventName.startupNoControl, MAZDA.MAZDA_CX5, CX5_FW_VERSIONS, "mazda"), + (EventName.startupNoControl, MAZDA.MAZDA_CX5, CX5_FW_VERSIONS, "mazda"), # unrecognized car with no fw (EventName.startupNoFw, None, None, ""), @@ -55,8 +55,8 @@ CX5_FW_VERSIONS = [ (EventName.startupNoCar, None, COROLLA_FW_VERSIONS[:1], "toyota"), # fuzzy match - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), - (EventName.startupMaster, TOYOTA.COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), + (EventName.startupMaster, TOYOTA.TOYOTA_COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), + (EventName.startupMaster, TOYOTA.TOYOTA_COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), ]) def test_startup_alert(expected_event, car_model, fw_versions, brand): controls_sock = messaging.sub_sock("controlsState") diff --git a/selfdrive/debug/cycle_alerts.py b/selfdrive/debug/cycle_alerts.py index 42561f70f0..db845ed58f 100755 --- a/selfdrive/debug/cycle_alerts.py +++ b/selfdrive/debug/cycle_alerts.py @@ -52,7 +52,7 @@ def cycle_alerts(duration=200, is_metric=False): cameras = ['roadCameraState', 'wideRoadCameraState', 'driverCameraState'] CS = car.CarState.new_message() - CP = CarInterface.get_non_essential_params("HONDA CIVIC 2016") + CP = CarInterface.get_non_essential_params("CIVIC") sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'liveLocationKalman', 'managerState'] + cameras) diff --git a/selfdrive/debug/dump_car_info.py b/selfdrive/debug/dump_car_docs.py similarity index 64% rename from selfdrive/debug/dump_car_info.py rename to selfdrive/debug/dump_car_docs.py index 6af328926b..f09c602cff 100755 --- a/selfdrive/debug/dump_car_info.py +++ b/selfdrive/debug/dump_car_docs.py @@ -2,12 +2,12 @@ import argparse import pickle -from openpilot.selfdrive.car.docs import get_all_car_info +from openpilot.selfdrive.car.docs import get_all_car_docs -def dump_car_info(path): +def dump_car_docs(path): with open(path, 'wb') as f: - pickle.dump(get_all_car_info(), f) + pickle.dump(get_all_car_docs(), f) print(f'Dumping car info to {path}') @@ -15,4 +15,4 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--path", required=True) args = parser.parse_args() - dump_car_info(args.path) + dump_car_docs(args.path) diff --git a/selfdrive/debug/print_docs_diff.py b/selfdrive/debug/print_docs_diff.py index 3d35532496..7ef89a6eca 100755 --- a/selfdrive/debug/print_docs_diff.py +++ b/selfdrive/debug/print_docs_diff.py @@ -4,7 +4,7 @@ from collections import defaultdict import difflib import pickle -from openpilot.selfdrive.car.docs import get_all_car_info +from openpilot.selfdrive.car.docs import get_all_car_docs from openpilot.selfdrive.car.docs_definitions import Column FOOTNOTE_TAG = "{}" @@ -17,7 +17,7 @@ COLUMN_HEADER = "|---|---|---|{}|".format("|".join([":---:"] * (len(Column) - 3) ARROW_SYMBOL = "➡️" -def load_base_car_info(path): +def load_base_car_docs(path): with open(path, "rb") as f: return pickle.load(f) @@ -57,31 +57,31 @@ def format_row(builder): return "|" + "|".join(builder) + "|" -def print_car_info_diff(path): - base_car_info = defaultdict(list) - new_car_info = defaultdict(list) +def print_car_docs_diff(path): + base_car_docs = defaultdict(list) + new_car_docs = defaultdict(list) - for car in load_base_car_info(path): - base_car_info[car.car_fingerprint].append(car) - for car in get_all_car_info(): - new_car_info[car.car_fingerprint].append(car) + for car in load_base_car_docs(path): + base_car_docs[car.car_fingerprint].append(car) + for car in get_all_car_docs(): + new_car_docs[car.car_fingerprint].append(car) # Add new platforms to base cars so we can detect additions and removals in one pass - base_car_info.update({car: [] for car in new_car_info if car not in base_car_info}) + base_car_docs.update({car: [] for car in new_car_docs if car not in base_car_docs}) changes = defaultdict(list) - for base_car_model, base_cars in base_car_info.items(): + for base_car_model, base_cars in base_car_docs.items(): # Match car info changes, and get additions and removals - new_cars = new_car_info[base_car_model] + new_cars = new_car_docs[base_car_model] car_changes, car_additions, car_removals = match_cars(base_cars, new_cars) # Removals - for car_info in car_removals: - changes["removals"].append(format_row([car_info.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) + for car_docs in car_removals: + changes["removals"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) # Additions - for car_info in car_additions: - changes["additions"].append(format_row([car_info.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) + for car_docs in car_additions: + changes["additions"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) for new_car, base_car in car_changes: # Column changes @@ -117,4 +117,4 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--path", required=True) args = parser.parse_args() - print_car_info_diff(args.path) + print_car_docs_diff(args.path) diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/selfdrive/debug/test_fw_query_on_routes.py index cc6fc2ae17..3c5733520e 100755 --- a/selfdrive/debug/test_fw_query_on_routes.py +++ b/selfdrive/debug/test_fw_query_on_routes.py @@ -9,6 +9,7 @@ from tqdm import tqdm from openpilot.tools.lib.logreader import LogReader, ReadMode from openpilot.tools.lib.route import SegmentRange from openpilot.selfdrive.car.car_helpers import interface_names +from openpilot.selfdrive.car.fingerprints import MIGRATION from openpilot.selfdrive.car.fw_versions import VERSIONS, match_fw_to_car @@ -17,11 +18,6 @@ SUPPORTED_BRANDS = VERSIONS.keys() SUPPORTED_CARS = [brand for brand in SUPPORTED_BRANDS for brand in interface_names[brand]] UNKNOWN_BRAND = "unknown" -try: - from xx.pipeline.lib.fingerprint import MIGRATION -except ImportError: - MIGRATION = {} - if __name__ == "__main__": parser = argparse.ArgumentParser(description='Run FW fingerprint on Qlog of route or list of routes') parser.add_argument('route', help='Route or file with list of routes') diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index 24dceaaf08..f30b81861a 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -16,9 +16,10 @@ from openpilot.selfdrive.manager.process import ensure_running from openpilot.selfdrive.manager.process_config import managed_processes from openpilot.selfdrive.athena.registration import register, UNREGISTERED_DONGLE_ID from openpilot.common.swaglog import cloudlog, add_file_handler -from openpilot.system.version import is_dirty, get_commit, get_version, get_origin, get_short_branch, \ +from openpilot.common.git import get_commit, get_origin, get_short_branch, get_commit_date +from openpilot.system.version import is_dirty, get_version, \ get_normalized_origin, terms_version, training_version, \ - is_tested_branch, is_release_branch, get_commit_date + is_tested_branch, is_release_branch diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 4f292917fd..8b616b7874 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -69,11 +69,12 @@ procs = [ PythonProcess("deleter", "system.loggerd.deleter", always_run), PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)), PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), + #PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI), PythonProcess("navd", "selfdrive.navd.navd", only_onroad), PythonProcess("pandad", "selfdrive.boardd.pandad", always_run), PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI), - PythonProcess("pigeond", "system.sensord.pigeond", ublox, enabled=TICI), + PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI), PythonProcess("plannerd", "selfdrive.controls.plannerd", only_onroad), PythonProcess("radard", "selfdrive.controls.radard", only_onroad), PythonProcess("thermald", "selfdrive.thermald.thermald", always_run), diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index e086b8aaf8..c3b3918903 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -13,6 +13,7 @@ from openpilot.common.swaglog import cloudlog from openpilot.common.params import Params from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.realtime import config_realtime_process +from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.common.transformations.model import get_warp_matrix from openpilot.selfdrive import sentry from openpilot.selfdrive.car.car_helpers import get_demo_car_params @@ -153,7 +154,7 @@ def main(demo=False): # messaging pm = PubMaster(["modelV2", "cameraOdometry"]) - sm = SubMaster(["carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "navModel", "navInstruction", "carControl"]) + sm = SubMaster(["deviceState", "carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "navModel", "navInstruction", "carControl"]) publish_state = PublishState() params = Params() @@ -225,10 +226,11 @@ def main(demo=False): is_rhd = sm["driverMonitoringState"].isRHD frame_id = sm["roadCameraState"].frameId lateral_control_params = np.array([sm["carState"].vEgo, steer_delay], dtype=np.float32) - if sm.updated["liveCalibration"]: + if sm.updated["liveCalibration"] and sm.seen['roadCameraState'] and sm.seen['deviceState']: device_from_calib_euler = np.array(sm["liveCalibration"].rpyCalib, dtype=np.float32) - model_transform_main = get_warp_matrix(device_from_calib_euler, main_wide_camera, False).astype(np.float32) - model_transform_extra = get_warp_matrix(device_from_calib_euler, True, True).astype(np.float32) + dc = DEVICE_CAMERAS[(str(sm['deviceState'].deviceType), str(sm['roadCameraState'].sensor))] + model_transform_main = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if main_wide_camera else dc.fcam.intrinsics, False).astype(np.float32) + model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics, True).astype(np.float32) live_calib_seen = True traffic_convention = np.zeros(2) diff --git a/selfdrive/modeld/models/supercombo.onnx b/selfdrive/modeld/models/supercombo.onnx index 68e39514d9..7991fef662 100644 --- a/selfdrive/modeld/models/supercombo.onnx +++ b/selfdrive/modeld/models/supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd4b0cc83d5ff275ee77ec430ea686603ad50fd6ad874f599ea6e95b123afc3e -size 48193749 +oid sha256:b4fb2cec9ef759cb1164ee2d27b338338a5a9302f427ad95f9b021361b02e1a2 +size 52263406 diff --git a/selfdrive/modeld/tests/test_modeld.py b/selfdrive/modeld/tests/test_modeld.py index 257a9bc878..67c6f71038 100755 --- a/selfdrive/modeld/tests/test_modeld.py +++ b/selfdrive/modeld/tests/test_modeld.py @@ -5,13 +5,14 @@ import random import cereal.messaging as messaging from cereal.visionipc import VisionIpcServer, VisionStreamType -from openpilot.common.transformations.camera import tici_f_frame_size +from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.car_helpers import write_car_param from openpilot.selfdrive.manager.process_config import managed_processes from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_camera_state -IMG = np.zeros(int(tici_f_frame_size[0]*tici_f_frame_size[1]*(3/2)), dtype=np.uint8) +CAM = DEVICE_CAMERAS[("tici", "ar0231")].fcam +IMG = np.zeros(int(CAM.width*CAM.height*(3/2)), dtype=np.uint8) IMG_BYTES = IMG.flatten().tobytes() @@ -19,9 +20,9 @@ class TestModeld(unittest.TestCase): def setUp(self): self.vipc_server = VisionIpcServer("camerad") - self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, *tici_f_frame_size) - self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, *tici_f_frame_size) - self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, *tici_f_frame_size) + self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, CAM.width, CAM.height) + self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, CAM.width, CAM.height) + self.vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, CAM.width, CAM.height) self.vipc_server.start_listener() write_car_param() diff --git a/selfdrive/monitoring/driver_monitor.py b/selfdrive/monitoring/driver_monitor.py index 2279002f35..7c1c297fff 100644 --- a/selfdrive/monitoring/driver_monitor.py +++ b/selfdrive/monitoring/driver_monitor.py @@ -5,7 +5,7 @@ from openpilot.common.numpy_fast import interp from openpilot.common.realtime import DT_DMON from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.stat_live import RunningStatFilter -from openpilot.common.transformations.camera import tici_d_frame_size +from openpilot.common.transformations.camera import DEVICE_CAMERAS EventName = car.CarEvent.EventName @@ -71,9 +71,11 @@ class DRIVER_MONITOR_SETTINGS(): self._MAX_TERMINAL_DURATION = int(30 / self._DT_DMON) # not allowed to engage after 30s of terminal alerts +# TODO: get these live # model output refers to center of undistorted+leveled image EFL = 598.0 # focal length in K -W, H = tici_d_frame_size # corrected image has same size as raw +cam = DEVICE_CAMERAS[("tici", "ar0231")] # corrected image has same size as raw +W, H = (cam.dcam.width, cam.dcam.height) # corrected image has same size as raw class DistractedType: NOT_DISTRACTED = 0 diff --git a/selfdrive/sentry.py b/selfdrive/sentry.py index 5b63a9fe2d..889178610f 100644 --- a/selfdrive/sentry.py +++ b/selfdrive/sentry.py @@ -6,9 +6,9 @@ from sentry_sdk.integrations.threading import ThreadingIntegration from openpilot.common.params import Params from openpilot.selfdrive.athena.registration import is_registered_device from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.git import get_commit, get_branch, get_origin from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_branch, get_commit, get_origin, get_version, \ - is_comma_remote, is_dirty, is_tested_branch +from openpilot.system.version import get_version, is_comma_remote, is_dirty, is_tested_branch class SentryProject(Enum): diff --git a/selfdrive/test/helpers.py b/selfdrive/test/helpers.py index fe47637bdd..43eadd38f4 100644 --- a/selfdrive/test/helpers.py +++ b/selfdrive/test/helpers.py @@ -14,7 +14,7 @@ from openpilot.system.version import training_version, terms_version def set_params_enabled(): - os.environ['FINGERPRINT'] = "TOYOTA COROLLA TSS2 2019" + os.environ['FINGERPRINT'] = "TOYOTA_COROLLA_TSS2" os.environ['LOGPRINT'] = "debug" params = Params() diff --git a/selfdrive/test/longitudinal_maneuvers/maneuver.py b/selfdrive/test/longitudinal_maneuvers/maneuver.py index 000225ab77..6c8495cc3b 100644 --- a/selfdrive/test/longitudinal_maneuvers/maneuver.py +++ b/selfdrive/test/longitudinal_maneuvers/maneuver.py @@ -19,6 +19,7 @@ class Maneuver: self.ensure_start = kwargs.get("ensure_start", False) self.enabled = kwargs.get("enabled", True) self.e2e = kwargs.get("e2e", False) + self.personality = kwargs.get("personality", 0) self.force_decel = kwargs.get("force_decel", False) self.duration = duration @@ -33,6 +34,7 @@ class Maneuver: only_lead2=self.only_lead2, only_radar=self.only_radar, e2e=self.e2e, + personality=self.personality, force_decel=self.force_decel, ) diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/selfdrive/test/longitudinal_maneuvers/plant.py index bb935fdc8e..ac54967f88 100755 --- a/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/selfdrive/test/longitudinal_maneuvers/plant.py @@ -15,7 +15,7 @@ class Plant: messaging_initialized = False def __init__(self, lead_relevancy=False, speed=0.0, distance_lead=2.0, - enabled=True, only_lead2=False, only_radar=False, e2e=False, force_decel=False): + enabled=True, only_lead2=False, only_radar=False, e2e=False, personality=0, force_decel=False): self.rate = 1. / DT_MDL if not Plant.messaging_initialized: @@ -39,6 +39,7 @@ class Plant: self.only_lead2 = only_lead2 self.only_radar = only_radar self.e2e = e2e + self.personality = personality self.force_decel = force_decel self.rk = Ratekeeper(self.rate, print_delay_threshold=100.0) @@ -49,7 +50,7 @@ class Plant: from openpilot.selfdrive.car.honda.values import CAR from openpilot.selfdrive.car.honda.interface import CarInterface - self.planner = LongitudinalPlanner(CarInterface.get_non_essential_params(CAR.CIVIC), init_v=self.speed) + self.planner = LongitudinalPlanner(CarInterface.get_non_essential_params(CAR.HONDA_CIVIC), init_v=self.speed) @property def current_time(self): @@ -112,6 +113,7 @@ class Plant: control.controlsState.longControlState = LongCtrlState.pid if self.enabled else LongCtrlState.off control.controlsState.vCruise = float(v_cruise * 3.6) control.controlsState.experimentalMode = self.e2e + control.controlsState.personality = self.personality control.controlsState.forceDecel = self.force_decel car_state.carState.vEgo = float(self.speed) car_state.carState.standstill = self.speed < 0.01 diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index d480309169..152f281948 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -1,6 +1,7 @@ from collections import defaultdict from cereal import messaging +from openpilot.selfdrive.car.fingerprints import MIGRATION from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_encode_index from openpilot.selfdrive.car.toyota.values import EPS_SCALE from openpilot.selfdrive.manager.process_config import managed_processes @@ -12,6 +13,7 @@ def migrate_all(lr, old_logtime=False, manager_states=False, panda_states=False, msgs = migrate_sensorEvents(lr, old_logtime) msgs = migrate_carParams(msgs, old_logtime) msgs = migrate_gpsLocation(msgs) + msgs = migrate_deviceState(msgs) if manager_states: msgs = migrate_managerState(msgs) if panda_states: @@ -52,13 +54,28 @@ def migrate_gpsLocation(lr): return all_msgs +def migrate_deviceState(lr): + all_msgs = [] + dt = None + for msg in lr: + if msg.which() == 'initData': + dt = msg.initData.deviceType + if msg.which() == 'deviceState': + n = msg.as_builder() + n.deviceState.deviceType = dt + all_msgs.append(n.as_reader()) + else: + all_msgs.append(msg) + return all_msgs + + def migrate_pandaStates(lr): all_msgs = [] # TODO: safety param migration should be handled automatically safety_param_migration = { - "TOYOTA PRIUS 2017": EPS_SCALE["TOYOTA PRIUS 2017"] | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL, - "TOYOTA RAV4 2017": EPS_SCALE["TOYOTA RAV4 2017"] | Panda.FLAG_TOYOTA_ALT_BRAKE | Panda.FLAG_TOYOTA_GAS_INTERCEPTOR, - "KIA EV6 2022": Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CANFD_HDA2, + "TOYOTA_PRIUS": EPS_SCALE["TOYOTA_PRIUS"] | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL, + "TOYOTA_RAV4": EPS_SCALE["TOYOTA_RAV4"] | Panda.FLAG_TOYOTA_ALT_BRAKE, + "KIA_EV6": Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CANFD_HDA2, } # Migrate safety param base on carState @@ -169,6 +186,7 @@ def migrate_carParams(lr, old_logtime=False): CP = messaging.new_message('carParams') CP.valid = True CP.carParams = msg.carParams.as_builder() + CP.carParams.carFingerprint = MIGRATION.get(CP.carParams.carFingerprint, CP.carParams.carFingerprint) for car_fw in CP.carParams.carFw: car_fw.brand = CP.carParams.carName if old_logtime: diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 97b7c7c46c..9db05cfc82 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -6,13 +6,13 @@ from collections import defaultdict from typing import Any import cereal.messaging as messaging +from openpilot.common.git import get_commit from openpilot.common.params import Params from openpilot.system.hardware import PC from openpilot.selfdrive.manager.process_config import managed_processes 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.system.version import get_commit from openpilot.tools.lib.framereader import FrameReader from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.helpers import save_log @@ -107,14 +107,17 @@ def model_replay(lr, frs): # modeld is using frame pairs modeld_logs = trim_logs_to_max_frames(lr, MAX_FRAMES, {"roadCameraState", "wideRoadCameraState"}, {"roadEncodeIdx", "wideRoadEncodeIdx", "carParams"}) dmodeld_logs = trim_logs_to_max_frames(lr, MAX_FRAMES, {"driverCameraState"}, {"driverEncodeIdx", "carParams"}) + if not SEND_EXTRA_INPUTS: - modeld_logs = [msg for msg in modeld_logs if msg.which() not in ["liveCalibration",]] - dmodeld_logs = [msg for msg in dmodeld_logs if msg.which() not in ["liveCalibration",]] - # initial calibration - cal_msg = next(msg for msg in lr if msg.which() == "liveCalibration").as_builder() - cal_msg.logMonoTime = lr[0].logMonoTime - modeld_logs.insert(0, cal_msg.as_reader()) - dmodeld_logs.insert(0, cal_msg.as_reader()) + modeld_logs = [msg for msg in modeld_logs if msg.which() != 'liveCalibration'] + dmodeld_logs = [msg for msg in dmodeld_logs if msg.which() != 'liveCalibration'] + + # initial setup + for s in ('liveCalibration', 'deviceState'): + msg = next(msg for msg in lr if msg.which() == s).as_builder() + msg.logMonoTime = lr[0].logMonoTime + modeld_logs.insert(1, msg.as_reader()) + dmodeld_logs.insert(1, msg.as_reader()) modeld = get_process_config("modeld") dmonitoringmodeld = get_process_config("dmonitoringmodeld") @@ -218,7 +221,8 @@ if __name__ == "__main__": results[TEST_ROUTE]["models"] = compare_logs(cmp_log, log_msgs, tolerance=tolerance, ignore_fields=ignore) diff_short, diff_long, failed = format_diff(results, log_paths, ref_commit) - print(diff_long) + if "CI" in os.environ: + print(diff_long) print('-------------\n'*5) print(diff_short) with open("model_diff.txt", "w") as f: diff --git a/selfdrive/test/process_replay/model_replay_ref_commit b/selfdrive/test/process_replay/model_replay_ref_commit index 786c2f2731..85ba5fb840 100644 --- a/selfdrive/test/process_replay/model_replay_ref_commit +++ b/selfdrive/test/process_replay/model_replay_ref_commit @@ -1 +1 @@ -e8b359a82316e6dfce3b6fb0fb9684431bfa0a1b +60b00d102b3aedcc74a91722d1210cc6905b0c8f diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 5119be0a8c..233f5d746a 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -546,7 +546,7 @@ CONFIGS = [ ), ProcessConfig( proc_name="modeld", - pubs=["roadCameraState", "wideRoadCameraState", "liveCalibration", "driverMonitoringState"], + pubs=["deviceState", "roadCameraState", "wideRoadCameraState", "liveCalibration", "driverMonitoringState"], subs=["modelV2", "cameraOdometry"], ignore=["logMonoTime", "modelV2.frameDropPerc", "modelV2.modelExecutionTime"], should_recv_callback=ModeldCameraSyncRcvCallback(), diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 97646ce064..7defed3f68 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -d53d44c21a89d7925d5ad16938e14794907f28b1 \ No newline at end of file +4e5e37be9d70450154f8b100ed88151bb3612331 \ No newline at end of file diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 8e882207b5..ec3023c5dc 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -10,7 +10,7 @@ from collections.abc import Iterable from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, FAKEDATA, ProcessConfig, replay_process, get_process_config, \ check_openpilot_enabled, get_custom_params_from_lr -from openpilot.selfdrive.test.process_replay.vision_meta import DRIVER_FRAME_SIZES +from openpilot.selfdrive.test.process_replay.vision_meta import DRIVER_CAMERA_FRAME_SIZES 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 @@ -37,7 +37,7 @@ class DummyFrameReader(BaseFrameReader): @staticmethod def zero_dcamera(): - return DummyFrameReader(*DRIVER_FRAME_SIZES["tici"], 1200, 0) + return DummyFrameReader(*DRIVER_CAMERA_FRAME_SIZES[("tici", "ar0231")], 1200, 0) def regen_segment( diff --git a/selfdrive/test/process_replay/test_debayer.py b/selfdrive/test/process_replay/test_debayer.py index edf2cbd469..805d73db88 100755 --- a/selfdrive/test/process_replay/test_debayer.py +++ b/selfdrive/test/process_replay/test_debayer.py @@ -9,7 +9,7 @@ import pyopencl as cl # install with `PYOPENCL_CL_PRETEND_VERSION=2.0 pip insta from openpilot.system.hardware import PC, TICI from openpilot.common.basedir import BASEDIR from openpilot.tools.lib.openpilotci import BASE_URL -from openpilot.system.version import get_commit +from openpilot.common.git import get_commit from openpilot.system.camerad.snapshot.snapshot import yuv_to_rgb from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.filereader import FileReader diff --git a/selfdrive/test/process_replay/test_fuzzy.py b/selfdrive/test/process_replay/test_fuzzy.py index adff06f88a..6c81119fbf 100755 --- a/selfdrive/test/process_replay/test_fuzzy.py +++ b/selfdrive/test/process_replay/test_fuzzy.py @@ -27,7 +27,7 @@ class TestFuzzProcesses(unittest.TestCase): msgs = FuzzyGenerator.get_random_event_msg(data.draw, events=cfg.pubs, real_floats=True) lr = [log.Event.new_message(**m).as_reader() for m in msgs] cfg.timeout = 5 - pr.replay_process(cfg, lr, fingerprint=TOYOTA.COROLLA_TSS2, disable_progress=True) + pr.replay_process(cfg, lr, fingerprint=TOYOTA.TOYOTA_COROLLA_TSS2, disable_progress=True) if __name__ == "__main__": unittest.main() diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 88e46abb06..5fa80f0e09 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -7,37 +7,37 @@ from collections import defaultdict from tqdm import tqdm from typing import Any +from openpilot.common.git import get_commit from openpilot.selfdrive.car.car_helpers import interface_names from openpilot.tools.lib.openpilotci import get_url, upload_file from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS, PROC_REPLAY_DIR, FAKEDATA, check_openpilot_enabled, replay_process -from openpilot.system.version import get_commit from openpilot.tools.lib.filereader import FileReader from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.helpers import save_log source_segments = [ - ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY - ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA - ("HYUNDAI2", "d545129f3ca90f28|2022-11-07--20-43-08--3"), # HYUNDAI.KIA_EV6 (+ QCOM GPS) - ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS - ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 - ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2 - ("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.CIVIC (NIDEC) - ("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.ACCORD (BOSCH) - ("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.PACIFICA_2018_HYBRID - ("RAM", "17fc16d840fe9d21|2023-04-26--13-28-44--5"), # CHRYSLER.RAM_1500 - ("SUBARU", "341dccd5359e3c97|2022-09-12--10-35-33--3"), # SUBARU.OUTBACK - ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT - ("GM2", "376bf99325883932|2022-10-27--13-41-22--1"), # GM.BOLT_EUV - ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL - ("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.GOLF - ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.CX9_2021 - ("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1 + ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.COMMA_BODY + ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.HYUNDAI_SONATA + ("HYUNDAI2", "d545129f3ca90f28|2022-11-07--20-43-08--3"), # HYUNDAI.HYUNDAI_KIA_EV6 (+ QCOM GPS) + ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.TOYOTA_PRIUS + ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.TOYOTA_RAV4 + ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.TOYOTA_COROLLA_TSS2 + ("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.HONDA_CIVIC (NIDEC) + ("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.HONDA_ACCORD (BOSCH) + ("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.CHRYSLER_PACIFICA_2018_HYBRID + ("RAM", "17fc16d840fe9d21|2023-04-26--13-28-44--5"), # CHRYSLER.RAM_1500_5TH_GEN + ("SUBARU", "341dccd5359e3c97|2022-09-12--10-35-33--3"), # SUBARU.SUBARU_OUTBACK + ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.CHEVROLET_VOLT + ("GM2", "376bf99325883932|2022-10-27--13-41-22--1"), # GM.CHEVROLET_BOLT_EUV + ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.NISSAN_XTRAIL + ("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.VOLKSWAGEN_GOLF + ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.MAZDA_CX9_2021 + ("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.FORD_BRONCO_SPORT_MK1 # Enable when port is tested and dashcamOnly is no longer set - #("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS - #("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.PASSAT_NMS + #("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.TESLA_AP2_MODELS + #("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.VOLKSWAGEN_PASSAT_NMS ] segments = [ diff --git a/selfdrive/test/process_replay/test_regen.py b/selfdrive/test/process_replay/test_regen.py index 41d67ea376..d989635497 100755 --- a/selfdrive/test/process_replay/test_regen.py +++ b/selfdrive/test/process_replay/test_regen.py @@ -11,7 +11,7 @@ from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.framereader import FrameReader TESTED_SEGMENTS = [ - ("PRIUS_C2", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA PRIUS 2017: NEO, pandaStateDEPRECATED, no peripheralState, sensorEventsDEPRECATED + ("PRIUS_C2", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.TOYOTA_PRIUS: NEO, pandaStateDEPRECATED, no peripheralState, sensorEventsDEPRECATED # Enable these once regen on CI becomes faster or use them for different tests running controlsd in isolation # ("MAZDA_C3", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.CX9_2021: TICI, incomplete managerState # ("FORD_C3", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1: TICI diff --git a/selfdrive/test/process_replay/vision_meta.py b/selfdrive/test/process_replay/vision_meta.py index b3c3dc0c9c..9bfe214c1e 100644 --- a/selfdrive/test/process_replay/vision_meta.py +++ b/selfdrive/test/process_replay/vision_meta.py @@ -1,17 +1,17 @@ from collections import namedtuple from cereal.visionipc import VisionStreamType from openpilot.common.realtime import DT_MDL, DT_DMON -from openpilot.common.transformations.camera import tici_f_frame_size, tici_d_frame_size, tici_e_frame_size, eon_f_frame_size, eon_d_frame_size +from openpilot.common.transformations.camera import DEVICE_CAMERAS VideoStreamMeta = namedtuple("VideoStreamMeta", ["camera_state", "encode_index", "stream", "dt", "frame_sizes"]) -ROAD_CAMERA_FRAME_SIZES = {"tici": tici_f_frame_size, "tizi": tici_f_frame_size, "neo": eon_f_frame_size} -WIDE_ROAD_CAMERA_FRAME_SIZES = {"tici": tici_e_frame_size, "tizi": tici_e_frame_size} -DRIVER_FRAME_SIZES = {"tici": tici_d_frame_size, "tizi": tici_d_frame_size, "neo": eon_d_frame_size} +ROAD_CAMERA_FRAME_SIZES = {k: (v.dcam.width, v.dcam.height) for k, v in DEVICE_CAMERAS.items()} +WIDE_ROAD_CAMERA_FRAME_SIZES = {k: (v.ecam.width, v.ecam.height) for k, v in DEVICE_CAMERAS.items() if v.ecam is not None} +DRIVER_CAMERA_FRAME_SIZES = {k: (v.dcam.width, v.dcam.height) for k, v in DEVICE_CAMERAS.items()} VIPC_STREAM_METADATA = [ # metadata: (state_msg_type, encode_msg_type, stream_type, dt, frame_sizes) ("roadCameraState", "roadEncodeIdx", VisionStreamType.VISION_STREAM_ROAD, DT_MDL, ROAD_CAMERA_FRAME_SIZES), ("wideRoadCameraState", "wideRoadEncodeIdx", VisionStreamType.VISION_STREAM_WIDE_ROAD, DT_MDL, WIDE_ROAD_CAMERA_FRAME_SIZES), - ("driverCameraState", "driverEncodeIdx", VisionStreamType.VISION_STREAM_DRIVER, DT_DMON, DRIVER_FRAME_SIZES), + ("driverCameraState", "driverEncodeIdx", VisionStreamType.VISION_STREAM_DRIVER, DT_DMON, DRIVER_CAMERA_FRAME_SIZES), ] diff --git a/selfdrive/test/profiling/profiler.py b/selfdrive/test/profiling/profiler.py index 6571825418..2cd547171a 100755 --- a/selfdrive/test/profiling/profiler.py +++ b/selfdrive/test/profiling/profiler.py @@ -16,8 +16,8 @@ from openpilot.selfdrive.car.volkswagen.values import CAR as VW BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/" CARS = { - 'toyota': ("0982d79ebb0de295|2021-01-03--20-03-36/6", TOYOTA.RAV4), - 'honda': ("0982d79ebb0de295|2021-01-08--10-13-10/6", HONDA.CIVIC), + 'toyota': ("0982d79ebb0de295|2021-01-03--20-03-36/6", TOYOTA.TOYOTA_RAV4), + 'honda': ("0982d79ebb0de295|2021-01-08--10-13-10/6", HONDA.HONDA_CIVIC), "vw": ("ef895f46af5fd73f|2021-05-22--14-06-35/6", VW.AUDI_A3_MK3), } diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 4be9b8a430..250534bf86 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -65,7 +65,7 @@ PROCS.update({ "tici": { "./boardd": 4.0, "./ubloxd": 0.02, - "system.sensord.pigeond": 6.0, + "system.ubloxd.pigeond": 6.0, }, "tizi": { "./boardd": 19.0, diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index 93ebd3ab87..bfc50c4478 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -216,6 +216,7 @@ def thermald_thread(end_event, hw_queue) -> None: peripheral_panda_present = peripheralState.pandaType != log.PandaState.PandaType.unknown msg = read_thermal(thermal_config) + msg.deviceState.deviceType = HARDWARE.get_device_type() if sm.updated['pandaStates'] and len(pandaStates) > 0: diff --git a/selfdrive/tombstoned.py b/selfdrive/tombstoned.py index ba3582d130..f1b8c88083 100755 --- a/selfdrive/tombstoned.py +++ b/selfdrive/tombstoned.py @@ -11,8 +11,8 @@ from typing import NoReturn import openpilot.selfdrive.sentry as sentry from openpilot.system.hardware.hw import Paths +from openpilot.common.git import get_commit from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_commit MAX_SIZE = 1_000_000 * 100 # allow up to 100M MAX_TOMBSTONE_FN_LEN = 62 # 85 - 23 ("/crash/") diff --git a/selfdrive/ui/qt/network/networking.cc b/selfdrive/ui/qt/network/networking.cc index 5354a01fa0..d7cdddff44 100644 --- a/selfdrive/ui/qt/network/networking.cc +++ b/selfdrive/ui/qt/network/networking.cc @@ -82,11 +82,11 @@ void Networking::connectToNetwork(const Network n) { if (wifi->isKnownConnection(n.ssid)) { wifi->activateWifiConnection(n.ssid); } else if (n.security_type == SecurityType::OPEN) { - wifi->connect(n); + wifi->connect(n, false); } else if (n.security_type == SecurityType::WPA) { QString pass = InputDialog::getText(tr("Enter password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8); if (!pass.isEmpty()) { - wifi->connect(n, pass); + wifi->connect(n, false, pass); } } } @@ -96,7 +96,7 @@ void Networking::wrongPassword(const QString &ssid) { const Network &n = wifi->seenNetworks.value(ssid); QString pass = InputDialog::getText(tr("Wrong password"), this, tr("for \"%1\"").arg(QString::fromUtf8(n.ssid)), true, 8); if (!pass.isEmpty()) { - wifi->connect(n, pass); + wifi->connect(n, false, pass); } } } @@ -192,9 +192,9 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid hidden_network.ssid = ssid.toUtf8(); if (!pass.isEmpty()) { hidden_network.security_type = SecurityType::WPA; - wifi->connect(hidden_network, pass); + wifi->connect(hidden_network, true, pass); } else { - wifi->connect(hidden_network); + wifi->connect(hidden_network, true); } emit requestWifiScreen(); } diff --git a/selfdrive/ui/qt/network/wifi_manager.cc b/selfdrive/ui/qt/network/wifi_manager.cc index ebb5cb8736..111726330d 100644 --- a/selfdrive/ui/qt/network/wifi_manager.cc +++ b/selfdrive/ui/qt/network/wifi_manager.cc @@ -166,7 +166,7 @@ SecurityType WifiManager::getSecurityType(const QVariantMap &properties) { } } -void WifiManager::connect(const Network &n, const QString &password, const QString &username) { +void WifiManager::connect(const Network &n, const bool is_hidden, const QString &password, const QString &username) { setCurrentConnecting(n.ssid); forgetConnection(n.ssid); // Clear all connections that may already exist to the network we are connecting Connection connection; @@ -176,6 +176,7 @@ void WifiManager::connect(const Network &n, const QString &password, const QStri connection["connection"]["autoconnect-retries"] = 0; connection["802-11-wireless"]["ssid"] = n.ssid; + connection["802-11-wireless"]["hidden"] = is_hidden; connection["802-11-wireless"]["mode"] = "infrastructure"; if (n.security_type == SecurityType::WPA) { diff --git a/selfdrive/ui/qt/network/wifi_manager.h b/selfdrive/ui/qt/network/wifi_manager.h index 7debffa452..933f25c9d4 100644 --- a/selfdrive/ui/qt/network/wifi_manager.h +++ b/selfdrive/ui/qt/network/wifi_manager.h @@ -52,7 +52,7 @@ public: std::optional activateWifiConnection(const QString &ssid); NetworkType currentNetworkType(); void updateGsmSettings(bool roaming, QString apn, bool metered); - void connect(const Network &ssid, const QString &password = {}, const QString &username = {}); + void connect(const Network &ssid, const bool is_hidden = false, const QString &password = {}, const QString &username = {}); // Tethering functions void setTetheringEnabled(bool enabled); diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 85393cabc0..bc7989b773 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -91,9 +91,14 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { std::vector longi_button_texts{tr("Aggressive"), tr("Standard"), tr("Relaxed")}; long_personality_setting = new ButtonParamControl("LongitudinalPersonality", tr("Driving Personality"), tr("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."), + "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."), "../assets/offroad/icon_speed_limit.png", longi_button_texts); + + // set up uiState update for personality setting + QObject::connect(uiState(), &UIState::uiUpdate, this, &TogglesPanel::updateState); + for (auto &[param, title, desc, icon] : toggle_defs) { auto toggle = new ParamControl(param, title, desc, icon, this); @@ -119,6 +124,18 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { }); } +void TogglesPanel::updateState(const UIState &s) { + const SubMaster &sm = *(s.sm); + + if (sm.updated("controlsState")) { + auto personality = sm["controlsState"].getControlsState().getPersonality(); + if (personality != s.scene.personality && s.scene.started && isVisible()) { + long_personality_setting->setCheckedButton(static_cast(personality)); + } + uiState()->scene.personality = personality; + } +} + void TogglesPanel::expandToggleDescription(const QString ¶m) { toggles[param.toStdString()]->showDescription(); } diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index a5dd25b14f..581fc098f4 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -11,6 +11,7 @@ #include +#include "selfdrive/ui/ui.h" #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/widgets/controls.h" @@ -64,6 +65,9 @@ public: public slots: void expandToggleDescription(const QString ¶m); +private slots: + void updateState(const UIState &s); + private: Params params; std::map toggles; diff --git a/selfdrive/ui/qt/widgets/cameraview.cc b/selfdrive/ui/qt/widgets/cameraview.cc index 7b1f2f1d24..7818da8669 100644 --- a/selfdrive/ui/qt/widgets/cameraview.cc +++ b/selfdrive/ui/qt/widgets/cameraview.cc @@ -41,6 +41,8 @@ const char frame_fragment_shader[] = "out vec4 colorOut;\n" "void main() {\n" " colorOut = texture(uTexture, vTexCoord);\n" + // gamma to improve worst case visibility when dark + " colorOut.rgb = pow(colorOut.rgb, vec3(1.0/1.28));\n" "}\n"; #else #ifdef __APPLE__ diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index e4630c6590..aa304e0df6 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -223,10 +223,8 @@ public: button_group->addButton(button, i); } - QObject::connect(button_group, QOverload::of(&QButtonGroup::buttonToggled), [=](int id, bool checked) { - if (checked) { - params.put(key, std::to_string(id)); - } + QObject::connect(button_group, QOverload::of(&QButtonGroup::buttonClicked), [=](int id) { + params.put(key, std::to_string(id)); }); } @@ -236,6 +234,19 @@ public: } } + void setCheckedButton(int id) { + button_group->button(id)->setChecked(true); + } + + void refresh() { + int value = atoi(params.get(key).c_str()); + button_group->button(value)->setChecked(true); + } + + void showEvent(QShowEvent *event) override { + refresh(); + } + private: std::string key; Params params; diff --git a/selfdrive/ui/tests/body.py b/selfdrive/ui/tests/body.py index c34e717eaf..7e24c2beb7 100755 --- a/selfdrive/ui/tests/body.py +++ b/selfdrive/ui/tests/body.py @@ -8,7 +8,7 @@ if __name__ == "__main__": batt = 1. while True: msg = messaging.new_message('carParams') - msg.carParams.carName = "COMMA BODY" + msg.carParams.carName = "BODY" msg.carParams.notCar = True pm.send('carParams', msg) diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index 7a2ac9a110..c834107780 100644 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -18,7 +18,7 @@ from cereal.messaging import SubMaster, PubMaster from openpilot.common.mock import mock_messages from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL -from openpilot.common.transformations.camera import tici_f_frame_size +from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.selfdrive.test.helpers import with_processes from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_camera_state from openpilot.tools.webcam.camera import Camera @@ -69,15 +69,16 @@ def setup_onroad(click, pm: PubMaster): pm.send("pandaStates", dat) + d = DEVICE_CAMERAS[("tici", "ar0231")] server = VisionIpcServer("camerad") - server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, *tici_f_frame_size) - server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, *tici_f_frame_size) - server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, *tici_f_frame_size) + server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, d.fcam.width, d.fcam.height) + server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, d.dcam.width, d.dcam.height) + server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, d.fcam.width, d.fcam.height) server.start_listener() time.sleep(0.5) # give time for vipc server to start - IMG = Camera.bgr2nv12(np.random.randint(0, 255, (*tici_f_frame_size,3), dtype=np.uint8)) + IMG = Camera.bgr2nv12(np.random.randint(0, 255, (d.fcam.width, d.fcam.height, 3), dtype=np.uint8)) IMG_BYTES = IMG.flatten().tobytes() cams = ('roadCameraState', 'wideRoadCameraState') diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 7a431b8bf8..10c87d87bd 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -1103,10 +1103,6 @@ This may take up to a minute. Driving Personality شخصية القيادة - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - يوصى بالوضع القياسي. في الوضع الهجومي، سيتبع openpilot السيارات الرائدة بشكل أقرب، ويصبح أكثر هجومية في دواسات الوقود والمكابح. في وضعية الراحة يبقى openplot بعيداً لمسافة جيدة عن السيارة الرائدة. - 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: يتم وضع openpilot بشكل قياسي في <b>وضعية الراحة</b>. يمكن الوضع التجريبي <b>ميزات المستوى ألفا</b> التي لا تكون جاهزة في وضع الراحة: @@ -1151,6 +1147,10 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. تمكين التحكم الطولي من openpilot (ألفا) للسماح بالوضع التجريبي. + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index ae2bdf33cb..cdcea24778 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -1105,10 +1105,6 @@ This may take up to a minute. 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. - - 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. - - End-to-End Longitudinal Control @@ -1137,6 +1133,10 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index ba496c1b89..b1c39db18e 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -1087,10 +1087,6 @@ Cela peut prendre jusqu'à une minute. Driving Personality Personnalité de conduite - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - Le mode standard est recommandé. En mode agressif, openpilot suivra de plus près les voitures de tête et sera plus agressif avec l'accélérateur et le frein. En mode détendu, openpilot restera plus éloigné des voitures de tête. - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: Par défaut, openpilot conduit en <b>mode détente</b>. Le mode expérimental permet d'activer des <b>fonctionnalités alpha</b> qui ne sont pas prêtes pour le mode détente. Les fonctionnalités expérimentales sont listées ci-dessous : @@ -1135,6 +1131,10 @@ Cela peut prendre jusqu'à une minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. Activer le contrôle longitudinal d'openpilot (en alpha) pour autoriser le mode expérimental. + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 54ff0fa4ae..5360c352d1 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -1097,10 +1097,6 @@ This may take up to a minute. 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. - - 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. - - End-to-End Longitudinal Control @@ -1129,6 +1125,10 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 3f98db2f9c..ed751912a6 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -634,7 +634,7 @@ This may take up to a minute. System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot. - + 시스템 재설정이 시작되었습니다. 모든 콘텐츠와 설정을 지우려면 확인을 누르시고 부팅을 재개하려면 취소를 누르세요. @@ -744,15 +744,15 @@ This may take up to a minute. Choose Software to Install - + 설치할 소프트웨어 선택 openpilot - openpilot + openpilot Custom Software - + 커스텀 소프트웨어 @@ -1103,10 +1103,6 @@ This may take up to a minute. Driving Personality 주행 모드 - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - 표준 모드를 권장합니다. 공격적 모드에서 openpilot은 앞 차량을 더 가까이 따라가며 적극적으로 가감속합니다. 편안한 모드에서 openpilot은 앞 차량을 더 멀리서 따라갑니다. - An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. openpilot 가감속 제어 알파 버전은 비 릴리즈 브랜치에서 실험 모드와 함께 테스트할 수 있습니다. @@ -1131,6 +1127,10 @@ This may take up to a minute. The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. 주행 시각화는 저속으로 주행 시 도로를 향한 광각 카메라로 자동 전환되어 일부 곡선 경로를 더 잘 보여줍니다. 실험 모드 로고는 우측 상단에 표시됩니다. 내비게이션 목적지가 설정되고 주행 모델에 입력되면 지도의 주행 경로가 녹색으로 바뀝니다. + + 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. + 표준 모드를 권장합니다. 공격적 모드의 openpilot은 선두 차량을 더 가까이 따라가고 가감속제어를 사용하여 더욱 공격적으로 움직입니다. 편안한 모드의 openpilot은 선두 차량으로부터 더 멀리 떨어져 있습니다. 지원되는 차량에서는 스티어링 휠 거리 버튼을 사용하여 이러한 특성을 순환할 수 있습니다. + Updater diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index c4789ed42e..c32aeacaa3 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -1107,10 +1107,6 @@ Isso pode levar até um minuto. Driving Personality Temperamento de Direção - - 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. - Neutro é o recomendado. No modo disputa o openpilot seguirá o carro da frente mais de perto e será mais agressivo com a aceleração e frenagem. No modo calmo o openpilot se manterá mais longe do carro da frente. - An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. Uma versão embrionária do controle longitudinal openpilot pode ser testada em conjunto com o modo Experimental, em branches que não sejam de produção. @@ -1135,6 +1131,10 @@ Isso pode levar até um minuto. The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. A visualização de condução fará a transição para a câmera grande angular voltada para a estrada em baixas velocidades para mostrar melhor algumas curvas. O logotipo do modo Experimental também será mostrado no canto superior direito. Quando um destino de navegação é definido e o modelo de condução o utiliza como entrada o caminho de condução no mapa fica verde. + + 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. + Neutro é o recomendado. No modo disputa o openpilot seguirá o carro da frente mais de perto e será mais agressivo com a aceleração e frenagem. No modo calmo o openpilot se manterá mais longe do carro da frente. Em carros compatíveis, você pode alternar esses temperamentos com o botão de distância do volante. + Updater diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index c1f0039a3c..25a8aaeebd 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -1103,10 +1103,6 @@ This may take up to a minute. Driving Personality บุคลิกการขับขี่ - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - แนะนำให้ใช้แบบมาตรฐาน ในโหมดดุดัน openpilot จะตามรถคันหน้าใกล้ขึ้นและเร่งและเบรคแบบดุดันมากขึ้น ในโหมดผ่อนคลาย openpilot จะอยู่ห่างจากรถคันหน้ามากขึ้น - An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. ระบบควบคุมการเร่ง/เบรคโดย openpilot เวอร์ชัน alpha สามารถทดสอบได้พร้อมกับโหมดการทดลอง บน branch ที่กำลังพัฒนา @@ -1131,6 +1127,10 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. เปิดระบบควบคุมการเร่ง/เบรคโดย openpilot (alpha) เพื่อเปิดใช้งานโหมดทดลอง + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index d19c9ff036..dfe4b3670b 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -1081,10 +1081,6 @@ This may take up to a minute. 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. - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - - openpilot defaults to driving in <b>chill mode</b>. Experimental mode enables <b>alpha-level features</b> that aren't ready for chill mode. Experimental features are listed below: @@ -1129,6 +1125,10 @@ This may take up to a minute. Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode. + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 59d6874035..d985945f02 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -1103,10 +1103,6 @@ This may take up to a minute. Driving Personality 驾驶风格 - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - 推荐使用标准模式。在积极模式中,openpilot 会更靠近前车并在加速和刹车方面更积极。在舒适模式中,openpilot 会与前车保持较远的距离。 - An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. 在正式(release)版本以外的分支上,可以测试 openpilot 纵向控制的 Alpha 版本以及实验模式。 @@ -1131,6 +1127,10 @@ This may take up to a minute. The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. 行驶画面将在低速时切换到道路朝向的广角摄像头,以更好地显示一些转弯。实验模式标志也将显示在右上角。当设置了导航目的地并且驾驶模型正在使用它作为输入时,地图上的驾驶路径将变为绿色。 + + 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. + + Updater diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 0079b47f7f..e64134f253 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -1103,10 +1103,6 @@ This may take up to a minute. Driving Personality 駕駛風格 - - Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. - 推薦使用標準模式。在積極模式中,openpilot 會更靠近前車並在加速和剎車方面更積極。在舒適模式中,openpilot 會與前車保持較遠的距離。 - An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches. 在正式 (release) 版以外的分支上可以測試 openpilot 縱向控制的 Alpha 版本以及實驗模式。 @@ -1131,6 +1127,10 @@ This may take up to a minute. The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner. When a navigation destination is set and the driving model is using it as input, the driving path on the map will turn green. 行駛畫面將在低速時切換至道路朝向的廣角鏡頭,以更好地顯示一些轉彎。實驗模式圖示也將顯示在右上角。當設定了導航目的地並且行駛模型正在將其作為輸入時,地圖上的行駛路徑將變為綠色。 + + 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. + + Updater diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 86cd70f028..6efb72af9a 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -155,6 +155,7 @@ typedef struct UIScene { vec3 face_kpts_draw[std::size(default_face_kpts_3d)]; bool navigate_on_openpilot = false; + cereal::LongitudinalPersonality personality; float light_sensor; bool started, ignition, is_metric, map_on_left, longitudinal_control; diff --git a/selfdrive/ui/ui.py b/selfdrive/ui/ui.py index ea2ee51a45..660495b1de 100755 --- a/selfdrive/ui/ui.py +++ b/selfdrive/ui/ui.py @@ -52,7 +52,7 @@ if __name__ == "__main__": onroad = sm.all_checks(['deviceState']) and sm['deviceState'].started if onroad: cs = sm['controlsState'] - color = ("grey" if str(cs.status) in ("overriding", "preEnabled") else "green") if cs.enabled else "blue" + color = ("grey" if str(cs.state) in ("overriding", "preEnabled") else "green") if cs.enabled else "blue" bg.setText("\U0001F44D" if cs.engageable else "\U0001F6D1") bg.setStyleSheet(f"font-size: 100px; background-color: {color};") bg.show() diff --git a/selfdrive/updated/common.py b/selfdrive/updated/common.py deleted file mode 100644 index 6847147995..0000000000 --- a/selfdrive/updated/common.py +++ /dev/null @@ -1,115 +0,0 @@ -import abc -import os - -from pathlib import Path -import subprocess -from typing import List - -from markdown_it import MarkdownIt -from openpilot.common.params import Params -from openpilot.common.swaglog import cloudlog - - -LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") -STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") -FINALIZED = os.path.join(STAGING_ROOT, "finalized") - - -def run(cmd: list[str], cwd: str = None) -> str: - return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding='utf8') - - -class UpdateStrategy(abc.ABC): - def __init__(self): - self.params = Params() - - @abc.abstractmethod - def init(self) -> None: - pass - - @abc.abstractmethod - def cleanup(self) -> None: - pass - - @abc.abstractmethod - def get_available_channels(self) -> List[str]: - """List of available channels to install, (branches, releases, etc)""" - - @abc.abstractmethod - def current_channel(self) -> str: - """Current channel installed""" - - @abc.abstractmethod - def fetched_path(self) -> str: - """Path to the fetched update""" - - @property - def target_channel(self) -> str: - """Target Channel""" - b: str | None = self.params.get("UpdaterTargetBranch", encoding='utf-8') - if b is None: - b = self.current_channel() - return b - - @abc.abstractmethod - def update_ready(self) -> bool: - """Check if an update is ready to be installed""" - - @abc.abstractmethod - def update_available(self) -> bool: - """Check if an update is available for the current channel""" - - @abc.abstractmethod - def describe_current_channel(self) -> tuple[str, str]: - """Describe the current channel installed, (description, release_notes)""" - - @abc.abstractmethod - def describe_ready_channel(self) -> tuple[str, str]: - """Describe the channel that is ready to be installed, (description, release_notes)""" - - @abc.abstractmethod - def fetch_update(self) -> None: - pass - - @abc.abstractmethod - def finalize_update(self) -> None: - pass - - -def set_consistent_flag(consistent: bool) -> None: - os.sync() - consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) - if consistent: - consistent_file.touch() - elif not consistent: - consistent_file.unlink(missing_ok=True) - os.sync() - - -def get_consistent_flag() -> bool: - consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) - return consistent_file.is_file() - - -def parse_release_notes(releases_md: str) -> str: - try: - r = releases_md.split('\n\n', 1)[0] # Slice latest release notes - try: - return str(MarkdownIt().render(r)) - except Exception: - return r + "\n" - except FileNotFoundError: - pass - except Exception: - cloudlog.exception("failed to parse release notes") - return "" - - -def get_version(path) -> str: - with open(os.path.join(path, "common", "version.h")) as f: - return f.read().split('"')[1] - - -def get_release_notes(path) -> str: - with open(os.path.join(path, "RELEASES.md"), "r") as f: - return parse_release_notes(f.read()) diff --git a/selfdrive/updated/git.py b/selfdrive/updated/git.py deleted file mode 100644 index 921b32ede2..0000000000 --- a/selfdrive/updated/git.py +++ /dev/null @@ -1,236 +0,0 @@ -import datetime -import os -import re -import shutil -import subprocess -import time - -from collections import defaultdict -from pathlib import Path -from typing import List - -from openpilot.common.basedir import BASEDIR -from openpilot.common.params import Params -from openpilot.common.swaglog import cloudlog -from openpilot.selfdrive.updated.common import FINALIZED, STAGING_ROOT, UpdateStrategy, \ - get_consistent_flag, get_release_notes, get_version, set_consistent_flag, run - - -OVERLAY_UPPER = os.path.join(STAGING_ROOT, "upper") -OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata") -OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged") -OVERLAY_INIT = Path(os.path.join(BASEDIR, ".overlay_init")) - - -def setup_git_options(cwd: str) -> None: - # We sync FS object atimes (which NEOS doesn't use) and mtimes, but ctimes - # are outside user control. Make sure Git is set up to ignore system ctimes, - # because they change when we make hard links during finalize. Otherwise, - # there is a lot of unnecessary churn. This appears to be a common need on - # OSX as well: https://www.git-tower.com/blog/make-git-rebase-safe-on-osx/ - - # We are using copytree to copy the directory, which also changes - # inode numbers. Ignore those changes too. - - # Set protocol to the new version (default after git 2.26) to reduce data - # usage on git fetch --dry-run from about 400KB to 18KB. - git_cfg = [ - ("core.trustctime", "false"), - ("core.checkStat", "minimal"), - ("protocol.version", "2"), - ("gc.auto", "0"), - ("gc.autoDetach", "false"), - ] - for option, value in git_cfg: - run(["git", "config", option, value], cwd) - - -def dismount_overlay() -> None: - if os.path.ismount(OVERLAY_MERGED): - cloudlog.info("unmounting existing overlay") - run(["sudo", "umount", "-l", OVERLAY_MERGED]) - - -def init_overlay() -> None: - - # Re-create the overlay if BASEDIR/.git has changed since we created the overlay - if OVERLAY_INIT.is_file() and os.path.ismount(OVERLAY_MERGED): - git_dir_path = os.path.join(BASEDIR, ".git") - new_files = run(["find", git_dir_path, "-newer", str(OVERLAY_INIT)]) - if not len(new_files.splitlines()): - # A valid overlay already exists - return - else: - cloudlog.info(".git directory changed, recreating overlay") - - cloudlog.info("preparing new safe staging area") - - params = Params() - params.put_bool("UpdateAvailable", False) - set_consistent_flag(False) - dismount_overlay() - run(["sudo", "rm", "-rf", STAGING_ROOT]) - if os.path.isdir(STAGING_ROOT): - shutil.rmtree(STAGING_ROOT) - - for dirname in [STAGING_ROOT, OVERLAY_UPPER, OVERLAY_METADATA, OVERLAY_MERGED]: - os.mkdir(dirname, 0o755) - - if os.lstat(BASEDIR).st_dev != os.lstat(OVERLAY_MERGED).st_dev: - raise RuntimeError("base and overlay merge directories are on different filesystems; not valid for overlay FS!") - - # Leave a timestamped canary in BASEDIR to check at startup. The device clock - # should be correct by the time we get here. If the init file disappears, or - # critical mtimes in BASEDIR are newer than .overlay_init, continue.sh can - # assume that BASEDIR has used for local development or otherwise modified, - # and skips the update activation attempt. - consistent_file = Path(os.path.join(BASEDIR, ".overlay_consistent")) - if consistent_file.is_file(): - consistent_file.unlink() - OVERLAY_INIT.touch() - - os.sync() - overlay_opts = f"lowerdir={BASEDIR},upperdir={OVERLAY_UPPER},workdir={OVERLAY_METADATA}" - - mount_cmd = ["mount", "-t", "overlay", "-o", overlay_opts, "none", OVERLAY_MERGED] - run(["sudo"] + mount_cmd) - run(["sudo", "chmod", "755", os.path.join(OVERLAY_METADATA, "work")]) - - git_diff = run(["git", "diff"], OVERLAY_MERGED) - params.put("GitDiff", git_diff) - cloudlog.info(f"git diff output:\n{git_diff}") - - -class GitUpdateStrategy(UpdateStrategy): - - def init(self) -> None: - init_overlay() - - def cleanup(self) -> None: - OVERLAY_INIT.unlink(missing_ok=True) - - def sync_branches(self): - excluded_branches = ('release2', 'release2-staging') - - output = run(["git", "ls-remote", "--heads"], OVERLAY_MERGED) - - self.branches = defaultdict(lambda: None) - for line in output.split('\n'): - ls_remotes_re = r'(?P\b[0-9a-f]{5,40}\b)(\s+)(refs\/heads\/)(?P.*$)' - x = re.fullmatch(ls_remotes_re, line.strip()) - if x is not None and x.group('branch_name') not in excluded_branches: - self.branches[x.group('branch_name')] = x.group('commit_sha') - - return self.branches - - def get_available_channels(self) -> List[str]: - self.sync_branches() - return list(self.branches.keys()) - - def update_ready(self) -> bool: - if get_consistent_flag(): - hash_mismatch = self.get_commit_hash(BASEDIR) != self.branches[self.target_channel] - branch_mismatch = self.get_branch(BASEDIR) != self.target_channel - on_target_channel = self.get_branch(FINALIZED) == self.target_channel - return ((hash_mismatch or branch_mismatch) and on_target_channel) - return False - - def update_available(self) -> bool: - if os.path.isdir(OVERLAY_MERGED) and len(self.get_available_channels()) > 0: - hash_mismatch = self.get_commit_hash(OVERLAY_MERGED) != self.branches[self.target_channel] - branch_mismatch = self.get_branch(OVERLAY_MERGED) != self.target_channel - return hash_mismatch or branch_mismatch - return False - - def get_branch(self, path: str) -> str: - return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], path).rstrip() - - def get_commit_hash(self, path) -> str: - return run(["git", "rev-parse", "HEAD"], path).rstrip() - - def get_current_channel(self) -> str: - return self.get_branch(BASEDIR) - - def current_channel(self) -> str: - return self.get_branch(BASEDIR) - - def describe_branch(self, basedir) -> str: - if not os.path.exists(basedir): - return "" - - version = "" - branch = "" - commit = "" - commit_date = "" - try: - branch = self.get_branch(basedir) - commit = self.get_commit_hash(basedir)[:7] - version = get_version(basedir) - - commit_unix_ts = run(["git", "show", "-s", "--format=%ct", "HEAD"], basedir).rstrip() - dt = datetime.datetime.fromtimestamp(int(commit_unix_ts)) - commit_date = dt.strftime("%b %d") - except Exception: - cloudlog.exception("updater.get_description") - return f"{version} / {branch} / {commit} / {commit_date}" - - def describe_current_channel(self) -> tuple[str, str]: - return self.describe_branch(BASEDIR), get_release_notes(BASEDIR) - - def describe_ready_channel(self) -> tuple[str, str]: - if self.update_ready(): - return self.describe_branch(FINALIZED), get_release_notes(FINALIZED) - - return "", "" - - def fetch_update(self): - cloudlog.info("attempting git fetch inside staging overlay") - - setup_git_options(OVERLAY_MERGED) - - branch = self.target_channel - git_fetch_output = run(["git", "fetch", "origin", branch], OVERLAY_MERGED) - cloudlog.info("git fetch success: %s", git_fetch_output) - - cloudlog.info("git reset in progress") - cmds = [ - ["git", "checkout", "--force", "--no-recurse-submodules", "-B", branch, "FETCH_HEAD"], - ["git", "reset", "--hard"], - ["git", "clean", "-xdff"], - ["git", "submodule", "sync"], - ["git", "submodule", "update", "--init", "--recursive"], - ["git", "submodule", "foreach", "--recursive", "git", "reset", "--hard"], - ] - r = [run(cmd, OVERLAY_MERGED) for cmd in cmds] - cloudlog.info("git reset success: %s", '\n'.join(r)) - - def fetched_path(self): - return str(OVERLAY_MERGED) - - def finalize_update(self) -> None: - """Take the current OverlayFS merged view and finalize a copy outside of - OverlayFS, ready to be swapped-in at BASEDIR. Copy using shutil.copytree""" - - # Remove the update ready flag and any old updates - cloudlog.info("creating finalized version of the overlay") - set_consistent_flag(False) - - # Copy the merged overlay view and set the update ready flag - if os.path.exists(FINALIZED): - shutil.rmtree(FINALIZED) - shutil.copytree(OVERLAY_MERGED, FINALIZED, symlinks=True) - - run(["git", "reset", "--hard"], FINALIZED) - run(["git", "submodule", "foreach", "--recursive", "git", "reset", "--hard"], FINALIZED) - - cloudlog.info("Starting git cleanup in finalized update") - t = time.monotonic() - try: - run(["git", "gc"], FINALIZED) - run(["git", "lfs", "prune"], FINALIZED) - cloudlog.event("Done git cleanup", duration=time.monotonic() - t) - except subprocess.CalledProcessError: - cloudlog.exception(f"Failed git cleanup, took {time.monotonic() - t:.3f} s") - - set_consistent_flag(True) - cloudlog.info("done finalizing overlay") diff --git a/selfdrive/updated/tests/test_base.py b/selfdrive/updated/tests/test_base.py index 9065899eb8..1d81459883 100644 --- a/selfdrive/updated/tests/test_base.py +++ b/selfdrive/updated/tests/test_base.py @@ -2,6 +2,7 @@ import os import pathlib import shutil import signal +import stat import subprocess import tempfile import time @@ -29,9 +30,27 @@ def update_release(directory, name, version, agnos_version, release_notes): with open(directory / "common" / "version.h", "w") as f: f.write(f'#define COMMA_VERSION "{version}"') - with open(directory / "launch_env.sh", "w") as f: + launch_env = directory / "launch_env.sh" + with open(launch_env, "w") as f: f.write(f'export AGNOS_VERSION="{agnos_version}"') + st = os.stat(launch_env) + os.chmod(launch_env, st.st_mode | stat.S_IEXEC) + + test_symlink = directory / "test_symlink" + if not os.path.exists(str(test_symlink)): + os.symlink("common/version.h", test_symlink) + + +def get_version(path: str) -> str: + with open(os.path.join(path, "common", "version.h")) as f: + return f.read().split('"')[1] + + +def get_consistent_flag(path: str) -> bool: + consistent_file = pathlib.Path(os.path.join(path, ".overlay_consistent")) + return consistent_file.is_file() + @pytest.mark.slow # TODO: can we test overlayfs in GHA? class BaseUpdateTest(unittest.TestCase): @@ -105,11 +124,14 @@ class BaseUpdateTest(unittest.TestCase): self.assertEqual(self.params.get_bool("UpdateAvailable"), update_available) def _test_finalized_update(self, branch, version, agnos_version, release_notes): - from openpilot.selfdrive.updated.common import get_version, get_consistent_flag # this needs to be inline because common uses environment variables self.assertTrue(self.params.get("UpdaterNewDescription", encoding="utf-8").startswith(f"{version} / {branch}")) self.assertEqual(self.params.get("UpdaterNewReleaseNotes", encoding="utf-8"), f"

{release_notes}

\n") self.assertEqual(get_version(str(self.staging_root / "finalized")), version) - self.assertEqual(get_consistent_flag(), True) + self.assertEqual(get_consistent_flag(str(self.staging_root / "finalized")), True) + self.assertTrue(os.access(str(self.staging_root / "finalized" / "launch_env.sh"), os.X_OK)) + + with open(self.staging_root / "finalized" / "test_symlink") as f: + self.assertIn(version, f.read()) def wait_for_condition(self, condition, timeout=12): start = time.monotonic() diff --git a/selfdrive/updated/updated.py b/selfdrive/updated/updated.py index 92034cc806..b6b395f254 100755 --- a/selfdrive/updated/updated.py +++ b/selfdrive/updated/updated.py @@ -1,21 +1,35 @@ #!/usr/bin/env python3 import os -from pathlib import Path +import re import datetime import subprocess import psutil +import shutil import signal import fcntl +import time import threading +from collections import defaultdict +from pathlib import Path +from markdown_it import MarkdownIt +from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.time import system_time_valid -from openpilot.selfdrive.updated.common import LOCK_FILE, STAGING_ROOT, UpdateStrategy, run, set_consistent_flag from openpilot.system.hardware import AGNOS, HARDWARE from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.alertmanager import set_offroad_alert from openpilot.system.version import is_tested_branch -from openpilot.selfdrive.updated.git import GitUpdateStrategy + +LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") +STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") + +OVERLAY_UPPER = os.path.join(STAGING_ROOT, "upper") +OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata") +OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged") +FINALIZED = os.path.join(STAGING_ROOT, "finalized") + +OVERLAY_INIT = Path(os.path.join(BASEDIR, ".overlay_init")) DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days @@ -57,13 +71,147 @@ def read_time_from_param(params, param) -> datetime.datetime | None: pass return None +def run(cmd: list[str], cwd: str = None) -> str: + return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding='utf8') + + +def set_consistent_flag(consistent: bool) -> None: + os.sync() + consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) + if consistent: + consistent_file.touch() + elif not consistent: + consistent_file.unlink(missing_ok=True) + os.sync() + +def parse_release_notes(basedir: str) -> bytes: + try: + with open(os.path.join(basedir, "RELEASES.md"), "rb") as f: + r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes + try: + return bytes(MarkdownIt().render(r.decode("utf-8")), encoding="utf-8") + except Exception: + return r + b"\n" + except FileNotFoundError: + pass + except Exception: + cloudlog.exception("failed to parse release notes") + return b"" + +def setup_git_options(cwd: str) -> None: + # We sync FS object atimes (which NEOS doesn't use) and mtimes, but ctimes + # are outside user control. Make sure Git is set up to ignore system ctimes, + # because they change when we make hard links during finalize. Otherwise, + # there is a lot of unnecessary churn. This appears to be a common need on + # OSX as well: https://www.git-tower.com/blog/make-git-rebase-safe-on-osx/ + + # We are using copytree to copy the directory, which also changes + # inode numbers. Ignore those changes too. + + # Set protocol to the new version (default after git 2.26) to reduce data + # usage on git fetch --dry-run from about 400KB to 18KB. + git_cfg = [ + ("core.trustctime", "false"), + ("core.checkStat", "minimal"), + ("protocol.version", "2"), + ("gc.auto", "0"), + ("gc.autoDetach", "false"), + ] + for option, value in git_cfg: + run(["git", "config", option, value], cwd) + + +def dismount_overlay() -> None: + if os.path.ismount(OVERLAY_MERGED): + cloudlog.info("unmounting existing overlay") + run(["sudo", "umount", "-l", OVERLAY_MERGED]) + + +def init_overlay() -> None: + + # Re-create the overlay if BASEDIR/.git has changed since we created the overlay + if OVERLAY_INIT.is_file() and os.path.ismount(OVERLAY_MERGED): + git_dir_path = os.path.join(BASEDIR, ".git") + new_files = run(["find", git_dir_path, "-newer", str(OVERLAY_INIT)]) + if not len(new_files.splitlines()): + # A valid overlay already exists + return + else: + cloudlog.info(".git directory changed, recreating overlay") + + cloudlog.info("preparing new safe staging area") + + params = Params() + params.put_bool("UpdateAvailable", False) + set_consistent_flag(False) + dismount_overlay() + run(["sudo", "rm", "-rf", STAGING_ROOT]) + if os.path.isdir(STAGING_ROOT): + shutil.rmtree(STAGING_ROOT) + + for dirname in [STAGING_ROOT, OVERLAY_UPPER, OVERLAY_METADATA, OVERLAY_MERGED]: + os.mkdir(dirname, 0o755) + + if os.lstat(BASEDIR).st_dev != os.lstat(OVERLAY_MERGED).st_dev: + raise RuntimeError("base and overlay merge directories are on different filesystems; not valid for overlay FS!") + + # Leave a timestamped canary in BASEDIR to check at startup. The device clock + # should be correct by the time we get here. If the init file disappears, or + # critical mtimes in BASEDIR are newer than .overlay_init, continue.sh can + # assume that BASEDIR has used for local development or otherwise modified, + # and skips the update activation attempt. + consistent_file = Path(os.path.join(BASEDIR, ".overlay_consistent")) + if consistent_file.is_file(): + consistent_file.unlink() + OVERLAY_INIT.touch() + + os.sync() + overlay_opts = f"lowerdir={BASEDIR},upperdir={OVERLAY_UPPER},workdir={OVERLAY_METADATA}" + + mount_cmd = ["mount", "-t", "overlay", "-o", overlay_opts, "none", OVERLAY_MERGED] + run(["sudo"] + mount_cmd) + run(["sudo", "chmod", "755", os.path.join(OVERLAY_METADATA, "work")]) + + git_diff = run(["git", "diff"], OVERLAY_MERGED) + params.put("GitDiff", git_diff) + cloudlog.info(f"git diff output:\n{git_diff}") + + +def finalize_update() -> None: + """Take the current OverlayFS merged view and finalize a copy outside of + OverlayFS, ready to be swapped-in at BASEDIR. Copy using shutil.copytree""" + + # Remove the update ready flag and any old updates + cloudlog.info("creating finalized version of the overlay") + set_consistent_flag(False) + + # Copy the merged overlay view and set the update ready flag + if os.path.exists(FINALIZED): + shutil.rmtree(FINALIZED) + shutil.copytree(OVERLAY_MERGED, FINALIZED, symlinks=True) + + run(["git", "reset", "--hard"], FINALIZED) + run(["git", "submodule", "foreach", "--recursive", "git", "reset", "--hard"], FINALIZED) + + cloudlog.info("Starting git cleanup in finalized update") + t = time.monotonic() + try: + run(["git", "gc"], FINALIZED) + run(["git", "lfs", "prune"], FINALIZED) + cloudlog.event("Done git cleanup", duration=time.monotonic() - t) + except subprocess.CalledProcessError: + cloudlog.exception(f"Failed git cleanup, took {time.monotonic() - t:.3f} s") + + set_consistent_flag(True) + cloudlog.info("done finalizing overlay") + -def handle_agnos_update(fetched_path) -> None: +def handle_agnos_update() -> None: from openpilot.system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number cur_version = HARDWARE.get_os_version() updated_version = run(["bash", "-c", r"unset AGNOS_VERSION && source launch_env.sh && \ - echo -n $AGNOS_VERSION"], fetched_path).strip() + echo -n $AGNOS_VERSION"], OVERLAY_MERGED).strip() cloudlog.info(f"AGNOS version check: {cur_version} vs {updated_version}") if cur_version == updated_version: @@ -75,44 +223,61 @@ def handle_agnos_update(fetched_path) -> None: cloudlog.info(f"Beginning background installation for AGNOS {updated_version}") set_offroad_alert("Offroad_NeosUpdate", True) - manifest_path = os.path.join(fetched_path, "system/hardware/tici/agnos.json") + manifest_path = os.path.join(OVERLAY_MERGED, "system/hardware/tici/agnos.json") target_slot_number = get_target_slot_number() flash_agnos_update(manifest_path, target_slot_number, cloudlog) set_offroad_alert("Offroad_NeosUpdate", False) -STRATEGY = { - "git": GitUpdateStrategy, -} - class Updater: def __init__(self): self.params = Params() + self.branches = defaultdict(str) self._has_internet: bool = False - self.strategy: UpdateStrategy = STRATEGY[os.environ.get("UPDATER_STRATEGY", "git")]() - @property def has_internet(self) -> bool: return self._has_internet - def init(self): - self.strategy.init() + @property + def target_branch(self) -> str: + b: str | None = self.params.get("UpdaterTargetBranch", encoding='utf-8') + if b is None: + b = self.get_branch(BASEDIR) + return b - def cleanup(self): - self.strategy.cleanup() + @property + def update_ready(self) -> bool: + consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) + if consistent_file.is_file(): + hash_mismatch = self.get_commit_hash(BASEDIR) != self.branches[self.target_branch] + branch_mismatch = self.get_branch(BASEDIR) != self.target_branch + on_target_branch = self.get_branch(FINALIZED) == self.target_branch + return ((hash_mismatch or branch_mismatch) and on_target_branch) + return False - def set_params(self, update_success: bool, failed_count: int, exception: str | None) -> None: - self.params.put("UpdateFailedCount", str(failed_count)) + @property + def update_available(self) -> bool: + if os.path.isdir(OVERLAY_MERGED) and len(self.branches) > 0: + hash_mismatch = self.get_commit_hash(OVERLAY_MERGED) != self.branches[self.target_branch] + branch_mismatch = self.get_branch(OVERLAY_MERGED) != self.target_branch + return hash_mismatch or branch_mismatch + return False + + def get_branch(self, path: str) -> str: + return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], path).rstrip() - if self.params.get("UpdaterTargetBranch") is None: - self.params.put("UpdaterTargetBranch", self.strategy.current_channel()) + def get_commit_hash(self, path: str = OVERLAY_MERGED) -> str: + return run(["git", "rev-parse", "HEAD"], path).rstrip() - self.params.put_bool("UpdaterFetchAvailable", self.strategy.update_available()) + def set_params(self, update_success: bool, failed_count: int, exception: str | None) -> None: + self.params.put("UpdateFailedCount", str(failed_count)) + self.params.put("UpdaterTargetBranch", self.target_branch) - available_channels = self.strategy.get_available_channels() - self.params.put("UpdaterAvailableBranches", ','.join(available_channels)) + self.params.put_bool("UpdaterFetchAvailable", self.update_available) + if len(self.branches): + self.params.put("UpdaterAvailableBranches", ','.join(self.branches.keys())) last_update = datetime.datetime.utcnow() if update_success: @@ -127,14 +292,32 @@ class Updater: else: self.params.put("LastUpdateException", exception) - description_current, release_notes_current = self.strategy.describe_current_channel() - description_ready, release_notes_ready = self.strategy.describe_ready_channel() + # Write out current and new version info + def get_description(basedir: str) -> str: + if not os.path.exists(basedir): + return "" - self.params.put("UpdaterCurrentDescription", description_current) - self.params.put("UpdaterCurrentReleaseNotes", release_notes_current) - self.params.put("UpdaterNewDescription", description_ready) - self.params.put("UpdaterNewReleaseNotes", release_notes_ready) - self.params.put_bool("UpdateAvailable", self.strategy.update_ready()) + version = "" + branch = "" + commit = "" + commit_date = "" + try: + branch = self.get_branch(basedir) + commit = self.get_commit_hash(basedir)[:7] + with open(os.path.join(basedir, "common", "version.h")) as f: + version = f.read().split('"')[1] + + commit_unix_ts = run(["git", "show", "-s", "--format=%ct", "HEAD"], basedir).rstrip() + dt = datetime.datetime.fromtimestamp(int(commit_unix_ts)) + commit_date = dt.strftime("%b %d") + except Exception: + cloudlog.exception("updater.get_description") + return f"{version} / {branch} / {commit} / {commit_date}" + self.params.put("UpdaterCurrentDescription", get_description(BASEDIR)) + self.params.put("UpdaterCurrentReleaseNotes", parse_release_notes(BASEDIR)) + self.params.put("UpdaterNewDescription", get_description(FINALIZED)) + self.params.put("UpdaterNewReleaseNotes", parse_release_notes(FINALIZED)) + self.params.put_bool("UpdateAvailable", self.update_ready) # Handle user prompt for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"): @@ -158,24 +341,67 @@ class Updater: def check_for_update(self) -> None: cloudlog.info("checking for updates") - self.strategy.update_available() + excluded_branches = ('release2', 'release2-staging') + + try: + run(["git", "ls-remote", "origin", "HEAD"], OVERLAY_MERGED) + self._has_internet = True + except subprocess.CalledProcessError: + self._has_internet = False + + setup_git_options(OVERLAY_MERGED) + output = run(["git", "ls-remote", "--heads"], OVERLAY_MERGED) + + self.branches = defaultdict(lambda: None) + for line in output.split('\n'): + ls_remotes_re = r'(?P\b[0-9a-f]{5,40}\b)(\s+)(refs\/heads\/)(?P.*$)' + x = re.fullmatch(ls_remotes_re, line.strip()) + if x is not None and x.group('branch_name') not in excluded_branches: + self.branches[x.group('branch_name')] = x.group('commit_sha') + + cur_branch = self.get_branch(OVERLAY_MERGED) + cur_commit = self.get_commit_hash(OVERLAY_MERGED) + new_branch = self.target_branch + new_commit = self.branches[new_branch] + if (cur_branch, cur_commit) != (new_branch, new_commit): + cloudlog.info(f"update available, {cur_branch} ({str(cur_commit)[:7]}) -> {new_branch} ({str(new_commit)[:7]})") + else: + cloudlog.info(f"up to date on {cur_branch} ({str(cur_commit)[:7]})") def fetch_update(self) -> None: + cloudlog.info("attempting git fetch inside staging overlay") + self.params.put("UpdaterState", "downloading...") # TODO: cleanly interrupt this and invalidate old update set_consistent_flag(False) self.params.put_bool("UpdateAvailable", False) - self.strategy.fetch_update() + setup_git_options(OVERLAY_MERGED) + + branch = self.target_branch + git_fetch_output = run(["git", "fetch", "origin", branch], OVERLAY_MERGED) + cloudlog.info("git fetch success: %s", git_fetch_output) + + cloudlog.info("git reset in progress") + cmds = [ + ["git", "checkout", "--force", "--no-recurse-submodules", "-B", branch, "FETCH_HEAD"], + ["git", "reset", "--hard"], + ["git", "clean", "-xdff"], + ["git", "submodule", "sync"], + ["git", "submodule", "update", "--init", "--recursive"], + ["git", "submodule", "foreach", "--recursive", "git", "reset", "--hard"], + ] + r = [run(cmd, OVERLAY_MERGED) for cmd in cmds] + cloudlog.info("git reset success: %s", '\n'.join(r)) # TODO: show agnos download progress if AGNOS: - handle_agnos_update(self.strategy.fetched_path()) + handle_agnos_update() # Create the finalized, ready-to-swap update self.params.put("UpdaterState", "finalizing update...") - self.strategy.finalize_update() + finalize_update() cloudlog.info("finalize success!") @@ -224,7 +450,7 @@ def main() -> None: exception = None try: # TODO: reuse overlay from previous updated instance if it looks clean - updater.init() + init_overlay() # ensure we have some params written soon after startup updater.set_params(False, update_failed_count, exception) @@ -260,11 +486,11 @@ def main() -> None: returncode=e.returncode ) exception = f"command failed: {e.cmd}\n{e.output}" - updater.cleanup() + OVERLAY_INIT.unlink(missing_ok=True) except Exception as e: cloudlog.exception("uncaught updated exception, shouldn't happen") exception = str(e) - updater.cleanup() + OVERLAY_INIT.unlink(missing_ok=True) try: params.put("UpdaterState", "idle") diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index c80dc19fce..fdea60a282 100755 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -24,7 +24,7 @@ from openpilot.system.version import get_version from openpilot.tools.lib.helpers import RE from openpilot.tools.lib.logreader import LogReader from cereal.visionipc import VisionIpcServer, VisionStreamType -from openpilot.common.transformations.camera import tici_f_frame_size, tici_d_frame_size, tici_e_frame_size +from openpilot.common.transformations.camera import DEVICE_CAMERAS SentinelType = log.Sentinel.SentinelType @@ -142,10 +142,11 @@ class TestLoggerd: os.environ["LOGGERD_TEST"] = "1" Params().put("RecordFront", "1") + d = DEVICE_CAMERAS[("tici", "ar0231")] expected_files = {"rlog", "qlog", "qcamera.ts", "fcamera.hevc", "dcamera.hevc", "ecamera.hevc"} - streams = [(VisionStreamType.VISION_STREAM_ROAD, (*tici_f_frame_size, 2048*2346, 2048, 2048*1216), "roadCameraState"), - (VisionStreamType.VISION_STREAM_DRIVER, (*tici_d_frame_size, 2048*2346, 2048, 2048*1216), "driverCameraState"), - (VisionStreamType.VISION_STREAM_WIDE_ROAD, (*tici_e_frame_size, 2048*2346, 2048, 2048*1216), "wideRoadCameraState")] + streams = [(VisionStreamType.VISION_STREAM_ROAD, (d.fcam.width, d.fcam.height, 2048*2346, 2048, 2048*1216), "roadCameraState"), + (VisionStreamType.VISION_STREAM_DRIVER, (d.dcam.width, d.dcam.height, 2048*2346, 2048, 2048*1216), "driverCameraState"), + (VisionStreamType.VISION_STREAM_WIDE_ROAD, (d.ecam.width, d.ecam.height, 2048*2346, 2048, 2048*1216), "wideRoadCameraState")] pm = messaging.PubMaster(["roadCameraState", "driverCameraState", "wideRoadCameraState"]) vipc_server = VisionIpcServer("camerad") diff --git a/system/qcomgpsd/cgpsd.py b/system/qcomgpsd/cgpsd.py deleted file mode 100755 index 04a92d4a45..0000000000 --- a/system/qcomgpsd/cgpsd.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python3 -import time -import datetime -from collections import defaultdict - -from cereal import log -import cereal.messaging as messaging -from openpilot.common.swaglog import cloudlog -from openpilot.system.qcomgpsd.qcomgpsd import at_cmd, wait_for_modem - -# https://campar.in.tum.de/twiki/pub/Chair/NaviGpsDemon/nmea.html#RMC -""" -AT+CGPSGPOS=1 -response: '$GNGGA,220212.00,3245.09188,N,11711.76362,W,1,06,24.54,0.0,M,,M,,*77' - -AT+CGPSGPOS=2 -response: '$GNGSA,A,3,06,17,19,22,,,,,,,,,14.11,8.95,10.91,1*01 -$GNGSA,A,3,29,26,,,,,,,,,,,14.11,8.95,10.91,4*03' - -AT+CGPSGPOS=3 -response: '$GPGSV,3,1,11,06,55,047,22,19,29,053,20,22,19,115,14,05,01,177,,0*68 -$GPGSV,3,2,11,11,77,156,23,12,47,322,17,17,08,066,10,20,25,151,,0*6D -$GPGSV,3,3,11,24,44,232,,25,16,312,,29,02,260,,0*5D' - -AT+CGPSGPOS=4 -response: '$GBGSV,1,1,03,26,75,242,20,29,19,049,16,35,,,24,0*7D' - -AT+CGPSGPOS=5 -response: '$GNRMC,220216.00,A,3245.09531,N,11711.76043,W,,,070324,,,A,V*20' -""" - - -def sfloat(n: str): - return float(n) if len(n) > 0 else 0 - -def checksum(s: str): - ret = 0 - for c in s[1:-3]: - ret ^= ord(c) - return format(ret, '02X') - -def main(): - wait_for_modem("AT+CGPS?") - - cmds = [ - "AT+GPSPORT=1", - "AT+CGPS=1", - ] - for c in cmds: - at_cmd(c) - - nmea = defaultdict(list) - pm = messaging.PubMaster(['gpsLocation']) - while True: - time.sleep(1) - try: - # TODO: read from streaming AT port instead of polling - out = at_cmd("AT+CGPS?") - - sentences = out.split("'")[1].splitlines() - new = {l.split(',')[0]: l.split(',') for l in sentences if l.startswith('$G')} - nmea.update(new) - if '$GNRMC' not in new: - print(f"no GNRMC:\n{out}\n") - continue - - # validate checksums - for s in nmea.values(): - sent = ','.join(s) - if checksum(sent) != s[-1].split('*')[1]: - cloudlog.error(f"invalid checksum: {repr(sent)}") - continue - - gnrmc = nmea['$GNRMC'] - #print(gnrmc) - - msg = messaging.new_message('gpsLocation', valid=True) - gps = msg.gpsLocation - gps.latitude = (sfloat(gnrmc[3][:2]) + (sfloat(gnrmc[3][2:]) / 60)) * (1 if gnrmc[4] == "N" else -2) - gps.longitude = (sfloat(gnrmc[5][:3]) + (sfloat(gnrmc[5][3:]) / 60)) * (1 if gnrmc[6] == "E" else -1) - - date = gnrmc[9][:6] - dt = datetime.datetime.strptime(f"{date} {gnrmc[1]}", '%d%m%y %H%M%S.%f') - gps.unixTimestampMillis = dt.timestamp()*1e3 - - gps.hasFix = gnrmc[1] == 'A' - - # TODO: make our own source - gps.source = log.GpsLocationData.SensorSource.qcomdiag - - gps.speed = sfloat(gnrmc[7]) - gps.bearingDeg = sfloat(gnrmc[8]) - - if len(nmea['$GNGGA']): - gngga = nmea['$GNGGA'] - if gngga[10] == 'M': - gps.altitude = sfloat(gngga[9]) - - if len(nmea['$GNGSA']): - # TODO: this is only for GPS sats - gngsa = nmea['$GNGSA'] - gps.horizontalAccuracy = sfloat(gngsa[4]) - gps.verticalAccuracy = sfloat(gngsa[5]) - - # TODO: set these from the module - gps.bearingAccuracyDeg = 5. - gps.speedAccuracy = 3. - - # TODO: can we get this from the NMEA sentences? - #gps.vNED = vNED - - pm.send('gpsLocation', msg) - - except Exception: - cloudlog.exception("gps.issue") - - -if __name__ == "__main__": - main() diff --git a/system/timed.py b/system/timed.py index 39acb2ba12..ab82f8c72d 100755 --- a/system/timed.py +++ b/system/timed.py @@ -56,7 +56,6 @@ def main() -> NoReturn: """ params = Params() - tf = TimezoneFinder() # Restore timezone from param tz = params.get("Timezone", encoding='utf8') diff --git a/system/sensord/pigeond.py b/system/ubloxd/pigeond.py similarity index 100% rename from system/sensord/pigeond.py rename to system/ubloxd/pigeond.py diff --git a/system/sensord/tests/test_pigeond.py b/system/ubloxd/tests/test_pigeond.py similarity index 100% rename from system/sensord/tests/test_pigeond.py rename to system/ubloxd/tests/test_pigeond.py diff --git a/system/ugpsd.py b/system/ugpsd.py new file mode 100755 index 0000000000..34b20b01c8 --- /dev/null +++ b/system/ugpsd.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +import os +import time +import traceback +import serial +import datetime +import numpy as np +from collections import defaultdict + +from cereal import log +import cereal.messaging as messaging +from openpilot.common.retry import retry +from openpilot.common.swaglog import cloudlog +from openpilot.system.qcomgpsd.qcomgpsd import at_cmd, wait_for_modem + + +def sfloat(n: str): + return float(n) if len(n) > 0 else 0 + +def checksum(s: str): + ret = 0 + for c in s[1:-3]: + ret ^= ord(c) + return format(ret, '02X') + +class Unicore: + def __init__(self): + self.s = serial.Serial('/dev/ttyHS0', 115200) + self.s.timeout = 1 + self.s.writeTimeout = 1 + self.s.newline = b'\r\n' + + self.s.flush() + self.s.reset_input_buffer() + self.s.reset_output_buffer() + self.s.read(2048) + + def send(self, cmd): + self.s.write(cmd.encode('utf8') + b'\r') + resp = self.s.read(2048) + print(len(resp), cmd, "\n", resp) + assert b"OK" in resp + + def recv(self): + return self.s.readline() + +def build_msg(state): + """ + NMEA sentences: + https://campar.in.tum.de/twiki/pub/Chair/NaviGpsDemon/nmea.html#RMC + NAV messages: + https://www.unicorecomm.com/assets/upload/file/UFirebird_Standard_Positioning_Products_Protocol_Specification_CH.pdf + """ + + msg = messaging.new_message('gpsLocation', valid=True) + gps = msg.gpsLocation + + gnrmc = state['$GNRMC'] + gps.hasFix = gnrmc[1] == 'A' + gps.source = log.GpsLocationData.SensorSource.unicore + gps.latitude = (sfloat(gnrmc[3][:2]) + (sfloat(gnrmc[3][2:]) / 60)) * (1 if gnrmc[4] == "N" else -1) + gps.longitude = (sfloat(gnrmc[5][:3]) + (sfloat(gnrmc[5][3:]) / 60)) * (1 if gnrmc[6] == "E" else -1) + + try: + date = gnrmc[9][:6] + dt = datetime.datetime.strptime(f"{date} {gnrmc[1]}", '%d%m%y %H%M%S.%f') + gps.unixTimestampMillis = dt.timestamp()*1e3 + except Exception: + pass + + gps.bearingDeg = sfloat(gnrmc[8]) + + if len(state['$GNGGA']): + gngga = state['$GNGGA'] + if gngga[10] == 'M': + gps.altitude = sfloat(gngga[9]) + + if len(state['$GNGSA']): + gngsa = state['$GNGSA'] + gps.horizontalAccuracy = sfloat(gngsa[4]) + gps.verticalAccuracy = sfloat(gngsa[5]) + + #if len(state['$NAVACC']): + # # $NAVVEL,264415000,5,3,0.375,0.141,-0.735,-65.450*2A + # navacc = state['$NAVACC'] + # gps.horizontalAccuracy = sfloat(navacc[3]) + # gps.speedAccuracy = sfloat(navacc[4]) + # gps.bearingAccuracyDeg = sfloat(navacc[5]) + + if len(state['$NAVVEL']): + # $NAVVEL,264415000,5,3,0.375,0.141,-0.735,-65.450*2A + navvel = state['$NAVVEL'] + vECEF = [ + sfloat(navvel[4]), + sfloat(navvel[5]), + sfloat(navvel[6]), + ] + + lat = np.radians(gps.latitude) + lon = np.radians(gps.longitude) + R = np.array([ + [-np.sin(lat) * np.cos(lon), -np.sin(lon), -np.cos(lat) * np.cos(lon)], + [-np.sin(lat) * np.sin(lon), np.cos(lon), -np.cos(lat) * np.sin(lon)], + [np.cos(lat), 0, -np.sin(lat)] + ]) + + vNED = [float(x) for x in R.dot(vECEF)] + gps.vNED = vNED + gps.speed = np.linalg.norm(vNED) + + # TODO: set these from the module + gps.bearingAccuracyDeg = 5. + gps.speedAccuracy = 3. + + return msg + + +@retry(attempts=10, delay=0.1) +def setup(u): + at_cmd('AT+CGPS=0') + at_cmd('AT+CGPS=1') + time.sleep(1.0) + + # setup NAVXXX outputs + for i in range(4): + u.send(f"$CFGMSG,1,{i},1") + for i in (1, 3): + u.send(f"$CFGMSG,3,{i},1") + + # 10Hz NAV outputs + u.send("$CFGNAV,100,100,1000") + + +def main(): + wait_for_modem("AT+CGPS?") + + u = Unicore() + setup(u) + + state = defaultdict(list) + pm = messaging.PubMaster(['gpsLocation']) + while True: + try: + msg = u.recv().decode('utf8').strip() + if "DEBUG" in os.environ: + print(repr(msg)) + + if len(msg) > 0: + if checksum(msg) != msg.split('*')[1]: + cloudlog.error(f"invalid checksum: {repr(msg)}") + continue + + k = msg.split(',')[0] + state[k] = msg.split(',') + if '$GNRMC' not in msg: + continue + + pm.send('gpsLocation', build_msg(state)) + except Exception: + traceback.print_exc() + cloudlog.exception("gps.issue") + + +if __name__ == "__main__": + main() diff --git a/system/version.py b/system/version.py index 4319ef2140..7ae8313089 100755 --- a/system/version.py +++ b/system/version.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 import os import subprocess -from typing import TypeVar -from collections.abc import Callable -from functools import lru_cache + from openpilot.common.basedir import BASEDIR from openpilot.common.swaglog import cloudlog +from openpilot.common.utils import cache +from openpilot.common.git import get_origin, get_branch, get_short_branch, get_normalized_origin, get_commit_date + RELEASE_BRANCHES = ['release3-staging', 'release3', 'nightly'] TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging'] @@ -14,66 +15,17 @@ TESTED_BRANCHES = RELEASE_BRANCHES + ['devel', 'devel-staging'] training_version: bytes = b"0.2.0" terms_version: bytes = b"2" -_RT = TypeVar("_RT") -def cache(user_function: Callable[..., _RT], /) -> Callable[..., _RT]: - return lru_cache(maxsize=None)(user_function) - - -def run_cmd(cmd: list[str]) -> str: - return subprocess.check_output(cmd, encoding='utf8').strip() - - -def run_cmd_default(cmd: list[str], default: str = "") -> str: - try: - return run_cmd(cmd) - except subprocess.CalledProcessError: - return default - - -@cache -def get_commit(branch: str = "HEAD") -> str: - return run_cmd_default(["git", "rev-parse", branch]) - - -@cache -def get_commit_date(commit: str = "HEAD") -> str: - return run_cmd_default(["git", "show", "--no-patch", "--format='%ct %ci'", commit]) - - -@cache -def get_short_branch() -> str: - return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "HEAD"]) - - -@cache -def get_branch() -> str: - return run_cmd_default(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]) - - -@cache -def get_origin() -> str: - try: - local_branch = run_cmd(["git", "name-rev", "--name-only", "HEAD"]) - tracking_remote = run_cmd(["git", "config", "branch." + local_branch + ".remote"]) - return run_cmd(["git", "config", "remote." + tracking_remote + ".url"]) - except subprocess.CalledProcessError: # Not on a branch, fallback - return run_cmd_default(["git", "config", "--get", "remote.origin.url"]) +def get_version(path: str = BASEDIR) -> str: + with open(os.path.join(path, "common", "version.h")) as _versionf: + version = _versionf.read().split('"')[1] + return version -@cache -def get_normalized_origin() -> str: - return get_origin() \ - .replace("git@", "", 1) \ - .replace(".git", "", 1) \ - .replace("https://", "", 1) \ - .replace(":", "/", 1) +def get_release_notes(path: str = BASEDIR) -> str: + with open(os.path.join(path, "RELEASES.md"), "r") as f: + return f.read().split('\n\n', 1)[0] -@cache -def get_version() -> str: - with open(os.path.join(BASEDIR, "common", "version.h")) as _versionf: - version = _versionf.read().split('"')[1] - return version @cache def get_short_version() -> str: diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc index fbbb54fd58..e7f7fdc6ef 100644 --- a/tools/cabana/dbc/dbcfile.cc +++ b/tools/cabana/dbc/dbcfile.cc @@ -98,10 +98,13 @@ void DBCFile::parse(const QString &content) { QTextStream stream((QString *)&content); cabana::Msg *current_msg = nullptr; int multiplexor_cnt = 0; + bool seen_first = false; while (!stream.atEnd()) { ++line_num; QString raw_line = stream.readLine(); line = raw_line.trimmed(); + + bool seen = true; if (line.startsWith("BO_ ")) { multiplexor_cnt = 0; auto match = bo_regexp.match(line); @@ -182,6 +185,14 @@ void DBCFile::parse(const QString &content) { if (auto s = get_sig(match.captured(1).toUInt(), match.captured(2))) { s->comment = match.captured(3).trimmed(); } + } else { + seen = false; + } + + if (seen) { + seen_first = true; + } else if (!seen_first) { + header += raw_line + "\n"; } } @@ -191,12 +202,12 @@ void DBCFile::parse(const QString &content) { } QString DBCFile::generateDBC() { - QString dbc_string, signal_comment, message_comment, val_desc; + QString dbc_string, comment, val_desc; for (const auto &[address, m] : msgs) { const QString transmitter = m.transmitter.isEmpty() ? DEFAULT_NODE_NAME : m.transmitter; dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(transmitter); if (!m.comment.isEmpty()) { - message_comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(m.comment); + comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(m.comment); } for (auto sig : m.getSignals()) { QString multiplexer_indicator; @@ -219,7 +230,7 @@ QString DBCFile::generateDBC() { .arg(sig->unit) .arg(sig->receiver_name.isEmpty() ? DEFAULT_NODE_NAME : sig->receiver_name); if (!sig->comment.isEmpty()) { - signal_comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment); + comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment); } if (!sig->val_desc.empty()) { QStringList text; @@ -231,5 +242,5 @@ QString DBCFile::generateDBC() { } dbc_string += "\n"; } - return dbc_string + message_comment + signal_comment + val_desc; + return header + dbc_string + comment + val_desc; } diff --git a/tools/cabana/dbc/dbcfile.h b/tools/cabana/dbc/dbcfile.h index 551bac4946..29f19a80e4 100644 --- a/tools/cabana/dbc/dbcfile.h +++ b/tools/cabana/dbc/dbcfile.h @@ -34,6 +34,7 @@ public: private: void parse(const QString &content); + QString header; std::map msgs; QString name_; }; diff --git a/tools/cabana/dbc/generate_dbc_json.py b/tools/cabana/dbc/generate_dbc_json.py index 5a8ef21d8b..dec1766a7e 100755 --- a/tools/cabana/dbc/generate_dbc_json.py +++ b/tools/cabana/dbc/generate_dbc_json.py @@ -6,7 +6,7 @@ from openpilot.selfdrive.car.values import create_platform_map def generate_dbc_json() -> str: - dbc_map = create_platform_map(lambda platform: platform.config.dbc_dict["pt"] if platform != "mock" else None) + dbc_map = create_platform_map(lambda platform: platform.config.dbc_dict["pt"] if platform != "MOCK" else None) return json.dumps(dict(sorted(dbc_map.items())), indent=2) diff --git a/tools/cabana/messageswidget.cc b/tools/cabana/messageswidget.cc index 0cec551017..720553dcb3 100644 --- a/tools/cabana/messageswidget.cc +++ b/tools/cabana/messageswidget.cc @@ -85,7 +85,9 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget Byte color
constant changing
increasing
- decreasing + decreasing
+ Shortcuts
+ Horizontal Scrolling:  shift+wheel  )")); } @@ -391,6 +393,14 @@ void MessageView::updateBytesSectionSize() { header()->resizeSection(MessageListModel::Column::DATA, delegate->sizeForBytes(max_bytes).width()); } +void MessageView::wheelEvent(QWheelEvent *event) { + if (event->modifiers() == Qt::ShiftModifier) { + QApplication::sendEvent(horizontalScrollBar(), event); + } else { + QTreeView::wheelEvent(event); + } +} + // MessageViewHeader MessageViewHeader::MessageViewHeader(QWidget *parent) : QHeaderView(Qt::Horizontal, parent) { diff --git a/tools/cabana/messageswidget.h b/tools/cabana/messageswidget.h index 4f54941c64..e7f1f8c033 100644 --- a/tools/cabana/messageswidget.h +++ b/tools/cabana/messageswidget.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "tools/cabana/dbc/dbcmanager.h" #include "tools/cabana/streams/abstractstream.h" @@ -65,10 +66,13 @@ class MessageView : public QTreeView { Q_OBJECT public: MessageView(QWidget *parent) : QTreeView(parent) {} + void updateBytesSectionSize(); + +protected: void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override {} void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()) override; - void updateBytesSectionSize(); + void wheelEvent(QWheelEvent *event) override; }; class MessageViewHeader : public QHeaderView { diff --git a/tools/cabana/streams/abstractstream.cc b/tools/cabana/streams/abstractstream.cc index 8a20086b5c..afb1ec200c 100644 --- a/tools/cabana/streams/abstractstream.cc +++ b/tools/cabana/streams/abstractstream.cc @@ -127,22 +127,27 @@ const CanData &AbstractStream::lastMessage(const MessageId &id) { // it is thread safe to update data in updateLastMsgsTo. // updateLastMsgsTo is always called in UI thread. void AbstractStream::updateLastMsgsTo(double sec) { - new_msgs_.clear(); - messages_.clear(); - current_sec_ = sec; uint64_t last_ts = (sec + routeStartTime()) * 1e9; + std::unordered_map msgs; + for (const auto &[id, ev] : events_) { auto it = std::upper_bound(ev.begin(), ev.end(), last_ts, CompareCanEvent()); if (it != ev.begin()) { auto prev = std::prev(it); double ts = (*prev)->mono_time / 1e9 - routeStartTime(); - auto &m = messages_[id]; + auto &m = msgs[id]; + // Keep last changes + if (auto old_m = messages_.find(id); old_m != messages_.end()) { + m.last_changes = old_m->second.last_changes; + } m.compute(id, (*prev)->dat, (*prev)->size, ts, getSpeed(), {}); m.count = std::distance(ev.begin(), prev) + 1; } } + new_msgs_.clear(); + messages_ = std::move(msgs); bool id_changed = messages_.size() != last_msgs.size() || std::any_of(messages_.cbegin(), messages_.cend(), [this](const auto &m) { return !last_msgs.count(m.first); }); @@ -183,8 +188,6 @@ void AbstractStream::mergeEvents(const std::vector &events) { lastest_event_ts = all_events_.empty() ? 0 : all_events_.back()->mono_time; } -// CanData - namespace { enum Color { GREYISH_BLUE, CYAN, RED}; diff --git a/tools/cabana/streams/replaystream.h b/tools/cabana/streams/replaystream.h index b4e4be4db6..d92a2e426b 100644 --- a/tools/cabana/streams/replaystream.h +++ b/tools/cabana/streams/replaystream.h @@ -23,7 +23,7 @@ public: inline QString routeName() const override { return replay->route()->name(); } inline QString carFingerprint() const override { return replay->carFingerprint().c_str(); } double totalSeconds() const override { return replay->totalSeconds(); } - inline QDateTime beginDateTime() const { return replay->route()->datetime(); } + inline QDateTime beginDateTime() const { return replay->routeDateTime(); } inline double routeStartTime() const override { return replay->routeStartTime() / (double)1e9; } inline const Route *route() const { return replay->route(); } inline void setSpeed(float speed) override { replay->setSpeed(speed); } diff --git a/tools/cabana/tests/test_cabana.cc b/tools/cabana/tests/test_cabana.cc index bf7550be0b..98c2de12b6 100644 --- a/tools/cabana/tests/test_cabana.cc +++ b/tools/cabana/tests/test_cabana.cc @@ -28,6 +28,43 @@ TEST_CASE("DBCFile::generateDBC") { } } +TEST_CASE("DBCFile::generateDBC - comment order") { + // Ensure that message comments are followed by signal comments and in the correct order + auto content = R"(BO_ 160 message_1: 8 EON + SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX + +BO_ 162 message_2: 8 EON + SG_ signal_2 : 0|12@1+ (1,0) [0|4095] "unit" XXX + +CM_ BO_ 160 "message comment"; +CM_ SG_ 160 signal_1 "signal comment"; +CM_ BO_ 162 "message comment"; +CM_ SG_ 162 signal_2 "signal comment"; +)"; + DBCFile dbc("", content); + REQUIRE(dbc.generateDBC() == content); +} + +TEST_CASE("DBCFile::generateDBC -- preserve original header") { + QString content = R"(VERSION "1.0" + +NS_ : + CM_ + +BS_: + +BU_: EON + +BO_ 160 message_1: 8 EON + SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX + +CM_ BO_ 160 "message comment"; +CM_ SG_ 160 signal_1 "signal comment"; +)"; + DBCFile dbc("", content); + REQUIRE(dbc.generateDBC() == content); +} + TEST_CASE("parse_dbc") { QString content = R"( BO_ 160 message_1: 8 EON diff --git a/tools/car_porting/README.md b/tools/car_porting/README.md index 8db17b0976..a32e9f96c9 100644 --- a/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -21,8 +21,8 @@ Given a route and platform, automatically inserts FW fingerprints from the platf Example: ```bash -> python tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'SUBARU OUTBACK 6TH GEN' -Attempting to add fw version for: SUBARU OUTBACK 6TH GEN +> python tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK' +Attempting to add fw version for: OUTBACK ``` ### [selfdrive/car/tests/test_car_interfaces.py](/selfdrive/car/tests/test_car_interfaces.py) diff --git a/tools/car_porting/auto_fingerprint.py b/tools/car_porting/auto_fingerprint.py index f122c2774e..8b0ae6762d 100755 --- a/tools/car_porting/auto_fingerprint.py +++ b/tools/car_porting/auto_fingerprint.py @@ -46,7 +46,7 @@ if __name__ == "__main__": if len(possible_platforms) != 1: print(f"Unable to auto-determine platform, possible platforms: {possible_platforms}") - if carPlatform != "mock": + if carPlatform != "MOCK": print("Using platform from route") platform = carPlatform else: diff --git a/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb b/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb index dd223667d8..99efc45aca 100644 --- a/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb +++ b/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -27,18 +27,18 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "PLATFORM_CODES = {\n", " Ecu.abs: {\n", " 0: {\n", - " b'\\xa5': [CAR.ASCENT, CAR.ASCENT_2023],\n", - " b'\\xa2': [CAR.IMPREZA, CAR.IMPREZA_2020, CAR.CROSSTREK_HYBRID],\n", - " b'\\xa1': [CAR.OUTBACK, CAR.LEGACY, CAR.OUTBACK_2023],\n", - " b'\\xa3': [CAR.FORESTER, CAR.FORESTER_HYBRID, CAR.FORESTER_2022],\n", - " b'z': [CAR.IMPREZA],\n", + " b'\\xa5': [CAR.SUBARU_ASCENT, CAR.SUBARU_ASCENT_2023],\n", + " b'\\xa2': [CAR.SUBARU_IMPREZA, CAR.SUBARU_IMPREZA_2020, CAR.SUBARU_CROSSTREK_HYBRID],\n", + " b'\\xa1': [CAR.SUBARU_OUTBACK, CAR.SUBARU_LEGACY, CAR.SUBARU_OUTBACK_2023],\n", + " b'\\xa3': [CAR.SUBARU_FORESTER, CAR.SUBARU_FORESTER_HYBRID, CAR.SUBARU_FORESTER_2022],\n", + " b'z': [CAR.SUBARU_IMPREZA],\n", " }\n", " }\n", "}\n", @@ -146,10 +146,10 @@ ], "source": [ "def test_year_code(platform, year):\n", - " car_info = CAR(platform).config.car_info\n", - " if isinstance(car_info, list):\n", - " car_info = car_info[0]\n", - " years = [int(y) for y in car_info.year_list]\n", + " car_docs = CAR(platform).config.car_docs\n", + " if isinstance(car_docs, list):\n", + " car_docs = car_docs[0]\n", + " years = [int(y) for y in car_docs.year_list]\n", " correct_year = year in years\n", " print(f\"{correct_year=!s: <6} {platform=: <32} {year=: <5} {years=}\")\n", "\n", diff --git a/tools/car_porting/examples/subaru_long_accel.ipynb b/tools/car_porting/examples/subaru_long_accel.ipynb index 24470b44d2..9d18a114df 100644 --- a/tools/car_porting/examples/subaru_long_accel.ipynb +++ b/tools/car_porting/examples/subaru_long_accel.ipynb @@ -9,7 +9,7 @@ "segments = [\n", " \"d9df6f87e8feff94|2023-03-28--17-41-10/1:12\"\n", "]\n", - "platform = \"SUBARU OUTBACK 6TH GEN\"\n" + "platform = \"SUBARU_OUTBACK\"\n" ] }, { @@ -56,7 +56,7 @@ " es_status_history.append(copy.copy(cp.vl[\"ES_Status\"]))\n", "\n", " acceleration_history.append(last_acc)\n", - " \n", + "\n", " if msg.which() == \"carState\":\n", " last_acc = msg.carState.aEgo" ] diff --git a/tools/car_porting/examples/subaru_steer_temp_fault.ipynb b/tools/car_porting/examples/subaru_steer_temp_fault.ipynb index 46d8dc413e..3d5055cbc2 100644 --- a/tools/car_porting/examples/subaru_steer_temp_fault.ipynb +++ b/tools/car_porting/examples/subaru_steer_temp_fault.ipynb @@ -11,7 +11,7 @@ "segments = [\n", " \"c3d1ccb52f5f9d65|2023-07-22--01-23-20/6:10\",\n", "]\n", - "platform = \"SUBARU OUTBACK 6TH GEN\"" + "platform = \"SUBARU_OUTBACK\"" ] }, { @@ -52,7 +52,7 @@ " for msg in can_msgs:\n", " cp.update_strings([msg.as_builder().to_bytes()])\n", " steering_torque_history.append(copy.copy(cp.vl[\"Steering_Torque\"]))\n", - " \n", + "\n", " steer_warning_last = False\n", " for i, steering_torque_msg in enumerate(steering_torque_history):\n", " steer_warning = steering_torque_msg[\"Steer_Warning\"]\n", diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index 1dfac7dcf3..b4d263667c 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -5,7 +5,6 @@ import unittest from openpilot.selfdrive.car.tests.routes import CarTestRoute from openpilot.selfdrive.car.tests.test_models import TestCarModel -from openpilot.selfdrive.car.values import PLATFORMS from openpilot.tools.lib.route import SegmentName @@ -33,9 +32,7 @@ if __name__ == "__main__": route_or_segment_name = SegmentName(args.route_or_segment_name.strip(), allow_route_name=True) segment_num = route_or_segment_name.segment_num if route_or_segment_name.segment_num != -1 else None - platform = PLATFORMS.get(args.car) - - test_route = CarTestRoute(route_or_segment_name.route_name.canonical_name, platform, segment=segment_num) + test_route = CarTestRoute(route_or_segment_name.route_name.canonical_name, args.car, segment=segment_num) test_suite = create_test_models_suite([test_route], ci=args.ci) unittest.TextTestRunner().run(test_suite) diff --git a/tools/lib/comma_car_segments.py b/tools/lib/comma_car_segments.py index 9027fec637..78825504e6 100644 --- a/tools/lib/comma_car_segments.py +++ b/tools/lib/comma_car_segments.py @@ -1,13 +1,22 @@ import os import requests + # Forks with additional car support can fork the commaCarSegments repo on huggingface or host the LFS files themselves COMMA_CAR_SEGMENTS_REPO = os.environ.get("COMMA_CAR_SEGMENTS_REPO", "https://huggingface.co/datasets/commaai/commaCarSegments") COMMA_CAR_SEGMENTS_BRANCH = os.environ.get("COMMA_CAR_SEGMENTS_BRANCH", "main") COMMA_CAR_SEGMENTS_LFS_INSTANCE = os.environ.get("COMMA_CAR_SEGMENTS_LFS_INSTANCE", COMMA_CAR_SEGMENTS_REPO) def get_comma_car_segments_database(): - return requests.get(get_repo_raw_url("database.json")).json() + from openpilot.selfdrive.car.fingerprints import MIGRATION + + database = requests.get(get_repo_raw_url("database.json")).json() + + ret = {} + for platform in database: + ret[MIGRATION.get(platform, platform)] = database[platform] + + return ret # Helpers related to interfacing with the commaCarSegments repository, which contains a collection of public segments for users to perform validation on. diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index 7a1e972e19..669c1520db 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -89,7 +89,7 @@ def default_valid_file(fn: LogPath) -> bool: def auto_strategy(rlog_paths: LogPaths, qlog_paths: LogPaths, interactive: bool, valid_file: ValidFileCallable) -> LogPaths: # auto select logs based on availability - if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths): + if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths) and all(qlog is not None and valid_file(qlog) for qlog in qlog_paths): if interactive: if input("Some rlogs were not found, would you like to fallback to qlogs for those segments? (y/n) ").lower() != "y": return rlog_paths @@ -172,6 +172,15 @@ def auto_source(sr: SegmentRange, mode=ReadMode.RLOG) -> LogPaths: SOURCES: list[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,] exceptions = [] + + # for automatic fallback modes, auto_source needs to first check if rlogs exist for any source + if mode in [ReadMode.AUTO, ReadMode.AUTO_INTERACTIVE]: + for source in SOURCES: + try: + return check_source(source, sr, ReadMode.RLOG) + except Exception: + pass + # Automatically determine viable source for source in SOURCES: try: diff --git a/tools/lib/tests/test_comma_car_segments.py b/tools/lib/tests/test_comma_car_segments.py index b293251583..91bab94343 100644 --- a/tools/lib/tests/test_comma_car_segments.py +++ b/tools/lib/tests/test_comma_car_segments.py @@ -1,7 +1,7 @@ import pytest import unittest - import requests +from openpilot.selfdrive.car.fingerprints import MIGRATION from openpilot.tools.lib.comma_car_segments import get_comma_car_segments_database, get_url from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.route import SegmentRange @@ -19,7 +19,7 @@ class TestCommaCarSegments(unittest.TestCase): def test_download_segment(self): database = get_comma_car_segments_database() - fp = "SUBARU FORESTER 2019" + fp = "SUBARU_FORESTER" segment = database[fp][0] @@ -31,10 +31,8 @@ class TestCommaCarSegments(unittest.TestCase): self.assertEqual(resp.status_code, 200) lr = LogReader(url) - CP = lr.first("carParams") - - self.assertEqual(CP.carFingerprint, fp) + self.assertEqual(MIGRATION.get(CP.carFingerprint, CP.carFingerprint), fp) if __name__ == "__main__": diff --git a/tools/replay/lib/ui_helpers.py b/tools/replay/lib/ui_helpers.py index 23f3563084..11b5182a6b 100644 --- a/tools/replay/lib/ui_helpers.py +++ b/tools/replay/lib/ui_helpers.py @@ -7,9 +7,7 @@ import pygame from matplotlib.backends.backend_agg import FigureCanvasAgg -from openpilot.common.transformations.camera import (eon_f_frame_size, eon_f_focal_length, - tici_f_frame_size, tici_f_focal_length, - get_view_frame_from_calib_frame) +from openpilot.common.transformations.camera import get_view_frame_from_calib_frame from openpilot.selfdrive.controls.radard import RADAR_TO_CAMERA @@ -20,9 +18,6 @@ YELLOW = (255, 255, 0) BLACK = (0, 0, 0) WHITE = (255, 255, 255) -_FULL_FRAME_SIZE = { -} - class UIParams: lidar_x, lidar_y, lidar_zoom = 384, 960, 6 lidar_car_x, lidar_car_y = lidar_x / 2., lidar_y / 1.1 @@ -32,45 +27,13 @@ class UIParams: car_color = 110 UP = UIParams -_BB_TO_FULL_FRAME = {} -_CALIB_BB_TO_FULL = {} -_FULL_FRAME_TO_BB = {} -_INTRINSICS = {} - -eon_f_qcam_frame_size = (480, 360) -tici_f_qcam_frame_size = (528, 330) - -cams = [(eon_f_frame_size, eon_f_focal_length, eon_f_frame_size), - (tici_f_frame_size, tici_f_focal_length, tici_f_frame_size), - (eon_f_qcam_frame_size, eon_f_focal_length, eon_f_frame_size), - (tici_f_qcam_frame_size, tici_f_focal_length, tici_f_frame_size)] -for size, focal, full_size in cams: - sz = size[0] * size[1] - _BB_SCALE = size[0] / 640. - _BB_TO_FULL_FRAME[sz] = np.asarray([ - [_BB_SCALE, 0., 0.], - [0., _BB_SCALE, 0.], - [0., 0., 1.]]) - calib_scale = full_size[0] / 640. - _CALIB_BB_TO_FULL[sz] = np.asarray([ - [calib_scale, 0., 0.], - [0., calib_scale, 0.], - [0., 0., 1.]]) - _FULL_FRAME_TO_BB[sz] = np.linalg.inv(_BB_TO_FULL_FRAME[sz]) - _FULL_FRAME_SIZE[sz] = (size[0], size[1]) - _INTRINSICS[sz] = np.array([ - [focal, 0., full_size[0] / 2.], - [0., focal, full_size[1] / 2.], - [0., 0., 1.]]) - - METER_WIDTH = 20 class Calibration: - def __init__(self, num_px, rpy, intrinsic): + def __init__(self, num_px, rpy, intrinsic, calib_scale): self.intrinsic = intrinsic self.extrinsics_matrix = get_view_frame_from_calib_frame(rpy[0], rpy[1], rpy[2], 0.0)[:,:3] - self.zoom = _CALIB_BB_TO_FULL[num_px][0, 0] + self.zoom = calib_scale def car_space_to_ff(self, x, y, z): car_space_projective = np.column_stack((x, y, z)).T diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 9657375be7..7c8c1ad43f 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -225,7 +225,7 @@ void Replay::queueSegment() { if (cur == segments_.end()) return; auto begin = std::prev(cur, std::min(segment_cache_limit / 2, std::distance(segments_.begin(), cur))); - auto end = std::next(begin, std::min(segment_cache_limit, segments_.size())); + auto end = std::next(begin, std::min(segment_cache_limit, std::distance(begin, segments_.end()))); // load one segment at a time auto it = std::find_if(cur, end, [](auto &it) { return !it.second || !it.second->isLoaded(); }); if (it != end && !it->second) { @@ -290,12 +290,22 @@ void Replay::mergeSegments(const SegmentMap::iterator &begin, const SegmentMap:: void Replay::startStream(const Segment *cur_segment) { const auto &events = cur_segment->log->events; - // each segment has an INIT_DATA route_start_ts_ = events.front()->mono_time; cur_mono_time_ += route_start_ts_ - 1; + // get datetime from INIT_DATA, fallback to datetime in the route name + route_date_time_ = route()->datetime(); + auto it = std::find_if(events.cbegin(), events.cend(), + [](auto e) { return e->which == cereal::Event::Which::INIT_DATA; }); + if (it != events.cend()) { + uint64_t wall_time = (*it)->event.getInitData().getWallTimeNanos(); + if (wall_time > 0) { + route_date_time_ = QDateTime::fromMSecsSinceEpoch(wall_time / 1e6); + } + } + // write CarParams - auto it = std::find_if(events.begin(), events.end(), [](auto e) { return e->which == cereal::Event::Which::CAR_PARAMS; }); + it = std::find_if(events.begin(), events.end(), [](auto e) { return e->which == cereal::Event::Which::CAR_PARAMS; }); if (it != events.end()) { car_fingerprint_ = (*it)->event.getCarParams().getCarFingerprint(); capnp::MallocMessageBuilder builder; diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 1a74b69c3d..3859b69380 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -72,7 +72,8 @@ public: inline void removeFlag(REPLAY_FLAGS flag) { flags_ &= ~flag; } inline const Route* route() const { return route_.get(); } inline double currentSeconds() const { return double(cur_mono_time_ - route_start_ts_) / 1e9; } - inline QDateTime currentDateTime() const { return route_->datetime().addSecs(currentSeconds()); } + inline QDateTime routeDateTime() const { return route_date_time_; } + inline QDateTime currentDateTime() const { return route_date_time_.addSecs(currentSeconds()); } inline uint64_t routeStartTime() const { return route_start_ts_; } inline double toSeconds(uint64_t mono_time) const { return (mono_time - route_start_ts_) / 1e9; } inline int totalSeconds() const { return (!segments_.empty()) ? (segments_.rbegin()->first + 1) * 60 : 0; } @@ -121,6 +122,7 @@ protected: std::atomic exit_ = false; bool paused_ = false; bool events_updated_ = false; + QDateTime route_date_time_; uint64_t route_start_ts_ = 0; std::atomic cur_mono_time_ = 0; std::unique_ptr> events_; diff --git a/tools/replay/ui.py b/tools/replay/ui.py index be80166e76..aa03ae193c 100755 --- a/tools/replay/ui.py +++ b/tools/replay/ui.py @@ -10,8 +10,9 @@ import pygame import cereal.messaging as messaging from openpilot.common.numpy_fast import clip from openpilot.common.basedir import BASEDIR -from openpilot.tools.replay.lib.ui_helpers import (_BB_TO_FULL_FRAME, UP, - _INTRINSICS, BLACK, GREEN, +from openpilot.common.transformations.camera import DEVICE_CAMERAS +from openpilot.tools.replay.lib.ui_helpers import (UP, + BLACK, GREEN, YELLOW, Calibration, get_blank_lid_overlay, init_plots, maybe_update_radar_points, plot_lead, @@ -55,7 +56,7 @@ def ui_thread(addr): top_down_surface = pygame.surface.Surface((UP.lidar_x, UP.lidar_y), 0, 8) sm = messaging.SubMaster(['carState', 'longitudinalPlan', 'carControl', 'radarState', 'liveCalibration', 'controlsState', - 'liveTracks', 'modelV2', 'liveParameters'], addr=addr) + 'liveTracks', 'modelV2', 'liveParameters', 'roadCameraState'], addr=addr) img = np.zeros((480, 640, 3), dtype='uint8') imgff = None @@ -112,20 +113,27 @@ def ui_thread(addr): vipc_client.connect(True) yuv_img_raw = vipc_client.recv() - if yuv_img_raw is None or not yuv_img_raw.data.any(): continue + sm.update(0) + + camera = DEVICE_CAMERAS[("tici", str(sm['roadCameraState'].sensor))] + imgff = np.frombuffer(yuv_img_raw.data, dtype=np.uint8).reshape((len(yuv_img_raw.data) // vipc_client.stride, vipc_client.stride)) num_px = vipc_client.width * vipc_client.height rgb = cv2.cvtColor(imgff[:vipc_client.height * 3 // 2, :vipc_client.width], cv2.COLOR_YUV2RGB_NV12) - zoom_matrix = _BB_TO_FULL_FRAME[num_px] + qcam = "QCAM" in os.environ + bb_scale = (528 if qcam else camera.fcam.width) / 640. + calib_scale = camera.fcam.width / 640. + zoom_matrix = np.asarray([ + [bb_scale, 0., 0.], + [0., bb_scale, 0.], + [0., 0., 1.]]) cv2.warpAffine(rgb, zoom_matrix[:2], (img.shape[1], img.shape[0]), dst=img, flags=cv2.WARP_INVERSE_MAP) - intrinsic_matrix = _INTRINSICS[num_px] - - sm.update(0) + intrinsic_matrix = camera.fcam.intrinsics w = sm['controlsState'].lateralControlState.which() if w == 'lqrStateDEPRECATED': @@ -165,7 +173,7 @@ def ui_thread(addr): if sm.updated['liveCalibration'] and num_px: rpyCalib = np.asarray(sm['liveCalibration'].rpyCalib) - calibration = Calibration(num_px, rpyCalib, intrinsic_matrix) + calibration = Calibration(num_px, rpyCalib, intrinsic_matrix, calib_scale) # *** blits *** pygame.surfarray.blit_array(camera_surface, img.swapaxes(0, 1)) diff --git a/tools/sim/bridge/metadrive/metadrive_bridge.py b/tools/sim/bridge/metadrive/metadrive_bridge.py index c2ea92798a..5c91238c55 100644 --- a/tools/sim/bridge/metadrive/metadrive_bridge.py +++ b/tools/sim/bridge/metadrive/metadrive_bridge.py @@ -75,6 +75,7 @@ class MetaDriveBridge(SimulatorBridge): on_continuous_line_done=False, crash_vehicle_done=False, crash_object_done=False, + arrive_dest_done=False, traffic_density=0.0, # traffic is incredibly expensive map_config=create_map(), decision_repeat=1, diff --git a/tools/sim/bridge/metadrive/metadrive_process.py b/tools/sim/bridge/metadrive/metadrive_process.py index 0e659c7a2d..79eefcd545 100644 --- a/tools/sim/bridge/metadrive/metadrive_process.py +++ b/tools/sim/bridge/metadrive/metadrive_process.py @@ -22,7 +22,7 @@ C3_HPR = Vec3(0, 0,0) metadrive_simulation_state = namedtuple("metadrive_simulation_state", ["running", "done", "done_info"]) metadrive_vehicle_state = namedtuple("metadrive_vehicle_state", ["velocity", "position", "bearing", "steering_angle"]) -def apply_metadrive_patches(): +def apply_metadrive_patches(arrive_dest_done=True): # By default, metadrive won't try to use cuda images unless it's used as a sensor for vehicles, so patch that in def add_image_sensor_patched(self, name: str, cls, args): if self.global_config["image_on_cuda"]:# and name == self.global_config["vehicle_config"]["image_source"]: @@ -44,12 +44,14 @@ def apply_metadrive_patches(): def arrive_destination_patch(self, *args, **kwargs): return False - MetaDriveEnv._is_arrive_destination = arrive_destination_patch + if not arrive_dest_done: + MetaDriveEnv._is_arrive_destination = arrive_destination_patch def metadrive_process(dual_camera: bool, config: dict, camera_array, wide_camera_array, image_lock, controls_recv: Connection, simulation_state_send: Connection, vehicle_state_send: Connection, exit_event): - apply_metadrive_patches() + arrive_dest_done = config.pop("arrive_dest_done", True) + apply_metadrive_patches(arrive_dest_done) road_image = np.frombuffer(camera_array.get_obj(), dtype=np.uint8).reshape((H, W, 3)) if dual_camera: diff --git a/tools/sim/launch_openpilot.sh b/tools/sim/launch_openpilot.sh index 9532537283..06984b690b 100755 --- a/tools/sim/launch_openpilot.sh +++ b/tools/sim/launch_openpilot.sh @@ -4,7 +4,7 @@ export PASSIVE="0" export NOBOARD="1" export SIMULATION="1" export SKIP_FW_QUERY="1" -export FINGERPRINT="HONDA CIVIC 2016" +export FINGERPRINT="CIVIC" export BLOCK="${BLOCK},camerad,loggerd,encoderd,micd,logmessaged" if [[ "$CI" ]]; then diff --git a/tools/sim/lib/simulated_car.py b/tools/sim/lib/simulated_car.py index f6319dd819..9148d0ddb2 100644 --- a/tools/sim/lib/simulated_car.py +++ b/tools/sim/lib/simulated_car.py @@ -6,7 +6,6 @@ from openpilot.common.params import Params from openpilot.selfdrive.boardd.boardd_api_impl import can_list_to_can_capnp from openpilot.selfdrive.car import crc8_pedal from openpilot.tools.sim.lib.common import SimulatorState -from panda.python import Panda class SimulatedCar: @@ -116,7 +115,7 @@ class SimulatedCar: 'controlsAllowed': True, 'safetyModel': 'hondaNidec', 'alternativeExperience': self.sm["carParams"].alternativeExperience, - 'safetyParam': Panda.FLAG_HONDA_GAS_INTERCEPTOR + 'safetyParam': 0, } self.pm.send('pandaStates', dat) diff --git a/tools/sim/scenarios/metadrive/stay_in_lane.py b/tools/sim/scenarios/metadrive/stay_in_lane.py index 17d3d28a2d..683ce55162 100755 --- a/tools/sim/scenarios/metadrive/stay_in_lane.py +++ b/tools/sim/scenarios/metadrive/stay_in_lane.py @@ -65,6 +65,7 @@ class MetaDriveBridge(SimulatorBridge): on_continuous_line_done=True, crash_vehicle_done=True, crash_object_done=True, + arrive_dest_done=True, traffic_density=0.0, map_config=create_map(), map_region_size=2048,