mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-09-29 04:13:43 +08:00
Merge branch 'master' into dev-priv/master
# Conflicts: # selfdrive/car/chrysler/interface.py # selfdrive/car/hyundai/carcontroller.py
This commit is contained in:
@@ -251,6 +251,7 @@ jobs:
|
||||
${{ env.RUN }} "CI=1 coverage run selfdrive/test/process_replay/test_processes.py -j$(nproc) && \
|
||||
coverage xml"
|
||||
- name: Print diff
|
||||
id: print-diff
|
||||
if: always()
|
||||
run: cat selfdrive/test/process_replay/diff.txt
|
||||
- uses: actions/upload-artifact@v2
|
||||
@@ -260,7 +261,7 @@ jobs:
|
||||
name: process_replay_diff.txt
|
||||
path: selfdrive/test/process_replay/diff.txt
|
||||
- name: Upload reference logs
|
||||
if: ${{ failure() && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
|
||||
if: ${{ failure() && steps.print-diff.outcome == 'success' && github.event_name == 'pull_request' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
|
||||
run: |
|
||||
${{ env.RUN }} "CI=1 AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
|
||||
- name: "Upload coverage to Codecov"
|
||||
|
||||
@@ -19,7 +19,7 @@ repos:
|
||||
rev: v2.2.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
exclude: '^(third_party/)|(body/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(selfdrive/ui/translations/.*.ts)'
|
||||
exclude: '^(third_party/)|(body/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(selfdrive/ui/translations/.*.ts)|(poetry.lock)'
|
||||
args:
|
||||
# if you've got a short variable name that's getting flagged, add it here
|
||||
- -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup
|
||||
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
Version 0.9.1 (2023-2-20)
|
||||
Version 0.9.1 (2023-02-23)
|
||||
========================
|
||||
* Adjust alert volume using ambient noise level
|
||||
* Removed driver monitoring timer resetting on interaction if face detected and distracted
|
||||
* UI updates
|
||||
* Driver monitoring icon shows driver's head pose
|
||||
* German translation thanks to Vrabetz and CzokNorris!
|
||||
* New driving model
|
||||
* 30% improved height estimation resulting in better driving performance for tall cars
|
||||
* Driver monitoring: removed timer resetting on user interaction if distracted
|
||||
* UI updates
|
||||
* Adjust alert volume using ambient noise level
|
||||
* Driver monitoring icon shows driver's head pose
|
||||
* German translation thanks to Vrabetz and CzokNorris!
|
||||
* Chevrolet Bolt EV 2022-23 support thanks to JasonJShuler!
|
||||
* Genesis GV60 2023 support thanks to sunnyhaibin!
|
||||
* Hyundai Tucson 2022-23 support
|
||||
|
||||
+1
-1
Submodule cereal updated: 168f460269...2cc8197d33
+1
-1
@@ -119,7 +119,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Kia|Sorento Plug-in Hybrid 2022-23[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento Plug-in Hybrid 2022-23">Hyundai A</a>||
|
||||
|Kia|Sportage 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage 2023">Hyundai N</a>||
|
||||
|Kia|Sportage Hybrid 2023[<sup>5</sup>](#footnotes)|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sportage Hybrid 2023">Hyundai N</a>||
|
||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2018-20">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2018-20">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=MJ94qoofYw0" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Stinger 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Stinger 2022">Hyundai K</a>||
|
||||
|Kia|Telluride 2020-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Telluride 2020-22">Hyundai H</a>||
|
||||
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=CT Hybrid 2017-18">Toyota</a>||
|
||||
|
||||
+1
-1
Submodule opendbc updated: c354dbcdb1...b8895f7c16
+1
-1
Submodule panda updated: 87ea052e55...92f4dbb620
Generated
+251
-18
@@ -564,6 +564,34 @@ python-versions = ">=3.7"
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "click-plugins"
|
||||
version = "1.1.1"
|
||||
description = "An extension module for click to enable registering CLI commands via setuptools entry-points."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=4.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "cligj"
|
||||
version = "0.7.2"
|
||||
description = "Click params for commmand line interfaces to GeoJSON"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, <4"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=4.0"
|
||||
|
||||
[package.extras]
|
||||
test = ["pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "cloudpickle"
|
||||
version = "2.2.0"
|
||||
@@ -959,6 +987,29 @@ python-versions = ">=3.7"
|
||||
docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"]
|
||||
testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "fiona"
|
||||
version = "1.9.1"
|
||||
description = "Fiona reads and writes spatial data files"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
attrs = ">=19.2.0"
|
||||
certifi = "*"
|
||||
click = ">=8.0,<9.0"
|
||||
click-plugins = ">=1.0"
|
||||
cligj = ">=0.5"
|
||||
munch = ">=2.3.2"
|
||||
setuptools = "*"
|
||||
|
||||
[package.extras]
|
||||
all = ["Fiona[calc,s3,test]"]
|
||||
calc = ["shapely"]
|
||||
s3 = ["boto3 (>=1.3.1)"]
|
||||
test = ["Fiona[s3]", "pytest (>=7)", "pytest-cov", "pytz"]
|
||||
|
||||
[[package]]
|
||||
name = "flake8"
|
||||
version = "4.0.1"
|
||||
@@ -1092,6 +1143,21 @@ python-versions = ">=3.7"
|
||||
packaging = "*"
|
||||
SQLAlchemy = ">=1.4"
|
||||
|
||||
[[package]]
|
||||
name = "geopandas"
|
||||
version = "0.12.2"
|
||||
description = "Geographic pandas extensions"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.dependencies]
|
||||
fiona = ">=1.8"
|
||||
packaging = "*"
|
||||
pandas = ">=1.0.0"
|
||||
pyproj = ">=2.6.1.post1"
|
||||
shapely = ">=1.7"
|
||||
|
||||
[[package]]
|
||||
name = "gevent"
|
||||
version = "22.10.1"
|
||||
@@ -2325,27 +2391,18 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "networkx"
|
||||
version = "2.3"
|
||||
version = "2.8.8"
|
||||
description = "Python package for creating and manipulating graphs and networks"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
decorator = ">=4.3.0"
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.extras]
|
||||
all = ["gdal", "lxml", "matplotlib", "nose", "numpy", "pandas", "pydot", "pygraphviz", "pyyaml", "scipy"]
|
||||
gdal = ["gdal"]
|
||||
lxml = ["lxml"]
|
||||
matplotlib = ["matplotlib"]
|
||||
nose = ["nose"]
|
||||
numpy = ["numpy"]
|
||||
pandas = ["pandas"]
|
||||
pydot = ["pydot"]
|
||||
pygraphviz = ["pygraphviz"]
|
||||
pyyaml = ["pyyaml"]
|
||||
scipy = ["scipy"]
|
||||
default = ["matplotlib (>=3.4)", "numpy (>=1.19)", "pandas (>=1.3)", "scipy (>=1.8)"]
|
||||
developer = ["mypy (>=0.982)", "pre-commit (>=2.20)"]
|
||||
doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.2)", "pydata-sphinx-theme (>=0.11)", "sphinx (>=5.2)", "sphinx-gallery (>=0.11)", "texext (>=0.6.6)"]
|
||||
extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.9)", "sympy (>=1.10)"]
|
||||
test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
@@ -2542,6 +2599,31 @@ python-versions = ">=3.6"
|
||||
[package.dependencies]
|
||||
requests = "*"
|
||||
|
||||
[[package]]
|
||||
name = "osmnx"
|
||||
version = "1.2.2"
|
||||
description = "Retrieve, model, analyze, and visualize OpenStreetMap street networks and other spatial data"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.dependencies]
|
||||
geopandas = ">=0.11"
|
||||
matplotlib = ">=3.5"
|
||||
networkx = ">=2.8"
|
||||
numpy = ">=1.22"
|
||||
pandas = ">=1.4"
|
||||
pyproj = ">=3.3"
|
||||
requests = ">=2.28"
|
||||
Rtree = ">=1.0"
|
||||
Shapely = ">=1.8,<2.0"
|
||||
|
||||
[package.extras]
|
||||
entropy = ["scipy"]
|
||||
nearest-neighbor = ["scikit-learn", "scipy"]
|
||||
raster = ["gdal", "rasterio"]
|
||||
web-map = ["folium"]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
@@ -3486,6 +3568,14 @@ python-versions = "*"
|
||||
numpy = ">=1.11.0"
|
||||
scipy = ">=0.17.1"
|
||||
|
||||
[[package]]
|
||||
name = "rtree"
|
||||
version = "1.0.1"
|
||||
description = "R-Tree spatial index for Python GIS"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "s2sphere"
|
||||
version = "0.2.5"
|
||||
@@ -3688,6 +3778,19 @@ typing-extensions = "*"
|
||||
test = ["pytest (>=6.2)", "virtualenv (>20)"]
|
||||
toml = ["setuptools (>=42)"]
|
||||
|
||||
[[package]]
|
||||
name = "shapely"
|
||||
version = "1.8.5.post1"
|
||||
description = "Geometric objects, predicates, and operations"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
all = ["numpy", "pytest", "pytest-cov"]
|
||||
test = ["pytest", "pytest-cov"]
|
||||
vectorized = ["numpy"]
|
||||
|
||||
[[package]]
|
||||
name = "shellingham"
|
||||
version = "1.5.0"
|
||||
@@ -4464,7 +4567,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "~3.8"
|
||||
content-hash = "3c2597d2199a29ef79dd4d5fbc5e2350d86c82a3fe6716d13b93ebc268053eb9"
|
||||
content-hash = "9e9495c896e6fd0855803aeaf46513c6c22424b86be820759a8baf27d44e73ee"
|
||||
|
||||
[metadata.files]
|
||||
adal = [
|
||||
@@ -4917,6 +5020,14 @@ click = [
|
||||
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
|
||||
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
|
||||
]
|
||||
click-plugins = [
|
||||
{file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"},
|
||||
{file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"},
|
||||
]
|
||||
cligj = [
|
||||
{file = "cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df"},
|
||||
{file = "cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27"},
|
||||
]
|
||||
cloudpickle = [
|
||||
{file = "cloudpickle-2.2.0-py3-none-any.whl", hash = "sha256:7428798d5926d8fcbfd092d18d01a2a03daf8237d8fcdc8095d256b8490796f0"},
|
||||
{file = "cloudpickle-2.2.0.tar.gz", hash = "sha256:3f4219469c55453cfe4737e564b67c2a149109dabf7f242478948b895f61106f"},
|
||||
@@ -5339,6 +5450,28 @@ filelock = [
|
||||
{file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"},
|
||||
{file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"},
|
||||
]
|
||||
fiona = [
|
||||
{file = "Fiona-1.9.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:902b67b2d012c5797b5d7d3cb3b46dcf9a342cf90a7f7e53fb12c83738d19926"},
|
||||
{file = "Fiona-1.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2f4535ae2c8446e6b328745a44567478d5a077ed63c888b8c212dddb1e11925"},
|
||||
{file = "Fiona-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3d7f3286fb59b93cefefb89014b6fa8413126e180e15c576db859ba936cf334"},
|
||||
{file = "Fiona-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:692fe64c0f3a39742d6f7a8e420a8387f6aec3b6818b727d2dfc98a0c40e992d"},
|
||||
{file = "Fiona-1.9.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:a017a39650df0cc541c57cf7de450bb4cee6fd9760eb716323b594c1074634a2"},
|
||||
{file = "Fiona-1.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c3b52d49bc379fdcfd1250b38e7e00ab24ee14eb765376c793bbe251ffd09d6a"},
|
||||
{file = "Fiona-1.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbb0ae851cd4417104c469335a01f938251a8639317f93d422c5c808150bd27"},
|
||||
{file = "Fiona-1.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:4a6d8fcbbdafa8af8ac1904628b0267382ed9f9921933d061d7bfc5d3f3daf99"},
|
||||
{file = "Fiona-1.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:74f056a84dc52a0b21a2cf024601a69105596f06f28d40b45049948be17b4df2"},
|
||||
{file = "Fiona-1.9.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5b9f3f6c782bb4ae2c924eefd373cabdeaaa99f86477b9c7c71eb20c052ee7c5"},
|
||||
{file = "Fiona-1.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:5d6183189a7e05e2498d38a1df3ab07e1353fa48e977cbc3a31203927bd06bca"},
|
||||
{file = "Fiona-1.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5f2c14beec98a330aee1fd81fa0447a6aa1d5e0a75d000c0052dbe1f23dd6cfd"},
|
||||
{file = "Fiona-1.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:585a47ec21f2d198abc112158eaf12a6587a272beb7f001162d8c3b262676666"},
|
||||
{file = "Fiona-1.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4368b4054f21518a19dea54ce9ac445c40418c6331c0c99d1531c3ddff05da"},
|
||||
{file = "Fiona-1.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:839ed0db23198bb754f0d655d4eeaf5f9c141bef734557e77e95e4dc83e42e7f"},
|
||||
{file = "Fiona-1.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:decca3956032ae2d2c19d2f7fa8a4553c43a6e66eb5abe9a05f6ddadcb1bfe5c"},
|
||||
{file = "Fiona-1.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb827fa0030d03d8080723137c74b865ec18dbade87c02ed60215491a315c6be"},
|
||||
{file = "Fiona-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7e0f36484757baa8cd1c0602941e029ff992282776f9afae4c5b90f501ff005"},
|
||||
{file = "Fiona-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f98933b552adf0506799097934a6950de412288e7a50466144d04874d6f63fbc"},
|
||||
{file = "Fiona-1.9.1.tar.gz", hash = "sha256:3a3725e94840a387fef48726d60db6a6791563f366939d22378a4661f8941be7"},
|
||||
]
|
||||
flake8 = [
|
||||
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
|
||||
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
|
||||
@@ -5463,6 +5596,10 @@ geoalchemy2 = [
|
||||
{file = "GeoAlchemy2-0.12.5-py2.py3-none-any.whl", hash = "sha256:3a59eb651df95b3dfee8e1d82f4d18c80b75f712860a0a3080defc6b0435070d"},
|
||||
{file = "GeoAlchemy2-0.12.5.tar.gz", hash = "sha256:31c2502dce317b57b335e4eb87562d501fa39e46c728be514d9b86091e08dd67"},
|
||||
]
|
||||
geopandas = [
|
||||
{file = "geopandas-0.12.2-py3-none-any.whl", hash = "sha256:0a470e4bf6f5367e6fd83ab6b40405e0b805c8174665bbcb7c4077ed90202912"},
|
||||
{file = "geopandas-0.12.2.tar.gz", hash = "sha256:0acdacddefa176525e4da6d9aeeece225da26055c4becdc6e97cf40fa97c27f4"},
|
||||
]
|
||||
gevent = [
|
||||
{file = "gevent-22.10.1-cp27-cp27m-win32.whl", hash = "sha256:702a51b8f21bad1976b0893f90ade466e8c27039b846b611ad2beb8c6e6ac701"},
|
||||
{file = "gevent-22.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:af7baec79a5f8ad1cc132d3b14edd12661c628d8094e501b089b1fe2d3df7f6e"},
|
||||
@@ -6393,7 +6530,8 @@ nest-asyncio = [
|
||||
{file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"},
|
||||
]
|
||||
networkx = [
|
||||
{file = "networkx-2.3.zip", hash = "sha256:8311ddef63cf5c5c5e7c1d0212dd141d9a1fe3f474915281b73597ed5f1d4e3d"},
|
||||
{file = "networkx-2.8.8-py3-none-any.whl", hash = "sha256:e435dfa75b1d7195c7b8378c3859f0445cd88c6b0375c181ed66823a9ceb7524"},
|
||||
{file = "networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e"},
|
||||
]
|
||||
nodeenv = [
|
||||
{file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
|
||||
@@ -6521,6 +6659,10 @@ osmium = [
|
||||
{file = "osmium-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e45b7c54ac756e9cb40e2ba68691df635804eb6aa2023088af66936a9c8e3782"},
|
||||
{file = "osmium-3.4.1.tar.gz", hash = "sha256:575dad72ab169cf585b9aeefb4f5f99ac250bf7da1986992afcbf169dc70c381"},
|
||||
]
|
||||
osmnx = [
|
||||
{file = "osmnx-1.2.2-py2.py3-none-any.whl", hash = "sha256:94f2a3929e857d8c0da39ae552c6da3b1a3f4bcfea6de108696bda5ee3a7689d"},
|
||||
{file = "osmnx-1.2.2.tar.gz", hash = "sha256:30924452ca02758ece3301f9fcfb1b80edf31e2be7abe7fa7e0fefddb5050408"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
@@ -7362,6 +7504,53 @@ requests-toolbelt = [
|
||||
reverse-geocoder = [
|
||||
{file = "reverse_geocoder-1.5.1.tar.gz", hash = "sha256:2a2e781b5f69376d922b78fe8978f1350c84fce0ddb07e02c834ecf98b57c75c"},
|
||||
]
|
||||
rtree = [
|
||||
{file = "Rtree-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9855b8f11cdad99c56eb361b7b632a4fbd3d8cbe3f2081426b445f0cfb7fdca9"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:18ce7e4d04b85c48f2d364835620b3b20e38e199639746e7b12f07a2303e18ff"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:784efa6b7be9e99b33613ae8495931032689441eabb6120c9b3eb91188c33794"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:157207191aebdacbbdbb369e698cfbfebce53bc97114e96c8af5bed3126475f1"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fb3671a8d440c24b1dd29ec621d4345ced7185e26f02abe98e85a6629fcb50"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:11d16f51cf9205cd6995af36e24efe8f184270f667fb49bb69b09fc46b97e7d4"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6db6a0a93e41594ffc14b053f386dd414ab5a82535bbd9aedafa6ac8dc0650d8"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6e29e5eb3083ad12ac5c1ce6e37465ea3428d894d3466cc9c9e2ee4bf768e53"},
|
||||
{file = "Rtree-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:656b148589c0b5bab4a7db4d033634329f42a5feaac10ca40aceeca109d83c1f"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b2c15f9373ba314c83a8df5cb6d99b4e3af23c376c6b1317add995432dd0970"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93c5e0bf31e76b4f92a6eec3d2891e938408774c75a8ed6ac3d2c8db04a2be33"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6792de0e3c2fd3ad7e069445027603bec7a47000432f49c80246886311f4f152"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e131b570dc360a49e7f3b60e7bc6517943a54df056587964d1cb903889e7e"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:becd711fe97c2e09b1b7969e83080a3c8012bce2d30f6db879aade255fcba5c1"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:015df09e1bc55ddf7c88799bf1515d058cd0ee78eacf4cd443a32876d3b3a863"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c2973b76f61669a85e160b4ad09879c4089fc0e3f20fd99adf161ca298fe8374"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e4335e131a58952635560a003458011d97f9ea6f3c010dc24906050b42ee2c03"},
|
||||
{file = "Rtree-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:e7ca5d743f6a1dc62653dfac8ee7ce2e1ba91be7cf97916a7f60b7cbe48fb48d"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2ee7165e9872a026ccb868c021711eba39cedf7d1820763c9de52d5324691a92"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8de99f28af0f1783eefb80918959903b4b18112f6a12b48f296ecb162804e69d"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a94e2f4bf74bd202ea8b67ea3d7c71e763ad41f79be1d6b72aa2c8d5a8e92c4"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5120da3a1b96f3a7a17dd6af0afdd4e6f3cc9baa87e9ee0a272882f01f980bb"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7e3d5f0e7b28250afbb290ab88b49aa0f121c9714d0da2080581783690347507"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:296203e933b6ec0dd07f6a7456c4f1492def95b6993f20cc61c92b0fee0aecc5"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:77908cd7acdd519a731979ebf5baff8afd102109c2f52864c1e6ee75d3ea2d87"},
|
||||
{file = "Rtree-1.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1a213e5d385278ca7668bc5b27083f8d6e39996a9bd59b6528f3a30009dae4ed"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfa8cffec5cb9fed494c4bb335ebdb69b3c26178b0b685f67f79296c6b3d800c"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b31fd22d214160859d038da7cb2aaa27acb71efc24a7bcc75c84b5e502721549"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d68a81ad419d5c2ea5fecc677e6c178666c057e2c7b24100a6c48392196f1e9"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62f38020af47b765adc6b0bc7c4e810c6c3d1eab44ba339b592ff25a4c0dc0a7"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50b658a6707f215a0056d52e9f83a97148c0af62dea07cf29b3789a2c429e78a"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3573cbb0de872f54d0a0c29596a84e8ac3939c47ca3bece4a82e92775730a0d0"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5abe5a19d943a88bea14901970e4c53e4579fc2662404cdea6163bf4c04d49a"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1e894112cef4de6c518bdea0b43eada65f12888c3645cc437c3a677aa023039f"},
|
||||
{file = "Rtree-1.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:582854252b8fd5c8472478af060635434931fb55edd269bac128cbf2eef43620"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b54057e8a8ad92c1d8e9eaa5cf32aad70dde454abbf9b638e9d6024520a52c02"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:698de8ce6c62e159d93b35bacf64bcf3619077b5367bc88cd2cff5e0bc36169b"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273ee61783de3a1664e5f868feebf5eea4629447137751bfa4087b0f82093082"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16900ee02cf5c198a42b03635268a80f606aa102f3f7618b89f75023d406da1c"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ce4a6fdb63254a4c1efebe7a4f7a59b1c333c703bde4ae715d9ad88c833e10b"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5b20f69e040a05503b22297af223f336fe7047909b57e4b207b98292f33a229f"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:57128293dd625cb1f07726f32208097953e8854d70ab1fc55d6858733618b9ed"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e898d7409ab645c25e06d4e058f99271182601d70b2887aba3351bf08e09a0c6"},
|
||||
{file = "Rtree-1.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ad9912faeddb1ddcec5e26b33089166d58a107af6862d8b7f1bb2b7c0002ab39"},
|
||||
{file = "Rtree-1.0.1.tar.gz", hash = "sha256:222121699c303a64065d849bf7038b1ecabc37b65c7fa340bedb38ef0e805429"},
|
||||
]
|
||||
s2sphere = [
|
||||
{file = "s2sphere-0.2.5-py2.py3-none-any.whl", hash = "sha256:d2340c9cf458ddc9a89afd1d8048a4195ce6fa6b0095ab900d4be5271e537401"},
|
||||
{file = "s2sphere-0.2.5.tar.gz", hash = "sha256:c2478c1ff7c601a59a7151a57b605435897514578fa6bdb8730721c182adbbaf"},
|
||||
@@ -7539,6 +7728,50 @@ setuptools-scm = [
|
||||
{file = "setuptools_scm-7.0.5-py3-none-any.whl", hash = "sha256:7930f720905e03ccd1e1d821db521bff7ec2ac9cf0ceb6552dd73d24a45d3b02"},
|
||||
{file = "setuptools_scm-7.0.5.tar.gz", hash = "sha256:031e13af771d6f892b941adb6ea04545bbf91ebc5ce68c78aaf3fff6e1fb4844"},
|
||||
]
|
||||
shapely = [
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d048f93e42ba578b82758c15d8ae037d08e69d91d9872bca5a1895b118f4e2b0"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99ab0ddc05e44acabdbe657c599fdb9b2d82e86c5493bdae216c0c4018a82dee"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a2f0da0109e81e0c101a2b4cd8412f73f5f299e7b5b2deaf64cd2a100ac118"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6fe855e7d45685926b6ba00aaeb5eba5862611f7465775dacd527e081a8ced6d"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec14ceca36f67cb48b34d02d7f65a9acae15cd72b48e303531893ba4a960f3ea"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a2b2a65fa7f97115c1cd989fe9d6f39281ca2a8a014f1d4904c1a6e34d7f25"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-win32.whl", hash = "sha256:21776184516a16bf82a0c3d6d6a312b3cd15a4cabafc61ee01cf2714a82e8396"},
|
||||
{file = "Shapely-1.8.5.post1-cp310-cp310-win_amd64.whl", hash = "sha256:a354199219c8d836f280b88f2c5102c81bb044ccea45bd361dc38a79f3873714"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:783bad5f48e2708a0e2f695a34ed382e4162c795cb2f0368b39528ac1d6db7ed"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a23ef3882d6aa203dd3623a3d55d698f59bfbd9f8a3bfed52c2da05a7f0f8640"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ab38f7b5196ace05725e407cb8cab9ff66edb8e6f7bb36a398e8f73f52a7aaa2"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d086591f744be483b34628b391d741e46f2645fe37594319e0a673cc2c26bcf"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4728666fff8cccc65a07448cae72c75a8773fea061c3f4f139c44adc429b18c3"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-win32.whl", hash = "sha256:84010db15eb364a52b74ea8804ef92a6a930dfc1981d17a369444b6ddec66efd"},
|
||||
{file = "Shapely-1.8.5.post1-cp311-cp311-win_amd64.whl", hash = "sha256:48dcfffb9e225c0481120f4bdf622131c8c95f342b00b158cdbe220edbbe20b6"},
|
||||
{file = "Shapely-1.8.5.post1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2fd15397638df291c427a53d641d3e6fd60458128029c8c4f487190473a69a91"},
|
||||
{file = "Shapely-1.8.5.post1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a74631e511153366c6dbe3229fa93f877e3c87ea8369cd00f1d38c76b0ed9ace"},
|
||||
{file = "Shapely-1.8.5.post1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:66bdac74fbd1d3458fa787191a90fa0ae610f09e2a5ec398c36f968cc0ed743f"},
|
||||
{file = "Shapely-1.8.5.post1-cp36-cp36m-win32.whl", hash = "sha256:6d388c0c1bd878ed1af4583695690aa52234b02ed35f93a1c8486ff52a555838"},
|
||||
{file = "Shapely-1.8.5.post1-cp36-cp36m-win_amd64.whl", hash = "sha256:be9423d5a3577ac2e92c7e758bd8a2b205f5e51a012177a590bc46fc51eb4834"},
|
||||
{file = "Shapely-1.8.5.post1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5d7f85c2d35d39ff53c9216bc76b7641c52326f7e09aaad1789a3611a0f812f2"},
|
||||
{file = "Shapely-1.8.5.post1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:adcf8a11b98af9375e32bff91de184f33a68dc48b9cb9becad4f132fa25cfa3c"},
|
||||
{file = "Shapely-1.8.5.post1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:753ed0e21ab108bd4282405b9b659f2e985e8502b1a72b978eaa51d3496dee19"},
|
||||
{file = "Shapely-1.8.5.post1-cp37-cp37m-win32.whl", hash = "sha256:65b21243d8f6bcd421210daf1fabb9de84de2c04353c5b026173b88d17c1a581"},
|
||||
{file = "Shapely-1.8.5.post1-cp37-cp37m-win_amd64.whl", hash = "sha256:370b574c78dc5af3a198a6da5d9b3d7c04654bd2ef7e80e80a3a0992dfb2d9cd"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:532a55ee2a6c52d23d6f7d1567c8f0473635f3b270262c44e1b0c88096827e22"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3480657460e939f45a7d359ef0e172a081f249312557fe9aa78c4fd3a362d993"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b65f5d530ba91e49ffc7c589255e878d2506a8b96ffce69d3b7c4500a9a9eaf8"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:147066da0be41b147a61f8eb805dea3b13709dbc873a431ccd7306e24d712bc0"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c2822111ddc5bcfb116e6c663e403579d0fe3f147d2a97426011a191c43a7458"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b47bb6f9369e8bf3e6dbd33e6a25a47ee02b2874792a529fe04a49bf8bc0df6"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-win32.whl", hash = "sha256:2e0a8c2e55f1be1312b51c92b06462ea89e6bb703fab4b114e7a846d941cfc40"},
|
||||
{file = "Shapely-1.8.5.post1-cp38-cp38-win_amd64.whl", hash = "sha256:0d885cb0cf670c1c834df3f371de8726efdf711f18e2a75da5cfa82843a7ab65"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0b4ee3132ee90f07d63db3aea316c4c065ed7a26231458dda0874414a09d6ba3"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:02dd5d7dc6e46515d88874134dc8fcdc65826bca93c3eecee59d1910c42c1b17"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c6a9a4a31cd6e86d0fbe8473ceed83d4fe760b19d949fb557ef668defafea0f6"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:38f0fbbcb8ca20c16451c966c1f527cc43968e121c8a048af19ed3e339a921cd"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78fb9d929b8ee15cfd424b6c10879ce1907f24e05fb83310fc47d2cd27088e40"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89164e7a9776a19e29f01369a98529321994e2e4d852b92b7e01d4d9804c55bf"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-win32.whl", hash = "sha256:8e59817b0fe63d34baedaabba8c393c0090f061917d18fc0bcc2f621937a8f73"},
|
||||
{file = "Shapely-1.8.5.post1-cp39-cp39-win_amd64.whl", hash = "sha256:e9c30b311de2513555ab02464ebb76115d242842b29c412f5a9aa0cac57be9f6"},
|
||||
{file = "Shapely-1.8.5.post1.tar.gz", hash = "sha256:ef3be705c3eac282a28058e6c6e5503419b250f482320df2172abcbea642c831"},
|
||||
]
|
||||
shellingham = [
|
||||
{file = "shellingham-1.5.0-py2.py3-none-any.whl", hash = "sha256:a8f02ba61b69baaa13facdba62908ca8690a94b8119b69f5ec5873ea85f7391b"},
|
||||
{file = "shellingham-1.5.0.tar.gz", hash = "sha256:72fb7f5c63103ca2cb91b23dee0c71fe8ad6fbfd46418ef17dbe40db51592dad"},
|
||||
|
||||
+2
-1
@@ -145,7 +145,7 @@ jupyterlab = "^3.4.4"
|
||||
jupyterlab-vim = "^0.15.1"
|
||||
Markdown = "^3.4.1"
|
||||
msgpack-python = "^0.5.6"
|
||||
networkx = "~2.3"
|
||||
networkx = "~2.8"
|
||||
nvidia-ml-py3 = "^7.352.0"
|
||||
onnx2torch = "^1.5.4"
|
||||
onnxoptimizer = "^0.3.1"
|
||||
@@ -172,6 +172,7 @@ triton = "^1.1.1"
|
||||
Werkzeug = "^2.1.2"
|
||||
zerorpc = { git = "https://github.com/commaai/zerorpc-python.git", branch = "master" }
|
||||
omegaconf = "^2.3.0"
|
||||
osmnx = "==1.2.2"
|
||||
|
||||
|
||||
[build-system]
|
||||
|
||||
@@ -316,7 +316,10 @@ int PandaSpiHandle::spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx
|
||||
goto transfer_fail;
|
||||
}
|
||||
rx_data_len = *(uint16_t *)(rx_buf+1);
|
||||
assert(rx_data_len < SPI_BUF_SIZE);
|
||||
if (rx_data_len >= SPI_BUF_SIZE) {
|
||||
LOGE("SPI: RX data len larger than buf size %d", rx_data_len);
|
||||
goto transfer_fail;
|
||||
}
|
||||
|
||||
// Read data
|
||||
transfer.len = rx_data_len + 1;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from cereal import car
|
||||
from panda import Panda
|
||||
from selfdrive.car import STD_CARGO_KG, get_safety_config, create_mads_event
|
||||
from selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, CHRYSLER_OLD_TUNING_BLACKLIST, ChryslerFlags
|
||||
from selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
@@ -42,11 +42,10 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.wheelbase = 3.089
|
||||
ret.steerRatio = 16.2 # Pacifica Hybrid 2017
|
||||
|
||||
if candidate in CHRYSLER_OLD_TUNING_BLACKLIST:
|
||||
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]]
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
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]]
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
|
||||
# Jeep
|
||||
elif candidate in (CAR.JEEP_CHEROKEE, CAR.JEEP_CHEROKEE_2019):
|
||||
@@ -55,11 +54,10 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerRatio = 16.7
|
||||
ret.steerActuatorDelay = 0.2
|
||||
|
||||
if candidate in CHRYSLER_OLD_TUNING_BLACKLIST:
|
||||
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]]
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
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]]
|
||||
ret.lateralTuning.pid.kf = 0.00006
|
||||
|
||||
# Ram
|
||||
elif candidate == CAR.RAM_1500:
|
||||
|
||||
@@ -46,12 +46,8 @@ class CarControllerParams:
|
||||
self.STEER_DELTA_DOWN = 6
|
||||
self.STEER_MAX = 261 # EPS allows more, up to 350?
|
||||
else:
|
||||
if CP.carFingerprint in CHRYSLER_OLD_TUNING_BLACKLIST:
|
||||
self.STEER_DELTA_UP = 3
|
||||
self.STEER_DELTA_DOWN = 3
|
||||
else:
|
||||
self.STEER_DELTA_UP = 6
|
||||
self.STEER_DELTA_DOWN = 6
|
||||
self.STEER_DELTA_UP = 3
|
||||
self.STEER_DELTA_DOWN = 3
|
||||
self.STEER_MAX = 261 # higher than this faults the EPS
|
||||
|
||||
STEER_THRESHOLD = 120
|
||||
@@ -60,9 +56,6 @@ RAM_DT = {CAR.RAM_1500, }
|
||||
RAM_HD = {CAR.RAM_HD, }
|
||||
RAM_CARS = RAM_DT | RAM_HD
|
||||
|
||||
# the increased steer rate hasn't been verified on these cars.
|
||||
# remove from this list once it's been tested and confirmed to not fault
|
||||
CHRYSLER_OLD_TUNING_BLACKLIST = {CAR.PACIFICA_2017_HYBRID, CAR.PACIFICA_2018_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE}
|
||||
|
||||
@dataclass
|
||||
class ChryslerCarInfo(CarInfo):
|
||||
@@ -142,7 +135,7 @@ FINGERPRINTS = {
|
||||
}],
|
||||
CAR.JEEP_CHEROKEE_2019: [{
|
||||
# Jeep Grand Cherokee 2019, including most 2020 models
|
||||
55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8
|
||||
55: 8, 168: 8, 179: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 341: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 640: 1, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 840: 8, 844: 5, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 874: 2, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 960: 4, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 8, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1250: 8, 1251: 8, 1252: 8, 1254: 8, 1264: 8, 1284: 8, 1536: 8, 1537: 8, 1543: 8, 1545: 8, 1562: 8, 1568: 8, 1570: 8, 1572: 8, 1593: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1890: 8, 1891: 8, 1892: 8, 1894: 8, 1896: 8, 1904: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8
|
||||
}],
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ class Request:
|
||||
whitelist_ecus: List[int] = field(default_factory=list)
|
||||
rx_offset: int = 0x8
|
||||
bus: int = 1
|
||||
# FW responses from these queries will not be used for fingerprinting
|
||||
logging: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -29,10 +29,9 @@ def chunks(l, n=128):
|
||||
def build_fw_dict(fw_versions, filter_brand=None):
|
||||
fw_versions_dict = defaultdict(set)
|
||||
for fw in fw_versions:
|
||||
if filter_brand is None or fw.brand == filter_brand:
|
||||
addr = fw.address
|
||||
if (filter_brand is None or fw.brand == filter_brand) and not fw.logging:
|
||||
sub_addr = fw.subAddress if fw.subAddress != 0 else None
|
||||
fw_versions_dict[(addr, sub_addr)].add(fw.fwVersion)
|
||||
fw_versions_dict[(fw.address, sub_addr)].add(fw.fwVersion)
|
||||
return dict(fw_versions_dict)
|
||||
|
||||
|
||||
@@ -232,15 +231,19 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1,
|
||||
# ECUs using a subaddress need be queried one by one, the rest can be done in parallel
|
||||
addrs = []
|
||||
parallel_addrs = []
|
||||
logging_addrs = []
|
||||
ecu_types = {}
|
||||
|
||||
for brand, brand_versions in versions.items():
|
||||
for c in brand_versions.values():
|
||||
for ecu_type, addr, sub_addr in c.keys():
|
||||
for candidate, ecu in brand_versions.items():
|
||||
for ecu_type, addr, sub_addr in ecu.keys():
|
||||
a = (brand, addr, sub_addr)
|
||||
if a not in ecu_types:
|
||||
ecu_types[a] = ecu_type
|
||||
|
||||
if a not in logging_addrs and candidate == "debug":
|
||||
logging_addrs.append(a)
|
||||
|
||||
if sub_addr is None:
|
||||
if a not in parallel_addrs:
|
||||
parallel_addrs.append(a)
|
||||
@@ -269,13 +272,15 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1,
|
||||
for (tx_addr, sub_addr), version in query.get_data(timeout).items():
|
||||
f = car.CarParams.CarFw.new_message()
|
||||
|
||||
f.ecu = ecu_types.get((brand, tx_addr, sub_addr), Ecu.unknown)
|
||||
ecu_key = (brand, tx_addr, sub_addr)
|
||||
f.ecu = ecu_types.get(ecu_key, Ecu.unknown)
|
||||
f.fwVersion = version
|
||||
f.address = tx_addr
|
||||
f.responseAddress = uds.get_rx_addr_for_tx_addr(tx_addr, r.rx_offset)
|
||||
f.request = r.request
|
||||
f.brand = brand
|
||||
f.bus = r.bus
|
||||
f.logging = r.logging or ecu_key in logging_addrs
|
||||
|
||||
if sub_addr is not None:
|
||||
f.subAddress = sub_addr
|
||||
|
||||
@@ -107,7 +107,8 @@ class CarState(CarStateBase):
|
||||
ret.parkingBrake = pt_cp.vl["VehicleIgnitionAlt"]["ParkBrake"] == 1
|
||||
ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0
|
||||
ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1
|
||||
ret.accFaulted = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED
|
||||
ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or
|
||||
pt_cp.vl["EBCMFrictionBrakeStatus"]["FrictionBrakeUnavailable"] == 1)
|
||||
|
||||
ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF
|
||||
ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL
|
||||
@@ -163,6 +164,7 @@ class CarState(CarStateBase):
|
||||
("RLWheelSpd", "EBCMWheelSpdRear"),
|
||||
("RRWheelSpd", "EBCMWheelSpdRear"),
|
||||
("MovingBackward", "EBCMWheelSpdRear"),
|
||||
("FrictionBrakeUnavailable", "EBCMFrictionBrakeStatus"),
|
||||
("PRNDL2", "ECMPRDNL2"),
|
||||
("ManualMode", "ECMPRDNL2"),
|
||||
("LKADriverAppldTrq", "PSCMStatus"),
|
||||
@@ -188,6 +190,7 @@ class CarState(CarStateBase):
|
||||
("VehicleIgnitionAlt", 10),
|
||||
("EBCMWheelSpdFront", 20),
|
||||
("EBCMWheelSpdRear", 20),
|
||||
("EBCMFrictionBrakeStatus", 20),
|
||||
("AcceleratorPedal2", 33),
|
||||
("ASCMSteeringButton", 33),
|
||||
("ECMEngineStatus", 100),
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
from cereal import car
|
||||
from math import fabs
|
||||
from panda import Panda
|
||||
|
||||
from common.numpy_fast import interp
|
||||
from common.conversions import Conversions as CV
|
||||
from selfdrive.car import STD_CARGO_KG, create_button_event, scale_tire_stiffness, get_safety_config, create_mads_event
|
||||
from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
from selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD
|
||||
from selfdrive.controls.lib.drive_helpers import apply_center_deadzone
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
EventName = car.CarEvent.EventName
|
||||
@@ -43,6 +46,43 @@ class CarInterface(CarInterfaceBase):
|
||||
else:
|
||||
return CarInterfaceBase.get_steer_feedforward_default
|
||||
|
||||
@staticmethod
|
||||
def torque_from_lateral_accel_bolt(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, vego, friction_compensation):
|
||||
friction_interp = interp(
|
||||
apply_center_deadzone(lateral_accel_error, lateral_accel_deadzone),
|
||||
[-FRICTION_THRESHOLD, FRICTION_THRESHOLD],
|
||||
[-torque_params.friction, torque_params.friction]
|
||||
)
|
||||
friction = friction_interp if friction_compensation else 0.0
|
||||
steer_torque = lateral_accel_value / torque_params.latAccelFactor
|
||||
|
||||
# TODO:
|
||||
# 1. Learn the correction factors from data
|
||||
# 2. Generalize the logic to other GM torque control platforms
|
||||
steer_break_pts = np.array([-1.0, -0.9, -0.75, -0.5, 0.0, 0.5, 0.75, 0.9, 1.0])
|
||||
steer_lataccel_factors = np.array([1.5, 1.15, 1.02, 1.0, 1.0, 1.0, 1.02, 1.15, 1.5])
|
||||
steer_correction_factor = np.interp(
|
||||
steer_torque,
|
||||
steer_break_pts,
|
||||
steer_lataccel_factors
|
||||
)
|
||||
|
||||
vego_break_pts = np.array([0.0, 10.0, 15.0, 20.0, 100.0])
|
||||
vego_lataccel_factors = np.array([1.5, 1.5, 1.25, 1.0, 1.0])
|
||||
vego_correction_factor = np.interp(
|
||||
vego,
|
||||
vego_break_pts,
|
||||
vego_lataccel_factors,
|
||||
)
|
||||
|
||||
return float((steer_torque + friction) / (steer_correction_factor * vego_correction_factor))
|
||||
|
||||
def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType:
|
||||
if self.CP.carFingerprint == CAR.BOLT_EUV:
|
||||
return self.torque_from_lateral_accel_bolt
|
||||
else:
|
||||
return self.torque_from_lateral_accel_linear
|
||||
|
||||
@staticmethod
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long):
|
||||
ret.carName = "gm"
|
||||
@@ -176,7 +216,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerRatio = 16.8
|
||||
ret.centerToFront = 2.15 # measured
|
||||
tire_stiffness_factor = 1.0
|
||||
ret.steerActuatorDelay = 0.2
|
||||
ret.steerActuatorDelay = 0.12
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
elif candidate == CAR.SILVERADO:
|
||||
|
||||
@@ -14,8 +14,8 @@ class CarControllerParams:
|
||||
STEER_STEP = 3 # Active control frames per command (~33hz)
|
||||
INACTIVE_STEER_STEP = 10 # Inactive control frames per command (10hz)
|
||||
STEER_DELTA_UP = 10 # Delta rates require review due to observed EPS weakness
|
||||
STEER_DELTA_DOWN = 25
|
||||
STEER_DRIVER_ALLOWANCE = 50
|
||||
STEER_DELTA_DOWN = 15
|
||||
STEER_DRIVER_ALLOWANCE = 65
|
||||
STEER_DRIVER_MULTIPLIER = 4
|
||||
STEER_DRIVER_FACTOR = 100
|
||||
NEAR_STOP_BRAKE_PHASE = 0.5 # m/s
|
||||
|
||||
@@ -171,12 +171,14 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
[HONDA_VERSION_REQUEST],
|
||||
[HONDA_VERSION_RESPONSE],
|
||||
bus=1,
|
||||
logging=True
|
||||
),
|
||||
# Query Nidec PT bus from camera for data collection
|
||||
Request(
|
||||
[StdQueries.UDS_VERSION_REQUEST],
|
||||
[StdQueries.UDS_VERSION_RESPONSE],
|
||||
bus=0,
|
||||
logging=True
|
||||
),
|
||||
],
|
||||
extra_ecus=[
|
||||
|
||||
@@ -199,11 +199,7 @@ class CarController:
|
||||
hud_control.leadVisible, set_speed_in_units, stopping, CC.cruiseControl.override, CS.mainEnabled))
|
||||
|
||||
# 20 Hz LFA MFA message
|
||||
if self.frame % 5 == 0 and self.car_fingerprint in (CAR.SONATA, CAR.PALISADE, CAR.IONIQ, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021,
|
||||
CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_CEED, CAR.KIA_SELTOS, CAR.KONA_EV, CAR.KONA_EV_2022,
|
||||
CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.SANTA_FE_2022,
|
||||
CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.GENESIS_G70_2020, CAR.SANTA_FE_PHEV_2022,
|
||||
CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020):
|
||||
if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value:
|
||||
can_sends.append(hyundaican.create_lfahda_mfc(self.packer, CC.enabled, CC.latActive, lateral_paused, blinking_icon))
|
||||
|
||||
# 5 Hz ACC options
|
||||
|
||||
@@ -44,6 +44,10 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.flags |= HyundaiFlags.CANFD_ALT_GEARS.value
|
||||
if candidate not in CANFD_RADAR_SCC_CAR:
|
||||
ret.flags |= HyundaiFlags.CANFD_CAMERA_SCC.value
|
||||
else:
|
||||
# Send LFA message on cars with HDA
|
||||
if 0x485 in fingerprint[2]:
|
||||
ret.flags |= HyundaiFlags.SEND_LFA.value
|
||||
|
||||
ret.steerActuatorDelay = 0.1 # Default delay
|
||||
ret.steerLimitTimer = 0.4
|
||||
|
||||
@@ -58,10 +58,9 @@ class HyundaiFlags(IntFlag):
|
||||
CANFD_CAMERA_SCC = 8
|
||||
|
||||
ALT_LIMITS = 16
|
||||
|
||||
ENABLE_BLINKERS = 32
|
||||
|
||||
CANFD_ALT_GEARS_2 = 64
|
||||
SEND_LFA = 128
|
||||
|
||||
SP_CAN_LFA_BTN = 128
|
||||
|
||||
@@ -1565,7 +1564,6 @@ FW_VERSIONS = {
|
||||
CAR.TUCSON_4TH_GEN: {
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.01 99211-N9240 14T',
|
||||
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW010 14X',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ',
|
||||
@@ -1656,7 +1654,7 @@ FEATURES = {
|
||||
"use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.KONA_EV_2022, CAR.KIA_K5_HEV_2020},
|
||||
|
||||
# these cars use the FCA11 message for the AEB and FCW signals, all others use SCC12
|
||||
"use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020},
|
||||
"use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_OPTIMA_G4_FL},
|
||||
}
|
||||
|
||||
CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5, CAR.TUCSON_4TH_GEN, CAR.TUCSON_HYBRID_4TH_GEN, CAR.KIA_SPORTAGE_HYBRID_5TH_GEN, CAR.SANTA_CRUZ_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_PHEV_4TH_GEN, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_NIRO_HEV_2ND_GEN}
|
||||
@@ -1671,7 +1669,8 @@ HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_N
|
||||
EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KONA_EV_2022, CAR.KIA_EV6, CAR.IONIQ_5, CAR.GENESIS_GV60_EV_1ST_GEN}
|
||||
|
||||
# these cars require a special panda safety mode due to missing counters and checksums in the messages
|
||||
LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022}
|
||||
LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.VELOSTER,
|
||||
CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022}
|
||||
|
||||
# If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points.
|
||||
# If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py
|
||||
|
||||
@@ -20,7 +20,7 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
GearShifter = car.CarState.GearShifter
|
||||
EventName = car.CarEvent.EventName
|
||||
TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, bool], float]
|
||||
TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, float, bool], float]
|
||||
|
||||
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
|
||||
ACCEL_MAX = 2.0
|
||||
@@ -145,7 +145,7 @@ class CarInterfaceBase(ABC):
|
||||
return self.get_steer_feedforward_default
|
||||
|
||||
@staticmethod
|
||||
def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, friction_compensation):
|
||||
def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, vego, friction_compensation):
|
||||
# The default is a linear relationship between torque and lateral acceleration (accounting for road roll and steering friction)
|
||||
friction_interp = interp(
|
||||
apply_center_deadzone(lateral_accel_error, lateral_accel_deadzone),
|
||||
|
||||
@@ -230,7 +230,7 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
|
||||
return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt)
|
||||
|
||||
def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
|
||||
return NoEntryAlert(f"Speed Below {get_display_speed(CP.minEnableSpeed, metric)}")
|
||||
return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage")
|
||||
|
||||
|
||||
def below_steer_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
|
||||
@@ -835,8 +835,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
|
||||
},
|
||||
|
||||
EventName.espDisabled: {
|
||||
ET.SOFT_DISABLE: soft_disable_alert("ESP Off"),
|
||||
ET.NO_ENTRY: NoEntryAlert("ESP Off"),
|
||||
ET.SOFT_DISABLE: soft_disable_alert("Electronic Stability Control Disabled"),
|
||||
ET.NO_ENTRY: NoEntryAlert("Electronic Stability Control Disabled"),
|
||||
},
|
||||
|
||||
EventName.lowBattery: {
|
||||
|
||||
@@ -64,10 +64,10 @@ class LatControlTorque(LatControl):
|
||||
error = setpoint - measurement
|
||||
gravity_adjusted_lateral_accel = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY
|
||||
pid_log.error = self.torque_from_lateral_accel(error, self.torque_params, error,
|
||||
lateral_accel_deadzone, friction_compensation=False)
|
||||
lateral_accel_deadzone, CS.vEgo, friction_compensation=False)
|
||||
ff = self.torque_from_lateral_accel(gravity_adjusted_lateral_accel, self.torque_params,
|
||||
desired_lateral_accel - actual_lateral_accel,
|
||||
lateral_accel_deadzone, friction_compensation=True)
|
||||
lateral_accel_deadzone, CS.vEgo, friction_compensation=True)
|
||||
|
||||
freeze_integrator = steer_limited or CS.steeringPressed or CS.vEgo < 5
|
||||
output_torque = self.pid.update(pid_log.error,
|
||||
|
||||
@@ -1 +1 @@
|
||||
fbf92051507b7a7585907b58baadec6b8cc475af
|
||||
3e53ce81f1ce26409fdc4479e650ef5626130876
|
||||
+132
-15
@@ -1,15 +1,17 @@
|
||||
#include "tools/cabana/binaryview.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QFontDatabase>
|
||||
#include <QHeaderView>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QToolTip>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "tools/cabana/commands.h"
|
||||
#include "tools/cabana/signaledit.h"
|
||||
#include "tools/cabana/streams/abstractstream.h"
|
||||
|
||||
// BinaryView
|
||||
@@ -38,6 +40,63 @@ BinaryView::BinaryView(QWidget *parent) : QTableView(parent) {
|
||||
|
||||
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &BinaryView::refresh);
|
||||
QObject::connect(UndoStack::instance(), &QUndoStack::indexChanged, this, &BinaryView::refresh);
|
||||
|
||||
addShortcuts();
|
||||
}
|
||||
|
||||
void BinaryView::addShortcuts() {
|
||||
// Delete (x, backspace, delete)
|
||||
QShortcut *shortcut_delete_x = new QShortcut(QKeySequence(Qt::Key_X), this);
|
||||
QShortcut *shortcut_delete_backspace = new QShortcut(QKeySequence(Qt::Key_Backspace), this);
|
||||
QShortcut *shortcut_delete_delete = new QShortcut(QKeySequence(Qt::Key_Delete), this);
|
||||
QObject::connect(shortcut_delete_delete, &QShortcut::activated, shortcut_delete_x, &QShortcut::activated);
|
||||
QObject::connect(shortcut_delete_backspace, &QShortcut::activated, shortcut_delete_x, &QShortcut::activated);
|
||||
QObject::connect(shortcut_delete_x, &QShortcut::activated, [=]{
|
||||
if (hovered_sig != nullptr) {
|
||||
emit removeSignal(hovered_sig);
|
||||
hovered_sig = nullptr;
|
||||
}
|
||||
});
|
||||
|
||||
// Change endianness (e)
|
||||
QShortcut *shortcut_endian = new QShortcut(QKeySequence(Qt::Key_E), this);
|
||||
QObject::connect(shortcut_endian, &QShortcut::activated, [=]{
|
||||
if (hovered_sig != nullptr) {
|
||||
const Signal *hovered_sig_prev = hovered_sig;
|
||||
Signal s = *hovered_sig;
|
||||
s.is_little_endian = !s.is_little_endian;
|
||||
emit editSignal(hovered_sig, s);
|
||||
|
||||
hovered_sig = nullptr;
|
||||
highlight(hovered_sig_prev);
|
||||
}
|
||||
});
|
||||
|
||||
// Change signedness (s)
|
||||
QShortcut *shortcut_sign = new QShortcut(QKeySequence(Qt::Key_S), this);
|
||||
QObject::connect(shortcut_sign, &QShortcut::activated, [=]{
|
||||
if (hovered_sig != nullptr) {
|
||||
const Signal *hovered_sig_prev = hovered_sig;
|
||||
Signal s = *hovered_sig;
|
||||
s.is_signed = !s.is_signed;
|
||||
emit editSignal(hovered_sig, s);
|
||||
|
||||
hovered_sig = nullptr;
|
||||
highlight(hovered_sig_prev);
|
||||
}
|
||||
});
|
||||
|
||||
// Open chart (c, p, g)
|
||||
QShortcut *shortcut_plot = new QShortcut(QKeySequence(Qt::Key_P), this);
|
||||
QShortcut *shortcut_plot_g = new QShortcut(QKeySequence(Qt::Key_G), this);
|
||||
QShortcut *shortcut_plot_c = new QShortcut(QKeySequence(Qt::Key_C), this);
|
||||
QObject::connect(shortcut_plot_g, &QShortcut::activated, shortcut_plot, &QShortcut::activated);
|
||||
QObject::connect(shortcut_plot_c, &QShortcut::activated, shortcut_plot, &QShortcut::activated);
|
||||
QObject::connect(shortcut_plot, &QShortcut::activated, [=]{
|
||||
if (hovered_sig != nullptr) {
|
||||
emit showChart(model->msg_id, hovered_sig, true, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QSize BinaryView::minimumSizeHint() const {
|
||||
@@ -83,7 +142,7 @@ void BinaryView::mousePressEvent(QMouseEvent *event) {
|
||||
if (bit_idx == s->lsb || bit_idx == s->msb) {
|
||||
anchor_index = model->bitIndex(bit_idx == s->lsb ? s->msb : s->lsb, true);
|
||||
resize_sig = s;
|
||||
delegate->selection_color = item->bg_color;
|
||||
delegate->selection_color = getColor(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -143,8 +202,8 @@ void BinaryView::refresh() {
|
||||
anchor_index = QModelIndex();
|
||||
resize_sig = nullptr;
|
||||
hovered_sig = nullptr;
|
||||
highlightPosition(QCursor::pos());
|
||||
model->refresh();
|
||||
highlightPosition(QCursor::pos());
|
||||
}
|
||||
|
||||
QSet<const Signal *> BinaryView::getOverlappingSignals() const {
|
||||
@@ -266,6 +325,17 @@ BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(pa
|
||||
hex_font.setBold(true);
|
||||
}
|
||||
|
||||
bool BinaryItemDelegate::isSameColor(const QModelIndex &index, int dx, int dy) const {
|
||||
QModelIndex index2 = index.sibling(index.row() + dy, index.column() + dx);
|
||||
if (!index2.isValid()) {
|
||||
return false;
|
||||
}
|
||||
auto color1 = ((const BinaryViewModel::Item *)index.internalPointer())->bg_color;
|
||||
auto color2 = ((const BinaryViewModel::Item *)index2.internalPointer())->bg_color;
|
||||
// Ignore alpha
|
||||
return (color1.red() == color2.red()) && (color2.green() == color2.green()) && (color1.blue() == color2.blue());
|
||||
}
|
||||
|
||||
void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||
auto item = (const BinaryViewModel::Item *)index.internalPointer();
|
||||
BinaryView *bin_view = (BinaryView *)parent();
|
||||
@@ -277,24 +347,71 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
||||
} else if (option.state & QStyle::State_Selected) {
|
||||
painter->fillRect(option.rect, selection_color);
|
||||
painter->setPen(option.palette.color(QPalette::BrightText));
|
||||
} else if (!item->sigs.isEmpty() && (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig))) {
|
||||
bool sig_hovered = item->sigs.contains(bin_view->hovered_sig);
|
||||
int min_alpha = item->sigs.contains(bin_view->hovered_sig) ? 255 : 50;
|
||||
} else if (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig)) { // not resizing
|
||||
QColor bg = item->bg_color;
|
||||
if (bg.alpha() < min_alpha) {
|
||||
bg.setAlpha(min_alpha);
|
||||
if (bin_view->hovered_sig && item->sigs.contains(bin_view->hovered_sig)) {
|
||||
bg.setAlpha(255);
|
||||
painter->fillRect(option.rect, bg.darker(125)); // 4/5x brightness
|
||||
painter->setPen(option.palette.color(QPalette::BrightText));
|
||||
} else {
|
||||
if (item->sigs.size() > 0) {
|
||||
drawBorder(painter, option, index);
|
||||
bg.setAlpha(std::max(50, bg.alpha()));
|
||||
}
|
||||
painter->fillRect(option.rect, bg);
|
||||
painter->setPen(Qt::black);
|
||||
}
|
||||
painter->fillRect(option.rect, sig_hovered ? bg.darker(125) : bg); // 4/5x brightness
|
||||
painter->setPen(sig_hovered ? option.palette.color(QPalette::BrightText) : Qt::black);
|
||||
} else {
|
||||
painter->fillRect(option.rect, item->bg_color);
|
||||
}
|
||||
|
||||
|
||||
painter->drawText(option.rect, Qt::AlignCenter, item->val);
|
||||
if (item->is_msb || item->is_lsb) {
|
||||
painter->setFont(small_font);
|
||||
painter->drawText(option.rect, Qt::AlignHCenter | Qt::AlignBottom, item->is_msb ? "MSB" : "LSB");
|
||||
painter->drawText(option.rect.adjusted(8, 0, -8, -3), Qt::AlignRight | Qt::AlignBottom, item->is_msb ? "M" : "L");
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
// Draw border on edge of signal
|
||||
void BinaryItemDelegate::drawBorder(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||
auto item = (const BinaryViewModel::Item *)index.internalPointer();
|
||||
QColor border_color = item->bg_color;
|
||||
border_color.setAlphaF(1.0);
|
||||
|
||||
bool draw_left = !isSameColor(index, -1, 0);
|
||||
bool draw_top = !isSameColor(index, 0, -1);
|
||||
bool draw_right = !isSameColor(index, 1, 0);
|
||||
bool draw_bottom = !isSameColor(index, 0, 1);
|
||||
|
||||
const int spacing = 2;
|
||||
QRect rc = option.rect.adjusted(draw_left * 3, draw_top * spacing, draw_right * -3, draw_bottom * -spacing);
|
||||
QRegion subtract;
|
||||
if (!draw_top) {
|
||||
if (!draw_left && !isSameColor(index, -1, -1)) {
|
||||
subtract += QRect{rc.left(), rc.top(), 3, spacing};
|
||||
} else if (!draw_right && !isSameColor(index, 1, -1)) {
|
||||
subtract += QRect{rc.right() - 2, rc.top(), 3, spacing};
|
||||
}
|
||||
}
|
||||
if (!draw_bottom) {
|
||||
if (!draw_left && !isSameColor(index, -1, 1)) {
|
||||
subtract += QRect{rc.left(), rc.bottom() - (spacing - 1), 3, spacing};
|
||||
} else if (!draw_right && !isSameColor(index, 1, 1)) {
|
||||
subtract += QRect{rc.right() - 2, rc.bottom() - (spacing - 1), 3, spacing};
|
||||
}
|
||||
}
|
||||
|
||||
painter->setPen(QPen(border_color, 1));
|
||||
if (draw_left) painter->drawLine(rc.topLeft(), rc.bottomLeft());
|
||||
if (draw_right) painter->drawLine(rc.topRight(), rc.bottomRight());
|
||||
if (draw_bottom) painter->drawLine(rc.bottomLeft(), rc.bottomRight());
|
||||
if (draw_top) painter->drawLine(rc.topLeft(), rc.topRight());
|
||||
|
||||
painter->setClipRegion(QRegion(rc).subtracted(subtract));
|
||||
if (!subtract.isEmpty()) {
|
||||
// fill gaps inside corners.
|
||||
painter->setPen(QPen(border_color, 2));
|
||||
for (auto &r : subtract) {
|
||||
painter->drawRect(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public:
|
||||
BinaryItemDelegate(QObject *parent);
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void setSelectionColor(const QColor &color) { selection_color = color; }
|
||||
bool isSameColor(const QModelIndex &index, int dx, int dy) const;
|
||||
void drawBorder(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
|
||||
QFont small_font, hex_font;
|
||||
QColor selection_color;
|
||||
@@ -66,8 +68,12 @@ signals:
|
||||
void signalHovered(const Signal *sig);
|
||||
void addSignal(int start_bit, int size, bool little_endian);
|
||||
void resizeSignal(const Signal *sig, int from, int size);
|
||||
void removeSignal(const Signal *sig);
|
||||
void editSignal(const Signal *origin_s, Signal &s);
|
||||
void showChart(const QString &name, const Signal *sig, bool show, bool merge);
|
||||
|
||||
private:
|
||||
void addShortcuts();
|
||||
void refresh();
|
||||
std::tuple<int, int, bool> getSelection(QModelIndex index);
|
||||
void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) override;
|
||||
|
||||
@@ -364,6 +364,8 @@ ChartView::ChartView(QWidget *parent) : QChartView(nullptr, parent) {
|
||||
}
|
||||
|
||||
void ChartView::addSeries(const QString &msg_id, const Signal *sig) {
|
||||
if (hasSeries(msg_id, sig)) return;
|
||||
|
||||
QXYSeries *series = createSeries(series_type, getColor(sig));
|
||||
chart()->addSeries(series);
|
||||
series->attachAxis(axis_x);
|
||||
@@ -438,9 +440,7 @@ void ChartView::manageSeries() {
|
||||
emit remove();
|
||||
} else {
|
||||
for (auto s : items) {
|
||||
if (!hasSeries(s->msg_id, s->sig)) {
|
||||
addSeries(s->msg_id, s->sig);
|
||||
}
|
||||
addSeries(s->msg_id, s->sig);
|
||||
}
|
||||
for (auto it = sigs.begin(); it != sigs.end(); /**/) {
|
||||
bool exists = std::any_of(items.cbegin(), items.cend(), [&](auto &s) {
|
||||
@@ -780,8 +780,10 @@ QXYSeries *ChartView::createSeries(QAbstractSeries::SeriesType type, QColor colo
|
||||
QXYSeries *series = nullptr;
|
||||
if (type == QAbstractSeries::SeriesTypeLine) {
|
||||
series = new QLineSeries(this);
|
||||
chart()->legend()->setMarkerShape(QLegend::MarkerShapeRectangle);
|
||||
} else {
|
||||
series = new QScatterSeries(this);
|
||||
chart()->legend()->setMarkerShape(QLegend::MarkerShapeCircle);
|
||||
}
|
||||
series->setColor(color);
|
||||
// TODO: Due to a bug in CameraWidget the camera frames
|
||||
@@ -850,7 +852,9 @@ SeriesSelector::SeriesSelector(QString title, QWidget *parent) : QDialog(parent)
|
||||
// buttons
|
||||
QVBoxLayout *btn_layout = new QVBoxLayout();
|
||||
QPushButton *add_btn = new QPushButton(utils::icon("chevron-right"), "", this);
|
||||
add_btn->setEnabled(false);
|
||||
QPushButton *remove_btn = new QPushButton(utils::icon("chevron-left"), "", this);
|
||||
remove_btn->setEnabled(false);
|
||||
btn_layout->addStretch(0);
|
||||
btn_layout->addWidget(add_btn);
|
||||
btn_layout->addWidget(remove_btn);
|
||||
|
||||
@@ -54,6 +54,8 @@ private:
|
||||
std::map<uint32_t, DBCMsg> msgs;
|
||||
};
|
||||
|
||||
const QString UNTITLED = "untitled";
|
||||
|
||||
// TODO: Add helper function in dbc.h
|
||||
double get_raw_value(uint8_t *data, size_t data_size, const Signal &sig);
|
||||
bool operator==(const Signal &l, const Signal &r);
|
||||
@@ -63,7 +65,7 @@ int bigEndianBitIndex(int index);
|
||||
void updateSigSizeParamsFromRange(Signal &s, int start_bit, int size);
|
||||
std::pair<int, int> getSignalRange(const Signal *s);
|
||||
DBCManager *dbc();
|
||||
inline QString msgName(const QString &id, const char *def = "untitled") {
|
||||
inline QString msgName(const QString &id) {
|
||||
auto msg = dbc()->msg(id);
|
||||
return msg ? msg->name : def;
|
||||
return msg ? msg->name : UNTITLED;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "tools/cabana/detailwidget.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFormLayout>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
@@ -75,6 +74,9 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart
|
||||
QObject::connect(binary_view, &BinaryView::addSignal, signal_view->model, &SignalModel::addSignal);
|
||||
QObject::connect(binary_view, &BinaryView::signalHovered, signal_view, &SignalView::signalHovered);
|
||||
QObject::connect(binary_view, &BinaryView::signalClicked, signal_view, &SignalView::expandSignal);
|
||||
QObject::connect(binary_view, &BinaryView::editSignal, signal_view->model, &SignalModel::saveSignal);
|
||||
QObject::connect(binary_view, &BinaryView::removeSignal, signal_view->model, &SignalModel::removeSignal);
|
||||
QObject::connect(binary_view, &BinaryView::showChart, charts, &ChartsWidget::showChart);
|
||||
QObject::connect(signal_view, &SignalView::showChart, charts, &ChartsWidget::showChart);
|
||||
QObject::connect(signal_view, &SignalView::highlight, binary_view, &BinaryView::highlight);
|
||||
QObject::connect(tab_widget, &QTabWidget::currentChanged, [this]() { updateState(); });
|
||||
@@ -190,11 +192,13 @@ void DetailWidget::removeMsg() {
|
||||
|
||||
// EditMessageDialog
|
||||
|
||||
EditMessageDialog::EditMessageDialog(const QString &msg_id, const QString &title, int size, QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle(tr("Edit message"));
|
||||
EditMessageDialog::EditMessageDialog(const QString &msg_id, const QString &title, int size, QWidget *parent)
|
||||
: original_name(title), QDialog(parent) {
|
||||
setWindowTitle(tr("Edit message: %1").arg(msg_id));
|
||||
QFormLayout *form_layout = new QFormLayout(this);
|
||||
form_layout->addRow("ID", new QLabel(msg_id));
|
||||
|
||||
form_layout->addRow("", error_label = new QLabel);
|
||||
error_label->setVisible(false);
|
||||
name_edit = new QLineEdit(title, this);
|
||||
name_edit->setValidator(new NameValidator(name_edit));
|
||||
form_layout->addRow(tr("Name"), name_edit);
|
||||
@@ -205,12 +209,28 @@ EditMessageDialog::EditMessageDialog(const QString &msg_id, const QString &title
|
||||
size_spin->setValue(size);
|
||||
form_layout->addRow(tr("Size"), size_spin);
|
||||
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
form_layout->addRow(buttonBox);
|
||||
setFixedWidth(parent->width() * 0.9);
|
||||
btn_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
btn_box->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
form_layout->addRow(btn_box);
|
||||
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
setFixedWidth(parent->width() * 0.9);
|
||||
connect(name_edit, &QLineEdit::textEdited, this, &EditMessageDialog::validateName);
|
||||
connect(btn_box, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(btn_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
}
|
||||
|
||||
void EditMessageDialog::validateName(const QString &text) {
|
||||
bool valid = false;
|
||||
error_label->setVisible(false);
|
||||
if (!text.isEmpty() && text != original_name && text.compare(UNTITLED, Qt::CaseInsensitive) != 0) {
|
||||
valid = std::none_of(dbc()->messages().begin(), dbc()->messages().end(),
|
||||
[&text](auto &m) { return m.second.name == text; });
|
||||
if (!valid) {
|
||||
error_label->setText(tr("Name already exists"));
|
||||
error_label->setVisible(true);
|
||||
}
|
||||
}
|
||||
btn_box->button(QDialogButtonBox::Ok)->setEnabled(valid);
|
||||
}
|
||||
|
||||
// WelcomeWidget
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QSplitter>
|
||||
#include <QStackedLayout>
|
||||
#include <QTabWidget>
|
||||
@@ -14,8 +15,12 @@
|
||||
class EditMessageDialog : public QDialog {
|
||||
public:
|
||||
EditMessageDialog(const QString &msg_id, const QString &title, int size, QWidget *parent);
|
||||
void validateName(const QString &text);
|
||||
|
||||
QString original_name;
|
||||
QDialogButtonBox *btn_box;
|
||||
QLineEdit *name_edit;
|
||||
QLabel *error_label;
|
||||
QSpinBox *size_spin;
|
||||
};
|
||||
|
||||
|
||||
@@ -81,11 +81,12 @@ void HistoryLogModel::updateState() {
|
||||
if (!msg_id.isEmpty()) {
|
||||
uint64_t current_time = (can->lastMessage(msg_id).ts + can->routeStartTime()) * 1e9 + 1;
|
||||
auto new_msgs = dynamic_mode ? fetchData(current_time, last_fetch_time) : fetchData(0);
|
||||
if ((has_more_data = !new_msgs.empty())) {
|
||||
if (!new_msgs.empty()) {
|
||||
beginInsertRows({}, 0, new_msgs.size() - 1);
|
||||
messages.insert(messages.begin(), std::move_iterator(new_msgs.begin()), std::move_iterator(new_msgs.end()));
|
||||
endInsertRows();
|
||||
}
|
||||
has_more_data = new_msgs.size() >= batch_size;
|
||||
last_fetch_time = current_time;
|
||||
}
|
||||
}
|
||||
@@ -93,11 +94,12 @@ void HistoryLogModel::updateState() {
|
||||
void HistoryLogModel::fetchMore(const QModelIndex &parent) {
|
||||
if (!messages.empty()) {
|
||||
auto new_msgs = fetchData(messages.back().mono_time);
|
||||
if ((has_more_data = !new_msgs.empty())) {
|
||||
if (!new_msgs.empty()) {
|
||||
beginInsertRows({}, messages.size(), messages.size() + new_msgs.size() - 1);
|
||||
messages.insert(messages.end(), std::move_iterator(new_msgs.begin()), std::move_iterator(new_msgs.end()));
|
||||
endInsertRows();
|
||||
}
|
||||
has_more_data = new_msgs.size() >= batch_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -449,3 +449,8 @@ void SignalView::signalHovered(const Signal *sig) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SignalView::leaveEvent(QEvent *event) {
|
||||
emit highlight(nullptr);
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ signals:
|
||||
|
||||
private:
|
||||
void rowsChanged();
|
||||
void leaveEvent(QEvent *event);
|
||||
|
||||
QString msg_id;
|
||||
QTreeView *tree;
|
||||
|
||||
Reference in New Issue
Block a user