mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-07 23:55:43 +08:00
Merge remote-tracking branch 'upstream/master' into hkg-legacy-long-update
This commit is contained in:
@@ -204,11 +204,12 @@ jobs:
|
||||
$UNIT_TEST selfdrive/boardd && \
|
||||
$UNIT_TEST selfdrive/controls && \
|
||||
$UNIT_TEST selfdrive/monitoring && \
|
||||
$UNIT_TEST selfdrive/loggerd && \
|
||||
$UNIT_TEST system/loggerd && \
|
||||
$UNIT_TEST selfdrive/car && \
|
||||
$UNIT_TEST selfdrive/locationd && \
|
||||
$UNIT_TEST system/ubloxd && \
|
||||
selfdrive/locationd/test/_test_locationd_lib.py && \
|
||||
./selfdrive/locationd/test/test_glonass_runner && \
|
||||
./system/ubloxd/tests/test_glonass_runner && \
|
||||
$UNIT_TEST selfdrive/athena && \
|
||||
$UNIT_TEST selfdrive/thermald && \
|
||||
$UNIT_TEST system/hardware/tici && \
|
||||
@@ -219,7 +220,7 @@ jobs:
|
||||
./common/tests/test_util && \
|
||||
./common/tests/test_swaglog && \
|
||||
./selfdrive/boardd/tests/test_boardd_usbprotocol && \
|
||||
./selfdrive/loggerd/tests/test_logger &&\
|
||||
./system/loggerd/tests/test_logger &&\
|
||||
./system/proclogd/tests/test_proclog && \
|
||||
./tools/replay/tests/test_replay && \
|
||||
./tools/cabana/tests/test_cabana && \
|
||||
|
||||
@@ -46,9 +46,6 @@ selfdrive/mapd/default_speeds_by_region.json
|
||||
system/proclogd/proclogd
|
||||
selfdrive/ui/_ui
|
||||
selfdrive/test/longitudinal_maneuvers/out
|
||||
selfdrive/visiond/visiond
|
||||
selfdrive/sensord/_gpsd
|
||||
selfdrive/sensord/_sensord
|
||||
system/camerad/camerad
|
||||
system/camerad/test/ae_gray_test
|
||||
selfdrive/modeld/_modeld
|
||||
|
||||
Vendored
+6
-5
@@ -157,10 +157,11 @@ pipeline {
|
||||
phone_steps("tici-common", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test power draw", "python system/hardware/tici/test_power_draw.py"],
|
||||
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"],
|
||||
["test pigeond", "python selfdrive/sensord/tests/test_pigeond.py"],
|
||||
["test loggerd", "python system/loggerd/tests/test_loggerd.py"],
|
||||
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python system/loggerd/tests/test_encoder.py"],
|
||||
["test pigeond", "python system/sensord/tests/test_pigeond.py"],
|
||||
["test manager", "python selfdrive/manager/test/test_manager.py"],
|
||||
["test pandad", "python selfdrive/boardd/tests/test_pandad.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -192,11 +193,11 @@ pipeline {
|
||||
steps {
|
||||
phone_steps("tici-lsmc", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"],
|
||||
["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"],
|
||||
])
|
||||
phone_steps("tici-bmx-lsm", [
|
||||
["build", "cd selfdrive/manager && ./build.py"],
|
||||
["test sensord", "cd selfdrive/sensord/tests && python -m unittest test_sensord.py"],
|
||||
["test sensord", "cd system/sensord/tests && python -m unittest test_sensord.py"],
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,10 @@ Directory Structure
|
||||
├── clocksd # Broadcasts current time
|
||||
├── hardware # Hardware abstraction classes
|
||||
├── logcatd # systemd journal as a service
|
||||
└── proclogd # Logs information from /proc
|
||||
├── loggerd # Logger and uploader of car data
|
||||
├── proclogd # Logs information from /proc
|
||||
├── sensord # IMU interface code
|
||||
└── ubloxd # u-blox GNSS module interface code
|
||||
└── selfdrive # Code needed to drive the car
|
||||
├── assets # Fonts, images, and sounds for UI
|
||||
├── athena # Allows communication with the app
|
||||
@@ -117,12 +120,10 @@ Directory Structure
|
||||
├── controls # Planning and controls
|
||||
├── debug # Tools to help you debug and do car ports
|
||||
├── locationd # Precise localization and vehicle parameter estimation
|
||||
├── loggerd # Logger and uploader of car data
|
||||
├── manager # Daemon that starts/stops all other daemons as needed
|
||||
├── modeld # Driving and monitoring model runners
|
||||
├── monitoring # Daemon to determine driver attention
|
||||
├── navd # Turn-by-turn navigation
|
||||
├── sensord # IMU interface code
|
||||
├── test # Unit tests, system tests, and a car simulator
|
||||
└── ui # The UI
|
||||
|
||||
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
Version 0.9.2 (2023-03-XX)
|
||||
========================
|
||||
* Draw MPC path instead of model predicted path, this is a more accurate representation of what the car will do.
|
||||
* Buick LaCrosse 2017-19 support thanks to koch-cf!
|
||||
* Škoda Fabia 2022-23 support thanks to jyoung8607!
|
||||
|
||||
Version 0.9.1 (2023-02-23)
|
||||
Version 0.9.1 (2023-02-28)
|
||||
========================
|
||||
* New driving model
|
||||
* 30% improved height estimation resulting in better driving performance for tall cars
|
||||
|
||||
+3
-2
@@ -398,6 +398,7 @@ SConscript([
|
||||
'system/camerad/SConscript',
|
||||
'system/clocksd/SConscript',
|
||||
'system/proclogd/SConscript',
|
||||
'system/ubloxd/SConscript',
|
||||
])
|
||||
if arch != "Darwin":
|
||||
SConscript(['system/logcatd/SConscript'])
|
||||
@@ -424,10 +425,10 @@ SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/boardd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/loggerd/SConscript'])
|
||||
SConscript(['system/loggerd/SConscript'])
|
||||
|
||||
SConscript(['selfdrive/locationd/SConscript'])
|
||||
SConscript(['selfdrive/sensord/SConscript'])
|
||||
SConscript(['system/sensord/SConscript'])
|
||||
SConscript(['selfdrive/ui/SConscript'])
|
||||
SConscript(['selfdrive/navd/SConscript'])
|
||||
|
||||
|
||||
+1
-1
Submodule cereal updated: b88523f05a...c516d5e985
+5
-4
@@ -98,8 +98,8 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"CompletedTrainingVersion", PERSISTENT},
|
||||
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"CurrentBootlog", PERSISTENT},
|
||||
{"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"DashcamOverride", PERSISTENT},
|
||||
{"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"DisablePowerDown", PERSISTENT},
|
||||
{"ExperimentalMode", PERSISTENT},
|
||||
@@ -111,7 +111,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"DoReboot", CLEAR_ON_MANAGER_START},
|
||||
{"DoShutdown", CLEAR_ON_MANAGER_START},
|
||||
{"DoUninstall", CLEAR_ON_MANAGER_START},
|
||||
{"FirmwareObdQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"FirmwareQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ForcePowerDown", CLEAR_ON_MANAGER_START},
|
||||
{"GitBranch", PERSISTENT},
|
||||
{"GitCommit", PERSISTENT},
|
||||
@@ -138,7 +138,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"IsReleaseBranch", CLEAR_ON_MANAGER_START},
|
||||
{"IsUpdateAvailable", CLEAR_ON_MANAGER_START},
|
||||
{"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"LaikadEphemeris", PERSISTENT | DONT_LOG},
|
||||
{"LaikadEphemerisV3", PERSISTENT | DONT_LOG},
|
||||
{"LanguageSetting", PERSISTENT},
|
||||
{"LastAthenaPingTime", CLEAR_ON_MANAGER_START},
|
||||
{"LastGPSPosition", PERSISTENT},
|
||||
@@ -155,7 +155,8 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"NavSettingTime24h", PERSISTENT},
|
||||
{"NavSettingLeftSide", PERSISTENT},
|
||||
{"NavdRender", PERSISTENT},
|
||||
{"ObdMultiplexingDisabled", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ObdMultiplexingChanged", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"ObdMultiplexingEnabled", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
|
||||
{"OpenpilotEnabledToggle", PERSISTENT},
|
||||
{"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
|
||||
{"PandaSignatures", CLEAR_ON_MANAGER_START},
|
||||
|
||||
+10
-8
@@ -4,7 +4,7 @@
|
||||
|
||||
A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system.
|
||||
|
||||
# 237 Supported Cars
|
||||
# 239 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|Video|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
@@ -17,6 +17,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Audi|Q3 2019-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=Q3 2019-23">J533</a>||
|
||||
|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=RS3 2018">J533</a>||
|
||||
|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Audi&model=S3 2015-17">J533</a>||
|
||||
|Buick|LaCrosse 2017-19[<sup>3</sup>](#footnotes)|Driver Confidence Package 2|openpilot|18 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Buick&model=LaCrosse 2017-19">OBD-II</a>||
|
||||
|Cadillac|Escalade 2017[<sup>3</sup>](#footnotes)|Driver Assist Package|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade 2017">OBD-II</a>||
|
||||
|Cadillac|Escalade ESV 2016[<sup>3</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|7 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Cadillac&model=Escalade ESV 2016">OBD-II</a>||
|
||||
|Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|openpilot available[<sup>1</sup>](#footnotes)|3 mph|6 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Chevrolet&model=Bolt EUV 2022-23">GM</a>|<a href="https://youtu.be/xvwzGMUA210" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
@@ -116,7 +117,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Kia|Seltos 2021|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=Seltos 2021">Hyundai A</a>||
|
||||
|Kia|Sorento 2018|Advanced Smart Cruise Control|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2018">Hyundai C</a>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Kia&model=Sorento 2019">Hyundai E</a>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Kia|Sorento 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 2022-23">Hyundai K</a>||
|
||||
|Kia|Sorento 2021-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 2021-23">Hyundai K</a>||
|
||||
|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>||
|
||||
@@ -125,14 +126,14 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|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>||
|
||||
|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES 2019-22">Toyota</a>||
|
||||
|Lexus|ES 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=ES Hybrid 2017-18">Toyota</a>||
|
||||
|Lexus|ES Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2017-18">Toyota</a>||
|
||||
|Lexus|ES Hybrid 2019-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=ES Hybrid 2019-23">Toyota</a>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=IS 2017-19">Toyota</a>||
|
||||
|Lexus|NX 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2018-19">Toyota</a>||
|
||||
|Lexus|NX 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX 2020-21">Toyota</a>||
|
||||
|Lexus|NX Hybrid 2018-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2018-19">Toyota</a>||
|
||||
|Lexus|NX Hybrid 2020-21|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=NX Hybrid 2020-21">Toyota</a>||
|
||||
|Lexus|RC 2017-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RC 2017-20">Toyota</a>||
|
||||
|Lexus|RC 2018-20|All|Stock|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RC 2018-20">Toyota</a>||
|
||||
|Lexus|RX 2016|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=RX 2016">Toyota</a>||
|
||||
|Lexus|RX 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2017-19">Toyota</a>||
|
||||
|Lexus|RX 2020-22|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Lexus&model=RX 2020-22">Toyota</a>||
|
||||
@@ -148,7 +149,7 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Nissan|Leaf 2018-22|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Leaf 2018-22">Nissan A</a>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=Rogue 2018-20">Nissan A</a>||
|
||||
|Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Nissan&model=X-Trail 2017">Nissan A</a>||
|
||||
|Ram|1500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Ram&model=1500 2019-22">Ram</a>||
|
||||
|Ram|1500 2019-23|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Ram&model=1500 2019-23">Ram</a>||
|
||||
|SEAT|Ateca 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Ateca 2018">J533</a>||
|
||||
|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=SEAT&model=Leon 2014-20">J533</a>||
|
||||
|Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Ascent 2019-21">Subaru A</a>||
|
||||
@@ -161,9 +162,10 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=Outback 2020-22">Subaru B</a>||
|
||||
|Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2018-19">Subaru A</a>|<a href="https://youtu.be/Agww7oE1k-s?t=26" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Subaru&model=XV 2020-21">Subaru A</a>||
|
||||
|Škoda|Fabia 2022-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Fabia 2022-23">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Kamiq 2021[<sup>7</sup>](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kamiq 2021">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
|Škoda|Karoq 2019-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Karoq 2019-21">J533</a>||
|
||||
|Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kodiaq 2018-19">J533</a>||
|
||||
|Škoda|Kodiaq 2017-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Kodiaq 2017-23">J533</a>||
|
||||
|Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia 2015, 2018-19">J533</a>||
|
||||
|Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Octavia RS 2016">J533</a>||
|
||||
|Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,9</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Škoda&model=Scala 2020">J533</a>[<sup>10</sup>](#footnotes)||
|
||||
@@ -178,10 +180,10 @@ A supported vehicle is one that just works when you install a comma three. All s
|
||||
|Toyota|Avalon Hybrid 2022|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Avalon Hybrid 2022">Toyota</a>||
|
||||
|Toyota|C-HR 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2017-20">Toyota</a>||
|
||||
|Toyota|C-HR 2021|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR 2021">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2017-19|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2017-19">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2017-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2017-20">Toyota</a>||
|
||||
|Toyota|C-HR Hybrid 2021-22|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=C-HR Hybrid 2021-22">Toyota</a>||
|
||||
|Toyota|Camry 2018-20|All|Stock|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=fkcjviZY9CM" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry 2021-22|All|openpilot|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2021-22">Toyota</a>||
|
||||
|Toyota|Camry 2021-23|All|openpilot|0 mph[<sup>6</sup>](#footnotes)|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry 2021-23">Toyota</a>||
|
||||
|Toyota|Camry Hybrid 2018-20|All|Stock|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2018-20">Toyota</a>|<a href="https://www.youtube.com/watch?v=Q2DYY0AWKgk" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Toyota|Camry Hybrid 2021-23|All|openpilot|0 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Camry Hybrid 2021-23">Toyota</a>||
|
||||
|Toyota|Corolla 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[](##)|[](##)|<a href="https://comma.ai/shop/comma-three.html?make=Toyota&model=Corolla 2017-19">Toyota</a>||
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ common
|
||||
sensorsd
|
||||
^^^^^^^^
|
||||
.. autodoxygenindex::
|
||||
:project: selfdrive_sensord_sensors
|
||||
:project: system_sensord_sensors
|
||||
|
||||
boardd
|
||||
^^^^^^
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ openpilot
|
||||
:maxdepth: 4
|
||||
|
||||
Debugging <selfdrive/debug/README.md>
|
||||
selfdrive/loggerd/README.md
|
||||
system/loggerd/README.md
|
||||
Driver Monitoring <selfdrive/monitoring/README.md>
|
||||
Process Replay <selfdrive/test/process_replay/README.md>
|
||||
|
||||
|
||||
+1
-1
Submodule laika_repo updated: 278b44ba8c...6fadabd860
+1
-1
Submodule opendbc updated: 510bfc0695...b7d4a6e271
+1
-1
Submodule panda updated: d2c2d5f926...d70fa4e120
Generated
+390
-31
@@ -113,9 +113,12 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
packaging = ">20.6"
|
||||
|
||||
[package.source]
|
||||
type = "url"
|
||||
url = "https://github.com/commaai/apex/releases/download/pytorch1.10.0%2Bcu11.1/apex-0.1-cp38-cp38-linux_x86_64.whl"
|
||||
url = "https://github.com/commaai/apex/releases/download/pytorch2.0.0%2Bcu11.8/apex-0.1-cp38-cp38-linux_x86_64.whl"
|
||||
|
||||
[[package]]
|
||||
name = "appdirs"
|
||||
@@ -457,6 +460,14 @@ python-versions = "*"
|
||||
docutils = ">=0.12"
|
||||
Sphinx = ">=4.0,<5.0.0 || >5.0.0,<6"
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "1.0.9"
|
||||
description = "Python bindings for the Brotli compression library"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "cachecontrol"
|
||||
version = "0.12.11"
|
||||
@@ -600,6 +611,17 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "3.26.0"
|
||||
description = "CMake is an open-source, cross-platform family of tools designed to build, test and package software"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
test = ["codecov (>=2.0.5)", "coverage (>=4.2)", "flake8 (>=3.0.4)", "path.py (>=11.5.0)", "pytest (>=3.0.3)", "pytest-cov (>=2.4.0)", "pytest-runner (>=2.9)", "pytest-virtualenv (>=1.7.0)", "scikit-build (>=0.10.0)", "setuptools (>=28.0.0)", "virtualenv (>=15.0.3)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.5"
|
||||
@@ -716,8 +738,8 @@ ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"]
|
||||
|
||||
[[package]]
|
||||
name = "cupy-cuda113"
|
||||
version = "10.6.0"
|
||||
name = "cupy-cuda11x"
|
||||
version = "11.6.0"
|
||||
description = "CuPy: NumPy & SciPy for GPU"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -725,12 +747,12 @@ python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
fastrlock = ">=0.5"
|
||||
numpy = ">=1.18,<1.25"
|
||||
numpy = ">=1.20,<1.27"
|
||||
|
||||
[package.extras]
|
||||
all = ["Cython (>=0.29.22,<3)", "optuna (>=2.0)", "scipy (>=1.4,<1.11)"]
|
||||
all = ["Cython (>=0.29.22,<3)", "optuna (>=2.0)", "scipy (>=1.6,<1.12)"]
|
||||
stylecheck = ["autopep8 (==1.5.5)", "flake8 (==3.8.4)", "mypy (==0.950)", "pbr (==5.5.1)", "pycodestyle (==2.6.0)", "types-setuptools (==57.4.14)"]
|
||||
test = ["hypothesis (>=6.37.2)", "pytest (>=6.2)"]
|
||||
test = ["hypothesis (>=6.37.2,<6.55.0)", "pytest (>=7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "cycler"
|
||||
@@ -1180,6 +1202,20 @@ monitor = ["psutil (>=5.7.0)"]
|
||||
recommended = ["backports.socketpair", "cffi (>=1.12.2)", "dnspython (>=1.16.0,<2.0)", "idna", "psutil (>=5.7.0)", "selectors2"]
|
||||
test = ["backports.socketpair", "cffi (>=1.12.2)", "contextvars (==2.4)", "coverage (>=5.0)", "coveralls (>=1.7.0)", "dnspython (>=1.16.0,<2.0)", "futures", "idna", "mock", "objgraph", "psutil (>=5.7.0)", "requests", "selectors2"]
|
||||
|
||||
[[package]]
|
||||
name = "geventhttpclient"
|
||||
version = "2.0.2"
|
||||
description = "http client library for gevent"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
brotli = "*"
|
||||
certifi = "*"
|
||||
gevent = ">=0.13"
|
||||
six = "*"
|
||||
|
||||
[[package]]
|
||||
name = "greenlet"
|
||||
version = "1.1.3.post0"
|
||||
@@ -1898,6 +1934,14 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "lit"
|
||||
version = "15.0.7"
|
||||
description = "A Software Testing Tool"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "lockfile"
|
||||
version = "0.12.2"
|
||||
@@ -2586,7 +2630,7 @@ numpy = [
|
||||
|
||||
[package.source]
|
||||
type = "url"
|
||||
url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu113/opencv_python_headless-4.5.5.64-cp38-cp38-manylinux_2_31_x86_64.whl"
|
||||
url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu118/opencv_python_headless-4.5.5.64-cp38-cp38-manylinux_2_31_x86_64.whl"
|
||||
|
||||
[[package]]
|
||||
name = "osmium"
|
||||
@@ -3339,6 +3383,14 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "python-rapidjson"
|
||||
version = "1.10"
|
||||
description = "Python wrapper around rapidjson"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "python-socketio"
|
||||
version = "5.7.2"
|
||||
@@ -4220,18 +4272,26 @@ python-versions = ">=3.6,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "torch"
|
||||
version = "1.11.0+cu113"
|
||||
version = "2.0.0+cu118"
|
||||
description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
python-versions = ">=3.8.0"
|
||||
|
||||
[package.dependencies]
|
||||
filelock = "*"
|
||||
jinja2 = "*"
|
||||
networkx = "*"
|
||||
sympy = "*"
|
||||
triton = {version = "2.0.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""}
|
||||
typing-extensions = "*"
|
||||
|
||||
[package.extras]
|
||||
opt-einsum = ["opt-einsum (>=3.3)"]
|
||||
|
||||
[package.source]
|
||||
type = "url"
|
||||
url = "https://download.pytorch.org/whl/cu113/torch-1.11.0%2Bcu113-cp38-cp38-linux_x86_64.whl"
|
||||
url = "https://download.pytorch.org/whl/cu118/torch-2.0.0%2Bcu118-cp38-cp38-linux_x86_64.whl"
|
||||
|
||||
[[package]]
|
||||
name = "torchsummary"
|
||||
@@ -4243,25 +4303,24 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "torchvision"
|
||||
version = "0.12.0+cu113"
|
||||
version = "0.15.1+cu118"
|
||||
description = "image and video datasets and models for torch deep learning"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
|
||||
[package.dependencies]
|
||||
numpy = "*"
|
||||
pillow = ">=5.3.0,<8.3.0 || >=8.4.0"
|
||||
requests = "*"
|
||||
torch = "1.11.0"
|
||||
typing-extensions = "*"
|
||||
torch = "2.0.0"
|
||||
|
||||
[package.extras]
|
||||
scipy = ["scipy"]
|
||||
|
||||
[package.source]
|
||||
type = "url"
|
||||
url = "https://download.pytorch.org/whl/cu113/torchvision-0.12.0%2Bcu113-cp38-cp38-linux_x86_64.whl"
|
||||
url = "https://download.pytorch.org/whl/cu118/torchvision-0.15.1%2Bcu118-cp38-cp38-linux_x86_64.whl"
|
||||
|
||||
[[package]]
|
||||
name = "tornado"
|
||||
@@ -4302,16 +4361,41 @@ test = ["pre-commit", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "triton"
|
||||
version = "1.1.1"
|
||||
version = "2.0.0"
|
||||
description = "A language and compiler for custom Deep Learning operations"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
cmake = "*"
|
||||
filelock = "*"
|
||||
lit = "*"
|
||||
torch = "*"
|
||||
|
||||
[package.extras]
|
||||
tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"]
|
||||
tutorials = ["matplotlib", "pandas", "tabulate"]
|
||||
|
||||
[[package]]
|
||||
name = "tritonclient"
|
||||
version = "2.28.0"
|
||||
description = "Python client library and utilities for communicating with Triton Inference Server"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = {version = ">=3.8.1", optional = true, markers = "extra == \"http\""}
|
||||
geventhttpclient = {version = ">=1.4.4,<=2.0.2", optional = true, markers = "extra == \"http\""}
|
||||
numpy = ">=1.19.1"
|
||||
python-rapidjson = ">=0.9.1"
|
||||
|
||||
[package.extras]
|
||||
all = ["aiohttp (>=3.8.1)", "geventhttpclient (>=1.4.4,<=2.0.2)", "grpcio (==1.41.0)", "numpy (>=1.19.1)", "protobuf (>=3.5.0,<3.20)", "python-rapidjson (>=0.9.1)"]
|
||||
grpc = ["grpcio (==1.41.0)", "numpy (>=1.19.1)", "protobuf (>=3.5.0,<3.20)", "python-rapidjson (>=0.9.1)"]
|
||||
http = ["aiohttp (>=3.8.1)", "geventhttpclient (>=1.4.4,<=2.0.2)", "numpy (>=1.19.1)", "python-rapidjson (>=0.9.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "types-atomicwrites"
|
||||
version = "1.4.5.1"
|
||||
@@ -4355,6 +4439,14 @@ python-versions = "*"
|
||||
[package.dependencies]
|
||||
types-urllib3 = "<1.27"
|
||||
|
||||
[[package]]
|
||||
name = "types-tabulate"
|
||||
version = "0.8.11"
|
||||
description = "Typing stubs for tabulate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-urllib3"
|
||||
version = "1.26.25.1"
|
||||
@@ -4567,7 +4659,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "~3.8"
|
||||
content-hash = "9e9495c896e6fd0855803aeaf46513c6c22424b86be820759a8baf27d44e73ee"
|
||||
content-hash = "b7cd75dfa0dcddff224696ccc7f41d87aac64652f744ab386321c1eee920fbe9"
|
||||
|
||||
[metadata.files]
|
||||
adal = [
|
||||
@@ -4877,6 +4969,90 @@ breathe = [
|
||||
{file = "breathe-4.34.0-py3-none-any.whl", hash = "sha256:48804dcf0e607a89fb6ad88c729ef12743a42db03ae9489be4ef8f7c4011774a"},
|
||||
{file = "breathe-4.34.0.tar.gz", hash = "sha256:ac0768a5e84addad3e632028fe67749c567aba2b29088493b64c2c1634bcdba1"},
|
||||
]
|
||||
brotli = [
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cc0283a406774f465fb45ec7efb66857c09ffefbe49ec20b7882eff6d3c86d3a"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11d3283d89af7033236fa4e73ec2cbe743d4f6a81d41bd234f24bf63dde979df"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1306004d49b84bd0c4f90457c6f57ad109f5cc6067a9664e12b7b79a9948ad"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1375b5d17d6145c798661b67e4ae9d5496920d9265e2f00f1c2c0b5ae91fbde"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cab1b5964b39607a66adbba01f1c12df2e55ac36c81ec6ed44f2fca44178bf1a"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ed6a5b3d23ecc00ea02e1ed8e0ff9a08f4fc87a1f58a2530e71c0f48adf882f"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cb02ed34557afde2d2da68194d12f5719ee96cfb2eacc886352cb73e3808fc5d"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3523f51818e8f16599613edddb1ff924eeb4b53ab7e7197f85cbc321cdca32f"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-win32.whl", hash = "sha256:ba72d37e2a924717990f4d7482e8ac88e2ef43fb95491eb6e0d124d77d2a150d"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:3ffaadcaeafe9d30a7e4e1e97ad727e4f5610b9fa2f7551998471e3736738679"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73fd30d4ce0ea48010564ccee1a26bfe39323fde05cb34b5863455629db61dc7"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02177603aaca36e1fd21b091cb742bb3b305a569e2402f1ca38af471777fb019"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b43775532a5904bc938f9c15b77c613cb6ad6fb30990f3b0afaea82797a402d8"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5bf37a08493232fbb0f8229f1824b366c2fc1d02d64e7e918af40acd15f3e337"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:330e3f10cd01da535c70d09c4283ba2df5fb78e915bea0a28becad6e2ac010be"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e1abbeef02962596548382e393f56e4c94acd286bd0c5afba756cffc33670e8a"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3148362937217b7072cf80a2dcc007f09bb5ecb96dae4617316638194113d5be"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336b40348269f9b91268378de5ff44dc6fbaa2268194f85177b53463d313842a"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b09a16a1950b9ef495a0f8b9d0a87599a9d1f179e2d4ac014b2ec831f87e7"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c8e521a0ce7cf690ca84b8cc2272ddaf9d8a50294fd086da67e517439614c755"},
|
||||
{file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"},
|
||||
]
|
||||
cachecontrol = [
|
||||
{file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"},
|
||||
{file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"},
|
||||
@@ -5032,6 +5208,25 @@ cloudpickle = [
|
||||
{file = "cloudpickle-2.2.0-py3-none-any.whl", hash = "sha256:7428798d5926d8fcbfd092d18d01a2a03daf8237d8fcdc8095d256b8490796f0"},
|
||||
{file = "cloudpickle-2.2.0.tar.gz", hash = "sha256:3f4219469c55453cfe4737e564b67c2a149109dabf7f242478948b895f61106f"},
|
||||
]
|
||||
cmake = [
|
||||
{file = "cmake-3.26.0-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl", hash = "sha256:4881727389325af84e39f1ec646b7249d8910b4ed637205bee6d589cb2b2ebd2"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2010_i686.manylinux_2_12_i686.whl", hash = "sha256:babd1e38c85d38a4bf4164c3126ec8cf4cd8d374072e2a4a181e52e953007f8c"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:1851be29d79bb39505954165e934d31994268d49f566ead6fff840a5092e444d"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:483aaaeb9535deaa2657c928af5d9f0da9329f89bc249f494923495745a03677"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2f78c6194f224d462333e08d3acd571c553b58d04935971b87efbe76f241353c"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:cf129c8b71f1344975f179f30287baa8804c4c61ff1b13003244b4157b676e13"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:fabb82c69223eda27e673c5c6bb02985d60cf0baa631a2e4932eed87e8229928"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502cbed2335557920b88687c6f3ff4ce433bd416204c928ad489e399e76149f5"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:b81c7775b125786c1696232078e9ceb0c9c66d26fb0a2259f40e33983170f924"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-musllinux_1_1_i686.whl", hash = "sha256:f4cc1dde7613cc813d15fd840a33e18cd07a443aa67205d74b9b05f55f08a459"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:ac6ca9d9ff58900138bbbebc55857647fb99f1c40b84d8a232f23b0d27d7f48a"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-musllinux_1_1_s390x.whl", hash = "sha256:85e0bad5aeb3a82919ed7d78b76a0462eafe2f918076a1823a09c6f37910f3e0"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:5523b9701be367572155e77294bf8aa3ac9aa0d73c50dcd6c57903d12bcb308e"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-win32.whl", hash = "sha256:96f0e887260255eeb83bcf3465d51bc6c94078251c9312fa142dce6d3e80acac"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-win_amd64.whl", hash = "sha256:a0719a6f79cdc4d7b16caf757b8ae13eae1c6ce5a08d594cc09774afe129515d"},
|
||||
{file = "cmake-3.26.0-py2.py3-none-win_arm64.whl", hash = "sha256:11159c9b64c6473d84361ab44ef2c85e1bd2db7a2b1b798ce8bf5988f32adf43"},
|
||||
{file = "cmake-3.26.0.tar.gz", hash = "sha256:c18185c9cc147d0fa1e9228962aa37901b37866bd5d617e9efa23dfe706f7321"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
|
||||
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
|
||||
@@ -5201,15 +5396,17 @@ cryptography = [
|
||||
{file = "cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"},
|
||||
{file = "cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"},
|
||||
]
|
||||
cupy-cuda113 = [
|
||||
{file = "cupy_cuda113-10.6.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:27e5efe2c3afa80ff48654cb27f9e0eddb36f8b26ef0d32d3ba0a233e1359b51"},
|
||||
{file = "cupy_cuda113-10.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:8b96076d1ddd33fdb2c908ed0f8109caf69d37d36f839a8a8cdae1312508336f"},
|
||||
{file = "cupy_cuda113-10.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22363c2863727cae5154aa4bab9e8a648d7fe66c9e2195d81dd4e8693c2e61ce"},
|
||||
{file = "cupy_cuda113-10.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8cc69b9d5735372477a7af3822c8f8e996ffe6de05cfc917500af9dc0117ca3e"},
|
||||
{file = "cupy_cuda113-10.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:10dc6899577e445426d81f0960ba9059d9aaa750426997c61fad882d6345264c"},
|
||||
{file = "cupy_cuda113-10.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:c6893ac9040a11610e63973063dfd715dbda8bd07ef99951bab7a09c7f335e1e"},
|
||||
{file = "cupy_cuda113-10.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4bf4bc06d991c06b95f6fe558d117cafd93bd4eeaf80606f18dd31d20d2eff25"},
|
||||
{file = "cupy_cuda113-10.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:3745fc42dca86ba8a1109ddc7964aed8e1efc0ce8085cb2f140dcd6429f26354"},
|
||||
cupy-cuda11x = [
|
||||
{file = "cupy_cuda11x-11.6.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:1b9914f57868a1559e9bfabfbae8c724585914e8e1f277acb9cdb6aa0756eaa4"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:ac8dd082ddb00996bc4d37cc5765907048f467aadb61bcbff25f3c2a88c50583"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:bf7496340dfbc2eaa3e0ebfd03c4ab8b1fc36d7d14f68718c33eeb395aaa6eed"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:e3bbd55c26d60069d7e5af2200fb47e7c42ca6437acac297637a2d3c00f6fe46"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0d7ebcfd7234946719ad28890593d9fc78fad5753ef4b073e0d7bdb7da2f5640"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3bc3f81fbc5a86c7155c6036809f2ada4023fc0870dce158d3d9f6d0b575727f"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:1d6810568e683cb153972b3019ddb5efc369036511122117d9eda09cf84d1042"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:31c1ec72ffe9ad6fda9fb0a2aff1fcca38da66a8e521e333bae0d67ebc80ead0"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6a4822daadfce0464cb619099eb82c7ba30ae7755d6869ba5eba1c675a9eed67"},
|
||||
{file = "cupy_cuda11x-11.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:3d0f44d747b38ce2b213d64270265f953b68cf29860ec5fa65848b9faaea3fc1"},
|
||||
]
|
||||
cycler = [
|
||||
{file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
|
||||
@@ -5640,6 +5837,86 @@ gevent = [
|
||||
{file = "gevent-22.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:0569e133bb620de1001ac807ad9a8abaadedd25349c6d695f80c9048a3f59d42"},
|
||||
{file = "gevent-22.10.1.tar.gz", hash = "sha256:df3042349c9a4460eeaec8d0e56d737cb183eed055e75a6af9dbda94aaddaf4d"},
|
||||
]
|
||||
geventhttpclient = [
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd76acdc7e7ee5c54c7b279f806b28957a6b092f79c40db34adcfd972749343c"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:320a2c756d8a4f296de370476a1515485c186d9e22c3fc29e04f8f743a7d47bb"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:36d3345c6585b09738195a7c45d279a87ccbab0350f1cce3679d3f0dce8577a1"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:407d54499556c2741b93691b86da93232590b013f4a0b773327d766fe3e5c0a9"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcf325131b0e4600b793643108cd85dddd66bbf532fd2eb498be5727ef532a1e"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5841dd02e6f792a4ef15dbd04fefe620c831ba0b78105808160bb779a31af4"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2ba69422d4e8670dd99803b1313ba574a4d41f52e92b512af51068c9c577bdc1"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e3af579c6b46b9caa515a8baf6a2cadeafcd1d41ad22ca5712851f074a40b47"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ff7fc19f9a4fdd54a2b1c106a705ea2c679fa049685ed763051d417725bdab1"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-win32.whl", hash = "sha256:eec7c52e8eb817674a193e0124486b507215d9e86d34f2638bf9a9292d16f815"},
|
||||
{file = "geventhttpclient-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:0e9f7283c01d970e643d89da81127869a8d94bb7a0081020dcad5b590bc007c4"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5ceb492d43a659b895794999dc40d0e7c23b1d41dd34040bbacd0dc264b57d5b"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:95959c201d3151fa8f57e0f1ce184476d1173996bdde41dc7d600006023dc5be"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:31c7febba298ecf44838561074a3fb7a01523adca286469b5a82dcc90e8d6a07"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:996c5f453d810b3c592160193d6832a065cca0112e92adc74e62df0e4c564df6"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f817e226c02b5a71d86de3772d6accdf250288d1e6825e426c713759830162d"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c55b7ac0ba0e1e1afbf297b7608f0b3a0bbc34fb4b0c19b7869f32a77ddc6209"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6775bc81e25c48fa58b034444aecfa508b0c3d1bc1e4ae546cc17661be1f51aa"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a0156882c73537bbbbc7c693ae44c9808119963174078692613ffa4feea21fcf"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3ebb582a291c4c5daaac2ea115b413f4be86874baa60def44d333301cee17bd7"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-win32.whl", hash = "sha256:716f1f72f50b841daf9c9511a01fc31a030866510a11863f27741e26e4f556a7"},
|
||||
{file = "geventhttpclient-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:777fcdb72077dfbf70516ecb9e9022246dd337b83a4c1e96f17f3ab9e15f4547"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:379d90d8b1fcdda94e74d693806e0b0116c0610504e7f62d5576bac738dc66a5"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00b7b2b836294c091c53789a469c5671202d79420b5191931df4e3a767d607fa"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d075355862d7726eb3436f0136fce7650c884f2d04eaae7a39fed3aad9798bc"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa7b1a27f950d209fe223a97906fe41312dc12c92372424639b8a9b96f1adf91"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fe4e06313aad353b103950780b050d3958000464cc732d621ff8ea3cacbd2bc4"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:84d7be660b6bc53dd53e3f46b3bc5d275972a8116bd183a77139bb4d9d6d9fb1"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:81f839d6becd664d0972b488422f5dc821f8ad2f2196d53aa5e4d799a3a35a66"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:e707f62271a093e6e3af6f1bbd8cc398b414b8c508fe6b15505dd8e76c4409ac"},
|
||||
{file = "geventhttpclient-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:28d7655d1d50bc75ece683a0ae8faf978821d4aeae358d77b59371548db07f1e"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58877b4440a580063571a23fbc616aed7c735c6bf9ef525c5129783df8b6966"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57c993c4b2bea551c4a71b75ae1e172e9f3e4352f704ff1b619a0f16aa762f76"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f67e789e31c7b1ce440cd1465dcdefeca29ba6108735eac0b1a593d3a55b7f"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f3326e115ec7e7ce95a5d0d47698e8f3584944c4c434a7404937d56b17136b8"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ef328ee3e7dca5055b833fdf3c181647a335abf0249947b27f5df2d95390198c"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:27049ea40e3b559eee380310272aaa9b7c19e73c1d9e51e2ec137362be2caa70"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b88a10538341e33fed1682c0dd4579c655d49db5863e7456583085a1cd6bd9d4"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:d52aba2c38420b3fc518188449f1c2a46b1a99adf1c0266c68e72ee0422cd0fa"},
|
||||
{file = "geventhttpclient-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3648626ca58ea4b340e695d78e5d533e6b8be78d375edbd42ff188bc3447e095"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fcf96e212b55b93490f3a5fcdfe7a2ef4995a0d13b7d9df398b11e319b7a86b1"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e9f2ff09706e3a64a99886d5f2595f3bf364821bc609f2865dbc3e499e21a36"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:721c3075897bfc81e918066f16ae3d1a88c7bb14eeeb831a4f89ea636474643e"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91615fed7931acd49cfe5fc30984acd5411dc1f2643b1544c879d1a537233c6d"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7adaa29e5699dea54e0224d1d2d9d8869668d8ad79f5b89433ff9c46f9424a6c"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9be5000ba57336a90b438782117c1e43205f51f49aa9b1499a82e210e8431b11"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:12d271cc53486efb3716e99855dc5cb84f2cd3fc9f3243721747bb39ec0fff8a"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b9c0c6b75b3905000d2490dc64b4c98a8bac155efbc0ff8917ac082ae0bad261"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e956a457d8831dc81d6f046ab09ebeec680f9a1e9c07e25a1906e77b287918ee"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-win32.whl", hash = "sha256:bc46d5479673dfb293ea428c057d2e23e48ebef5c5d44587cdbaada7f87553e4"},
|
||||
{file = "geventhttpclient-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:f44153e4b3ef9b901edcd14be54145a0058bf5fa371b3e583153865fac866245"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ebf98db9435824cf0b80b5247be6c88b20bfafd6249f7ebaabb85297da37e380"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c8b7298eb1ebd015257bf4503e34f5fbbe64bd83324140f76b511046aba5a0d5"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:60b81a6d4e65db7c1a5350c9fb72ebf800b478849a7e8020d1ab93af237a3747"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad6c2fcbc3733785bd3b8c2bb43d1f605f9085b0a8b70ce354d198f37143f884"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94edb022fa50d576cf63f6dd0c437c1acd24a719872a5935991aaf08f8e88cb2"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ca459cedb3827d960362e05ea3a4ae600a6d0d93de77eac2ac0f79828e5e18c"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7551b6db860b56411de1f96618e91b54f65e1a7be8d10255bd1adfb738bb6ee5"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bcb7e061c243308d9a44b02de5298001e917f1636a9f270c10da86601fcc8dfa"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:96922d170ef8933f4c20036e8d70d4fbe861f54c543e32e7459ebdbaafa65a2e"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ebb3c993903d40fd4bb1f3e55b84c62c8fc1d14433ae6d4d477dd9a325354c94"},
|
||||
{file = "geventhttpclient-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:dbccf1ba155dea3ea99ba0e67a835c05b4303f05298e85f5bb2a46700ccdf092"},
|
||||
{file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8770b8ab9e8c31d2aaf8a6fbc63fbb7239c58db10bb49cee191ca5c141c61542"},
|
||||
{file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daff1e977fccf98f27266d3891afdc101f1d705a48331754909e960bcae83f8a"},
|
||||
{file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2435e0f2a60e00d977822ec4c12e7851deb7aa49a23d32d648e72c641aae3b05"},
|
||||
{file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09acd03d0a8c1bb7d5a1cb6fcb77aaa19a907c1b4915ab58da5d283675edb0a5"},
|
||||
{file = "geventhttpclient-2.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5d0813d97050446dab2fb243312e6c446e4ef5e9591befd597ef8f2887f8e2a8"},
|
||||
{file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:852da9bb0fc792cdca5ffc9327490094783e42415494b3569e5d532615027439"},
|
||||
{file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79304a63a9d0512f2757c5862487b332b18a9c85feebecf6ebc3526c6dd1ba2"},
|
||||
{file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c1c783fce45f16db448d7e34864f1e9c22fe60a7780d2c1c14edbb1fb7262e"},
|
||||
{file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77c407c2b4bea817c6f752502db4ab0e9f9465b4fb85b459d1332b5f93a3096c"},
|
||||
{file = "geventhttpclient-2.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f0d70a83ef4ab93102c6601477c13e9cdbc87205e5237fbf5797e30dc9d3ee8"},
|
||||
{file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b03f298ec19b8a4717cce8112fe30322c9e5bfada84dde61a1a44d1eeffc1d3c"},
|
||||
{file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2dc94b9a23eb6744a8c729aec2b1cdc4e39acf1d8f16ea85a62810aa6b2cae5"},
|
||||
{file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:805554594bb29231fd990cc2cbbe493d223d76a6085fec891dd76bb4e0928933"},
|
||||
{file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb23527d98f626ca7a4e8961ed9bdc6aed3388de306614c69a133b34262460f4"},
|
||||
{file = "geventhttpclient-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a594ab319872a38fb7f16be4cfb107d3c63c43a081f2abe241834e9877f27401"},
|
||||
{file = "geventhttpclient-2.0.2.tar.gz", hash = "sha256:8135a85200b170def7293d01dd1557931fcd1bec1ac78c52ad7cedd22368b9ba"},
|
||||
]
|
||||
greenlet = [
|
||||
{file = "greenlet-1.1.3.post0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:949c9061b8c6d3e6e439466a9be1e787208dec6246f4ec5fffe9677b4c19fcc3"},
|
||||
{file = "greenlet-1.1.3.post0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:d7815e1519a8361c5ea2a7a5864945906f8e386fa1bc26797b4d443ab11a4589"},
|
||||
@@ -6037,6 +6314,9 @@ libusb1 = [
|
||||
{file = "libusb1-3.0.0-py3-none-win_amd64.whl", hash = "sha256:6f6bb010632ada35c661d17a65e135077beef0fbb2434d5ffdb3a4a911fd9490"},
|
||||
{file = "libusb1-3.0.0.tar.gz", hash = "sha256:5792a9defee40f15d330a40d9b1800545c32e47ba7fc66b6f28f133c9fcc8538"},
|
||||
]
|
||||
lit = [
|
||||
{file = "lit-15.0.7.tar.gz", hash = "sha256:ed08ac55afe714a193653df293ae8a6ee6c45d6fb11eeca72ce347d99b88ecc8"},
|
||||
]
|
||||
lockfile = [
|
||||
{file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"},
|
||||
{file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"},
|
||||
@@ -7286,6 +7566,64 @@ python-engineio = [
|
||||
python-logstash = [
|
||||
{file = "python-logstash-0.4.8.tar.gz", hash = "sha256:d04e1ce11ecc107e4a4f3b807fc57d96811e964a554081b3bbb44732f74ef5f9"},
|
||||
]
|
||||
python-rapidjson = [
|
||||
{file = "python-rapidjson-1.10.tar.gz", hash = "sha256:acfecbf5edb91ec72a20a125de7f56b8c2f6161eff4c65382c8ee6a2484d3540"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1db7b0af882999f5685eb7046a0f3b3aca5d55a3e84b3089747d29a4ec6fdade"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87c8c8b615513f9dc414af1554140589036d14840f5e1f1845965e1c0a080e1"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a0a2f5c4abe529ca2764343416e35710a263832533b7bdc76c3285efb5b5ecc8"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40467c3a6d8f070cc4d196fe46a79ed59d1a13a4d3fdc6a0325a21816600e5a7"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df4e7237a3e77666ccb9b437013294e6aa3968528f7c61f60f6f38eea0f8f79"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:99a5215f24ff1fa6cc67ee275a6852aa56d934d3b8cd7a40197feb632b54fd76"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3dbea0ee9fa1cd6ecc13a949f6bb94013639d39cdb56f58df4ab61130d35e57c"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:6d1d0c5da3bd5f701b1aed550e1e7bd59b16ae642877cddf18815006cf998f9a"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:072f76c1f1483bcc4056d7d3a8b0319bf841a73e955f188302094b62b2163bf9"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-win32.whl", hash = "sha256:c95d466307a2140a7687a575103980c6e81c9f62d19556cafad3d6b2932b7eb1"},
|
||||
{file = "python_rapidjson-1.10-cp310-cp310-win_amd64.whl", hash = "sha256:454ffda58cc6fed64d983b1b8ae4b39a563b4fd671dae9132e06450025898539"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fff343076fbeee0cd7e4e3fb9472f2d567a127ec7b8b5b7ecba6bf7960a3ce07"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:686482c67727edad4b6d0c753bc159f35134a5a623e9651c4b7c008ef2996252"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ef7d55688b7123d62690b193537cc048fa9f35cfa43d249fedc0d9fd398890a"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f27c0601792533ab6e98452961d61566480dc155da19d2a358a5fd9a85d9321"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95176e35e3bacb8a1a27f563e815b5b57c717992c871b1c25fd76a835fbba32c"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47a0ec20886b8be86af307c10d699a447e22979ed7dd1f2b7ed5cb7496b3d920"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f7968c0cb09d9a76aa2483556ba46ab42634baf216cb2f2c7cd6bf77119a33c1"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5faab270a4dd49216ceaca7169682680b2f5df8311c1ed259e4612d9d0cf61b7"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:81b797934dc037810f5f98af138b55a3b6f18dd569cc5e8f81fe79956a4717ca"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-win32.whl", hash = "sha256:6c1d62cc58a61629fc5e216fb7b3a1b02787c98fded874a7b474b1e6325e377e"},
|
||||
{file = "python_rapidjson-1.10-cp311-cp311-win_amd64.whl", hash = "sha256:29d31fc4254f1a4dca420e58bd1331e990fc2959d09ff2daa7934d52732a8491"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:718f4e217b511cfbf9166f55ccf4bf4e4538495bee403e390cf89791c0debc26"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541bbb96353cf3fe2bdb29e727087226532be4e4573daad6f042cfdea533a564"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50f0402a6899c6a177d4a37152deefcd59c61e44bef56b71e8d006a186c86286"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c035e17744d6d6fba073b550b0040a74e55f2ad33fd798df206ff6879b41ad10"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da970bde42309a74a5556e696673ea11c4545b8bee5081b84265ded460b2e9ef"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7437a649821008aa456f2fbec737880d7f9bdda7ec94cc1743a43ccf32b5d26"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:362d969bbd277f78bf0b1ffaa810857ea40351146b827f896f8d49e9c25fc99c"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:409256e7748c4ab7f17b3793c7a78ca01914c487644fc42140d116ed4dec8c4f"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a34a7e2853456fe50ba2ee22e38e7841e55eee10021d4496cce62285f148e8e7"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-win32.whl", hash = "sha256:bc4a97940e5afa60a598483d0eb863b26e4810aaf030d92a4301f5fc183e1b6d"},
|
||||
{file = "python_rapidjson-1.10-cp37-cp37m-win_amd64.whl", hash = "sha256:89586b67f9c69b66885774acebf3d018e7b8f93cea2b3cffa306ec9d37877594"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2e38082b1a8ce3e2bd55821852c0cd643cdabe6497fd9c054f6b47a099afbea0"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0955ef22fabb36b26fcad702ae54c1bce2bc2a74b1883c42d251d72011d0d426"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a9db03c68ab0158bcdf80299b2c980186d148aa3e05d5650fea5148a425a29a"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fde8ab0f06debaa06d93085f19dc3ec3db53f22883f1625dd32b96a87e7009de"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23539c9f7d85d64a00d3cb44c7d9ab3be2184d4da42a5f3263dcfd1d0203ee43"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8bfd484285f3477acef0bb45abd2b80b6252e35a5a53395ce48f0327cbe43c23"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8b0ed643ebaa8ddf3f40422752efe83abda29aa30a9e6866ccd9dd591b5057d0"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:5aeca661a0f229f1312fb3ad3e1a5c6736d49942d80d4931810158559eb8f119"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8a68ed066e8f0878b7112f943cf35ba9e5217395bcdd8cb478cde01871e2701c"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-win32.whl", hash = "sha256:d286be6f63446776c4958bb37824c683194b4878fc9cd5b7255134fb5a6ba536"},
|
||||
{file = "python_rapidjson-1.10-cp38-cp38-win_amd64.whl", hash = "sha256:aece5270c6e6d5c3d54586c9a5fb9677d70d7019744a59560c5c369c7b9bba25"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc09c5ad0fe71f262cdcc5655409f132f1560a8af80e76e7757945ce401fdbab"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f6447bd7a8ff5135ab7e372b48a174d3c560d5b322e32bd465e8458e6e4593"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22ede69213885391b46cc14596bfd4cd1a5c6f34a2db6600fb08b03982dbc7b7"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a9425129623718a04b885a12190faa23e7997c4e8632054e18df7ea473f746d"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e10f32e1a8d155448842934cbe71eb620b4b4a0cb3627ba4c4856e27556534"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d23caab17b87ed5b82e28cdc19172ba1ca65c982e3fff387961d3f33710031f"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f07d4fcdcfd64bdad0143b9705c5d5089677ebddf60ac6c1f8074a34b1c70cf9"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:87b991c7ae435489c56a46cef228d2b65a3df689ee4fe24fab69c791c841f633"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3706a5c4f21073c04be133c36565efc6e3f5646a03c8d19af78c19d7c70eb708"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-win32.whl", hash = "sha256:47f9078ea6884f700166a8728d863609fec62232e66a33b8fb4a7706ce7c731c"},
|
||||
{file = "python_rapidjson-1.10-cp39-cp39-win_amd64.whl", hash = "sha256:9e4921ab7002ae9faad7f439a7c50aa195039f177e9e51a76c34c97966c79a79"},
|
||||
]
|
||||
python-socketio = [
|
||||
{file = "python-socketio-5.7.2.tar.gz", hash = "sha256:92395062d9db3c13d30e7cdedaa0e1330bba78505645db695415f9a3c628d097"},
|
||||
{file = "python_socketio-5.7.2-py3-none-any.whl", hash = "sha256:d9a9f047e6fdd306c852fbac36516f4b495c2096f8ad9ceb8803b8e5ff5622e3"},
|
||||
@@ -8040,11 +8378,28 @@ traitlets = [
|
||||
{file = "traitlets-5.5.0.tar.gz", hash = "sha256:b122f9ff2f2f6c1709dab289a05555be011c87828e911c0cf4074b85cb780a79"},
|
||||
]
|
||||
triton = [
|
||||
{file = "triton-1.1.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8441e6f44517aef8f6345f621c003926cbe970892802411a949ccda516cbd5ba"},
|
||||
{file = "triton-1.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840776bc1f4757fb2d6af974694c5e5313220ceec238ee6118b9728bc2aa9ade"},
|
||||
{file = "triton-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97d42cdaa7d56de463d762c18cc876bfd0828a2b6a706263393fe7e10d1c83ca"},
|
||||
{file = "triton-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc19c0e902bbf7d29de4d444455608065a2c56e3524f4bc94e724511ca518f3"},
|
||||
{file = "triton-1.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02f798cd2dd922228082ce1a4e9d81badb9a6217a9aac6d783e95bf7055974d"},
|
||||
{file = "triton-2.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38806ee9663f4b0f7cd64790e96c579374089e58f49aac4a6608121aa55e2505"},
|
||||
{file = "triton-2.0.0-1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:226941c7b8595219ddef59a1fdb821e8c744289a132415ddd584facedeb475b1"},
|
||||
{file = "triton-2.0.0-1-cp36-cp36m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4c9fc8c89874bc48eb7e7b2107a9b8d2c0bf139778637be5bfccb09191685cfd"},
|
||||
{file = "triton-2.0.0-1-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d2684b6a60b9f174f447f36f933e9a45f31db96cb723723ecd2dcfd1c57b778b"},
|
||||
{file = "triton-2.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9d4978298b74fcf59a75fe71e535c092b023088933b2f1df933ec32615e4beef"},
|
||||
{file = "triton-2.0.0-1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:74f118c12b437fb2ca25e1a04759173b517582fcf4c7be11913316c764213656"},
|
||||
{file = "triton-2.0.0-1-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9618815a8da1d9157514f08f855d9e9ff92e329cd81c0305003eb9ec25cc5add"},
|
||||
{file = "triton-2.0.0-1-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aca3303629cd3136375b82cb9921727f804e47ebee27b2677fef23005c3851a"},
|
||||
{file = "triton-2.0.0-1-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e3e13aa8b527c9b642e3a9defcc0fbd8ffbe1c80d8ac8c15a01692478dc64d8a"},
|
||||
{file = "triton-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f05a7e64e4ca0565535e3d5d3405d7e49f9d308505bb7773d21fb26a4c008c2"},
|
||||
{file = "triton-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4b99ca3c6844066e516658541d876c28a5f6e3a852286bbc97ad57134827fd"},
|
||||
{file = "triton-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47b4d70dc92fb40af553b4460492c31dc7d3a114a979ffb7a5cdedb7eb546c08"},
|
||||
{file = "triton-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fedce6a381901b1547e0e7e1f2546e4f65dca6d91e2d8a7305a2d1f5551895be"},
|
||||
{file = "triton-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75834f27926eab6c7f00ce73aaf1ab5bfb9bec6eb57ab7c0bfc0a23fac803b4c"},
|
||||
{file = "triton-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0117722f8c2b579cd429e0bee80f7731ae05f63fe8e9414acd9a679885fcbf42"},
|
||||
{file = "triton-2.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd9be5d0c2e45d2b7e6ddc6da20112b6862d69741576f9c3dbaf941d745ecae"},
|
||||
{file = "triton-2.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a0d2c3fc2eab4ba71384f2e785fbfd47aa41ae05fa58bf12cb31dcbd0aeceb"},
|
||||
{file = "triton-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c47b72c72693198163ece9d90a721299e4fb3b8e24fd13141e384ad952724f"},
|
||||
]
|
||||
tritonclient = [
|
||||
{file = "tritonclient-2.28.0-py3-none-any.whl", hash = "sha256:1f58bbe09a88c35f7979de8ab6579a5337372951f723c0aba31e8bee3e8d79da"},
|
||||
{file = "tritonclient-2.28.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:47d93197a0876a743012db4c03f1100f7b225b9aaf8d5f8025bf4a5d9e61bfd2"},
|
||||
]
|
||||
types-atomicwrites = [
|
||||
{file = "types-atomicwrites-1.4.5.1.tar.gz", hash = "sha256:9e9f0923ebf93524b28bcece5a23ac8c3820f39b060df29f671936d2e4bc04bc"},
|
||||
@@ -8066,6 +8421,10 @@ types-requests = [
|
||||
{file = "types-requests-2.28.11.2.tar.gz", hash = "sha256:fdcd7bd148139fb8eef72cf4a41ac7273872cad9e6ada14b11ff5dfdeee60ed3"},
|
||||
{file = "types_requests-2.28.11.2-py3-none-any.whl", hash = "sha256:14941f8023a80b16441b3b46caffcbfce5265fd14555844d6029697824b5a2ef"},
|
||||
]
|
||||
types-tabulate = [
|
||||
{file = "types-tabulate-0.8.11.tar.gz", hash = "sha256:17a5fa3b5ca453815778fc9865e8ecd0118b07b2b9faff3e2b06fe448174dd5e"},
|
||||
{file = "types_tabulate-0.8.11-py3-none-any.whl", hash = "sha256:af811268241e8fb87b63c052c87d1e329898a93191309d5d42111372232b2e0e"},
|
||||
]
|
||||
types-urllib3 = [
|
||||
{file = "types-urllib3-1.26.25.1.tar.gz", hash = "sha256:a948584944b2412c9a74b9cf64f6c48caf8652cb88b38361316f6d15d8a184cd"},
|
||||
{file = "types_urllib3-1.26.25.1-py3-none-any.whl", hash = "sha256:f6422596cc9ee5fdf68f9d547f541096a20c2dcfd587e37c804c9ea720bf5cb2"},
|
||||
|
||||
+8
-6
@@ -83,7 +83,7 @@ mypy = "^0.961"
|
||||
myst-parser = "^0.18.0"
|
||||
natsort = "^8.1.0"
|
||||
numpy = "^1.23.0"
|
||||
opencv-python-headless = { url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu113/opencv_python_headless-4.5.5.64-cp38-cp38-manylinux_2_31_x86_64.whl", platform = "linux" }
|
||||
opencv-python-headless = { url = "https://github.com/commaai/opencv-python-builder/releases/download/4.5.5.64%2Bcu118/opencv_python_headless-4.5.5.64-cp38-cp38-manylinux_2_31_x86_64.whl", platform = "linux" }
|
||||
pandas = "^1.4.3"
|
||||
parameterized = "^0.8.1"
|
||||
paramiko = "^2.11.0"
|
||||
@@ -107,6 +107,7 @@ types-certifi = "^2021.10.8"
|
||||
types-pycurl = "^7.45.1"
|
||||
types-PyYAML = "^6.0"
|
||||
types-requests = "^2.28.11"
|
||||
types-tabulate = "^0.8.10"
|
||||
|
||||
|
||||
[tool.poetry.group.xx]
|
||||
@@ -116,7 +117,7 @@ optional = true
|
||||
aenum = "^3.1.11"
|
||||
aiohttp = "^3.8.1"
|
||||
albumentations = "^1.2.1"
|
||||
apex = { url = "https://github.com/commaai/apex/releases/download/pytorch1.10.0%2Bcu11.1/apex-0.1-cp38-cp38-linux_x86_64.whl" }
|
||||
apex = { url = "https://github.com/commaai/apex/releases/download/pytorch2.0.0%2Bcu11.8/apex-0.1-cp38-cp38-linux_x86_64.whl" }
|
||||
azure-cli-core = "^2.38.0"
|
||||
azure-common = "^1.1.28"
|
||||
azure-core = "^1.24.2"
|
||||
@@ -126,7 +127,7 @@ azure-storage-nspkg = "~3.1"
|
||||
blosc = "==1.9.2"
|
||||
cloudpickle = "^2.1.0"
|
||||
configargparse = "^1.5.3"
|
||||
cupy-cuda113 = "^10.6.0"
|
||||
cupy-cuda11x = "^11.6.0"
|
||||
datadog = "^0.44.0"
|
||||
dotmap = "^1.3.30"
|
||||
einops = "^0.5.0"
|
||||
@@ -165,14 +166,15 @@ scikit-learn = "^1.1.1"
|
||||
segmentation-models-pytorch = "==0.2.1"
|
||||
simplejson = "^3.17.6"
|
||||
SQLAlchemy = "^1.4.39"
|
||||
torch = { url = "https://download.pytorch.org/whl/cu113/torch-1.11.0%2Bcu113-cp38-cp38-linux_x86_64.whl" }
|
||||
torch = { url = "https://download.pytorch.org/whl/cu118/torch-2.0.0%2Bcu118-cp38-cp38-linux_x86_64.whl" }
|
||||
torchsummary = "^1.5.1"
|
||||
torchvision = { url = "https://download.pytorch.org/whl/cu113/torchvision-0.12.0%2Bcu113-cp38-cp38-linux_x86_64.whl" }
|
||||
triton = "^1.1.1"
|
||||
torchvision = { url = "https://download.pytorch.org/whl/cu118/torchvision-0.15.1%2Bcu118-cp38-cp38-linux_x86_64.whl" }
|
||||
triton = "^2.0.0"
|
||||
Werkzeug = "^2.1.2"
|
||||
zerorpc = { git = "https://github.com/commaai/zerorpc-python.git", branch = "master" }
|
||||
omegaconf = "^2.3.0"
|
||||
osmnx = "==1.2.2"
|
||||
tritonclient = {version = "2.28.0", extras = ["http"]}
|
||||
|
||||
|
||||
[build-system]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
while read hash submodule ref; do
|
||||
git -C $submodule fetch --depth 300 origin master
|
||||
git -C $submodule fetch --depth 1000 origin master
|
||||
git -C $submodule branch -r --contains $hash | grep "origin/master"
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo "$submodule ok"
|
||||
|
||||
+41
-38
@@ -219,14 +219,15 @@ system/hardware/pc/__init__.py
|
||||
system/hardware/pc/hardware.h
|
||||
system/hardware/pc/hardware.py
|
||||
|
||||
selfdrive/locationd/__init__.py
|
||||
selfdrive/locationd/.gitignore
|
||||
selfdrive/locationd/SConscript
|
||||
selfdrive/locationd/ubloxd.cc
|
||||
selfdrive/locationd/ublox_msg.cc
|
||||
selfdrive/locationd/ublox_msg.h
|
||||
selfdrive/locationd/generated/*
|
||||
system/ubloxd/.gitignore
|
||||
system/ubloxd/SConscript
|
||||
system/ubloxd/generated/*
|
||||
system/ubloxd/*.h
|
||||
system/ubloxd/*.cc
|
||||
|
||||
selfdrive/locationd/__init__.py
|
||||
selfdrive/locationd/SConscript
|
||||
selfdrive/locationd/.gitignore
|
||||
selfdrive/locationd/laikad.py
|
||||
selfdrive/locationd/locationd.h
|
||||
selfdrive/locationd/locationd.cc
|
||||
@@ -253,35 +254,36 @@ system/proclogd/main.cc
|
||||
system/proclogd/proclog.cc
|
||||
system/proclogd/proclog.h
|
||||
|
||||
selfdrive/loggerd/.gitignore
|
||||
selfdrive/loggerd/SConscript
|
||||
selfdrive/loggerd/encoder/encoder.cc
|
||||
selfdrive/loggerd/encoder/encoder.h
|
||||
selfdrive/loggerd/encoder/v4l_encoder.cc
|
||||
selfdrive/loggerd/encoder/v4l_encoder.h
|
||||
selfdrive/loggerd/video_writer.cc
|
||||
selfdrive/loggerd/video_writer.h
|
||||
selfdrive/loggerd/logger.cc
|
||||
selfdrive/loggerd/logger.h
|
||||
selfdrive/loggerd/loggerd.cc
|
||||
selfdrive/loggerd/loggerd.h
|
||||
selfdrive/loggerd/encoderd.cc
|
||||
selfdrive/loggerd/bootlog.cc
|
||||
selfdrive/loggerd/encoder/ffmpeg_encoder.cc
|
||||
selfdrive/loggerd/encoder/ffmpeg_encoder.h
|
||||
system/loggerd/.gitignore
|
||||
system/loggerd/SConscript
|
||||
system/loggerd/encoder/encoder.cc
|
||||
system/loggerd/encoder/encoder.h
|
||||
system/loggerd/encoder/v4l_encoder.cc
|
||||
system/loggerd/encoder/v4l_encoder.h
|
||||
system/loggerd/video_writer.cc
|
||||
system/loggerd/video_writer.h
|
||||
system/loggerd/logger.cc
|
||||
system/loggerd/logger.h
|
||||
system/loggerd/loggerd.cc
|
||||
system/loggerd/loggerd.h
|
||||
system/loggerd/encoderd.cc
|
||||
system/loggerd/bootlog.cc
|
||||
system/loggerd/encoder/ffmpeg_encoder.cc
|
||||
system/loggerd/encoder/ffmpeg_encoder.h
|
||||
|
||||
selfdrive/loggerd/__init__.py
|
||||
selfdrive/loggerd/config.py
|
||||
selfdrive/loggerd/uploader.py
|
||||
selfdrive/loggerd/deleter.py
|
||||
selfdrive/loggerd/xattr_cache.py
|
||||
system/loggerd/__init__.py
|
||||
system/loggerd/config.py
|
||||
system/loggerd/uploader.py
|
||||
system/loggerd/deleter.py
|
||||
system/loggerd/xattr_cache.py
|
||||
|
||||
selfdrive/sensord/SConscript
|
||||
selfdrive/sensord/sensors_qcom2.cc
|
||||
selfdrive/sensord/sensors/*.cc
|
||||
selfdrive/sensord/sensors/*.h
|
||||
selfdrive/sensord/sensord
|
||||
selfdrive/sensord/pigeond.py
|
||||
system/sensord/.gitignore
|
||||
system/sensord/SConscript
|
||||
system/sensord/sensors_qcom2.cc
|
||||
system/sensord/sensors/*.cc
|
||||
system/sensord/sensors/*.h
|
||||
system/sensord/sensord
|
||||
system/sensord/pigeond.py
|
||||
|
||||
selfdrive/thermald/thermald.py
|
||||
selfdrive/thermald/power_monitoring.py
|
||||
@@ -577,13 +579,14 @@ opendbc/tesla_can.dbc
|
||||
opendbc/tesla_radar.dbc
|
||||
opendbc/tesla_powertrain.dbc
|
||||
|
||||
tinygrad_repo/accel/opencl/*
|
||||
tinygrad_repo/tinygrad/llops/ops_opencl.py
|
||||
tinygrad_repo/openpilot/compile.py
|
||||
tinygrad_repo/extra/onnx.py
|
||||
tinygrad_repo/extra/onnx_ops.py
|
||||
tinygrad_repo/extra/thneed.py
|
||||
tinygrad_repo/extra/utils.py
|
||||
tinygrad_repo/tinygrad/llops/ops_gpu.py
|
||||
tinygrad_repo/tinygrad/shape/*
|
||||
tinygrad_repo/tinygrad/codegen/ast.py
|
||||
tinygrad_repo/tinygrad/codegen/gpu.py
|
||||
tinygrad_repo/tinygrad/nn/*
|
||||
tinygrad_repo/tinygrad/runtime/ops_gpu.py
|
||||
tinygrad_repo/tinygrad/shape/*
|
||||
tinygrad_repo/tinygrad/*.py
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ system/camerad/cameras/camera_util.cc
|
||||
system/camerad/cameras/camera_util.h
|
||||
system/camerad/cameras/real_debayer.cl
|
||||
|
||||
selfdrive/sensord/rawgps/*
|
||||
system/sensord/rawgps/*
|
||||
|
||||
selfdrive/ui/qt/spinner_larch64
|
||||
selfdrive/ui/qt/text_larch64
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
@@ -36,8 +36,8 @@ from common.file_helpers import CallbackReader
|
||||
from common.params import Params
|
||||
from common.realtime import sec_since_boot, set_core_affinity
|
||||
from system.hardware import HARDWARE, PC, AGNOS
|
||||
from selfdrive.loggerd.config import ROOT
|
||||
from selfdrive.loggerd.xattr_cache import getxattr, setxattr
|
||||
from system.loggerd.config import ROOT
|
||||
from system.loggerd.xattr_cache import getxattr, setxattr
|
||||
from selfdrive.statsd import STATS_DIR
|
||||
from system.swaglog import SWAGLOG_DIR, cloudlog
|
||||
from system.version import get_commit, get_origin, get_short_branch, get_version
|
||||
|
||||
+16
-13
@@ -113,32 +113,35 @@ bool safety_setter_thread(std::vector<Panda *> pandas) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// set to ELM327 for fingerprinting
|
||||
// initialize to ELM327 without OBD multiplexing for fingerprinting
|
||||
bool obd_multiplexing_enabled = false;
|
||||
for (int i = 0; i < pandas.size(); i++) {
|
||||
const uint16_t safety_param = (i > 0) ? 1U : 0U;
|
||||
pandas[i]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, safety_param);
|
||||
pandas[i]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1U);
|
||||
}
|
||||
|
||||
// wait for FW query at OBD port to finish
|
||||
// openpilot can switch between multiplexing modes for different FW queries
|
||||
while (true) {
|
||||
if (do_exit || !check_all_connected(pandas) || !ignition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p.getBool("FirmwareObdQueryDone")) {
|
||||
LOGW("finished FW query at OBD port");
|
||||
bool obd_multiplexing_requested = p.getBool("ObdMultiplexingEnabled");
|
||||
if (obd_multiplexing_requested != obd_multiplexing_enabled) {
|
||||
for (int i = 0; i < pandas.size(); i++) {
|
||||
const uint16_t safety_param = (i > 0 || !obd_multiplexing_requested) ? 1U : 0U;
|
||||
pandas[i]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, safety_param);
|
||||
}
|
||||
obd_multiplexing_enabled = obd_multiplexing_requested;
|
||||
p.putBool("ObdMultiplexingChanged", true);
|
||||
}
|
||||
|
||||
if (p.getBool("FirmwareQueryDone")) {
|
||||
LOGW("finished FW query");
|
||||
break;
|
||||
}
|
||||
util::sleep_for(20);
|
||||
}
|
||||
|
||||
// set to ELM327 to finish fingerprinting and for potential ECU knockouts
|
||||
for (Panda *panda : pandas) {
|
||||
panda->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1U);
|
||||
}
|
||||
|
||||
p.putBool("ObdMultiplexingDisabled", true);
|
||||
|
||||
std::string params;
|
||||
LOGW("waiting for params to set safety model");
|
||||
while (true) {
|
||||
|
||||
@@ -84,9 +84,9 @@ def main() -> NoReturn:
|
||||
params.remove("PandaSignatures")
|
||||
|
||||
# Flash all Pandas in DFU mode
|
||||
for p in PandaDFU.list():
|
||||
cloudlog.info(f"Panda in DFU mode found, flashing recovery {p}")
|
||||
PandaDFU(p).recover()
|
||||
for serial in PandaDFU.list():
|
||||
cloudlog.info(f"Panda in DFU mode found, flashing recovery {serial}")
|
||||
PandaDFU(serial).recover()
|
||||
time.sleep(1)
|
||||
|
||||
panda_serials = Panda.list()
|
||||
|
||||
@@ -51,7 +51,7 @@ class TestBoardd(unittest.TestCase):
|
||||
cp.safetyConfigs = [safety_config]*num_pandas
|
||||
|
||||
params = Params()
|
||||
params.put_bool("FirmwareObdQueryDone", True)
|
||||
params.put_bool("FirmwareQueryDone", True)
|
||||
params.put_bool("ControlsReady", True)
|
||||
params.put("CarParams", cp.to_bytes())
|
||||
|
||||
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from panda import Panda
|
||||
from selfdrive.test.helpers import phone_only
|
||||
from selfdrive.manager.process_config import managed_processes
|
||||
from system.hardware import HARDWARE
|
||||
|
||||
|
||||
class TestPandad(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
managed_processes['pandad'].stop()
|
||||
|
||||
def _wait_for_boardd(self):
|
||||
sm = messaging.SubMaster(['peripheralState'])
|
||||
for _ in range(30):
|
||||
sm.update(1000)
|
||||
if sm.updated['peripheralState']:
|
||||
break
|
||||
|
||||
if not sm.updated['peripheralState']:
|
||||
raise Exception("boardd failed to start")
|
||||
|
||||
@phone_only
|
||||
def test_in_dfu(self):
|
||||
HARDWARE.recover_internal_panda()
|
||||
time.sleep(1)
|
||||
|
||||
managed_processes['pandad'].start()
|
||||
self._wait_for_boardd()
|
||||
|
||||
@phone_only
|
||||
def test_in_bootstub(self):
|
||||
with Panda() as p:
|
||||
p.reset(enter_bootstub=True)
|
||||
assert p.bootstub
|
||||
managed_processes['pandad'].start()
|
||||
self._wait_for_boardd()
|
||||
|
||||
#def test_out_of_date_fw(self):
|
||||
# pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+24
-16
@@ -73,7 +73,7 @@ def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None, body_dbc=None) -> Dict[str, st
|
||||
return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc, 'body': body_dbc}
|
||||
|
||||
|
||||
def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque, LIMITS):
|
||||
def apply_driver_steer_torque_limits(apply_torque, apply_torque_last, driver_torque, LIMITS):
|
||||
|
||||
# limits due to driver torque
|
||||
driver_max_torque = LIMITS.STEER_MAX + (LIMITS.STEER_DRIVER_ALLOWANCE + driver_torque * LIMITS.STEER_DRIVER_FACTOR) * LIMITS.STEER_DRIVER_MULTIPLIER
|
||||
@@ -93,29 +93,37 @@ def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque
|
||||
return int(round(float(apply_torque)))
|
||||
|
||||
|
||||
def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torque, LIMITS):
|
||||
# limits due to comparison of commanded torque VS motor reported torque
|
||||
max_lim = min(max(motor_torque + LIMITS.STEER_ERROR_MAX, LIMITS.STEER_ERROR_MAX), LIMITS.STEER_MAX)
|
||||
min_lim = max(min(motor_torque - LIMITS.STEER_ERROR_MAX, -LIMITS.STEER_ERROR_MAX), -LIMITS.STEER_MAX)
|
||||
def apply_dist_to_meas_limits(val, val_last, val_meas,
|
||||
STEER_DELTA_UP, STEER_DELTA_DOWN,
|
||||
STEER_ERROR_MAX, STEER_MAX):
|
||||
# limits due to comparison of commanded val VS measured val (torque/angle/curvature)
|
||||
max_lim = min(max(val_meas + STEER_ERROR_MAX, STEER_ERROR_MAX), STEER_MAX)
|
||||
min_lim = max(min(val_meas - STEER_ERROR_MAX, -STEER_ERROR_MAX), -STEER_MAX)
|
||||
|
||||
apply_torque = clip(apply_torque, min_lim, max_lim)
|
||||
val = clip(val, min_lim, max_lim)
|
||||
|
||||
# slow rate if steer torque increases in magnitude
|
||||
if apply_torque_last > 0:
|
||||
apply_torque = clip(apply_torque,
|
||||
max(apply_torque_last - LIMITS.STEER_DELTA_DOWN, -LIMITS.STEER_DELTA_UP),
|
||||
apply_torque_last + LIMITS.STEER_DELTA_UP)
|
||||
# slow rate if val increases in magnitude
|
||||
if val_last > 0:
|
||||
val = clip(val,
|
||||
max(val_last - STEER_DELTA_DOWN, -STEER_DELTA_UP),
|
||||
val_last + STEER_DELTA_UP)
|
||||
else:
|
||||
apply_torque = clip(apply_torque,
|
||||
apply_torque_last - LIMITS.STEER_DELTA_UP,
|
||||
min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP))
|
||||
val = clip(val,
|
||||
val_last - STEER_DELTA_UP,
|
||||
min(val_last + STEER_DELTA_DOWN, STEER_DELTA_UP))
|
||||
|
||||
return int(round(float(apply_torque)))
|
||||
return float(val)
|
||||
|
||||
|
||||
def apply_meas_steer_torque_limits(apply_torque, apply_torque_last, motor_torque, LIMITS):
|
||||
return int(round(apply_dist_to_meas_limits(apply_torque, apply_torque_last, motor_torque,
|
||||
LIMITS.STEER_DELTA_UP, LIMITS.STEER_DELTA_DOWN,
|
||||
LIMITS.STEER_ERROR_MAX, LIMITS.STEER_MAX)))
|
||||
|
||||
|
||||
def apply_std_steer_angle_limits(apply_angle, apply_angle_last, v_ego, LIMITS):
|
||||
# pick angle rate limits based on wind up/down
|
||||
steer_up = apply_angle_last * apply_angle > 0. and abs(apply_angle) > abs(apply_angle_last)
|
||||
steer_up = apply_angle_last * apply_angle >= 0. and abs(apply_angle) > abs(apply_angle_last)
|
||||
rate_limits = LIMITS.ANGLE_RATE_LIMIT_UP if steer_up else LIMITS.ANGLE_RATE_LIMIT_DOWN
|
||||
|
||||
angle_rate_lim = interp(v_ego, rate_limits.speed_bp, rate_limits.angle_v)
|
||||
|
||||
@@ -8,7 +8,7 @@ from system.version import is_comma_remote, is_tested_branch
|
||||
from selfdrive.car.interfaces import get_interface_attr
|
||||
from selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars
|
||||
from selfdrive.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN
|
||||
from selfdrive.car.fw_versions import disable_obd_multiplexing, get_fw_versions_ordered, match_fw_to_car, get_present_ecus
|
||||
from selfdrive.car.fw_versions import get_fw_versions_ordered, get_present_ecus, match_fw_to_car, set_obd_multiplexing
|
||||
from system.swaglog import cloudlog
|
||||
import cereal.messaging as messaging
|
||||
from selfdrive.car import gen_empty_fingerprint
|
||||
@@ -80,12 +80,13 @@ def fingerprint(logcan, sendcan, num_pandas):
|
||||
fixed_fingerprint = os.environ.get('FINGERPRINT', "")
|
||||
skip_fw_query = os.environ.get('SKIP_FW_QUERY', False)
|
||||
ecu_rx_addrs = set()
|
||||
params = Params()
|
||||
|
||||
if not skip_fw_query:
|
||||
# Vin query only reliably works through OBDII
|
||||
bus = 1
|
||||
|
||||
cached_params = Params().get("CarParamsCache")
|
||||
cached_params = params.get("CarParamsCache")
|
||||
if cached_params is not None:
|
||||
cached_params = car.CarParams.from_bytes(cached_params)
|
||||
if cached_params.carName == "mock":
|
||||
@@ -98,6 +99,7 @@ def fingerprint(logcan, sendcan, num_pandas):
|
||||
cached = True
|
||||
else:
|
||||
cloudlog.warning("Getting VIN & FW versions")
|
||||
set_obd_multiplexing(params, True)
|
||||
vin_rx_addr, vin = get_vin(logcan, sendcan, bus)
|
||||
ecu_rx_addrs = get_present_ecus(logcan, sendcan, num_pandas=num_pandas)
|
||||
car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, num_pandas=num_pandas)
|
||||
@@ -113,10 +115,11 @@ def fingerprint(logcan, sendcan, num_pandas):
|
||||
cloudlog.event("Malformed VIN", vin=vin, error=True)
|
||||
vin = VIN_UNKNOWN
|
||||
cloudlog.warning("VIN %s", vin)
|
||||
|
||||
params = Params()
|
||||
params.put("CarVin", vin)
|
||||
disable_obd_multiplexing(params)
|
||||
|
||||
# disable OBD multiplexing for potential ECU knockouts
|
||||
set_obd_multiplexing(params, False)
|
||||
params.put_bool("FirmwareQueryDone", True)
|
||||
|
||||
finger = gen_empty_fingerprint()
|
||||
candidate_cars = {i: all_legacy_fingerprint_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1
|
||||
@@ -180,7 +183,7 @@ def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1):
|
||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas)
|
||||
|
||||
if candidate is None:
|
||||
cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints)
|
||||
cloudlog.event("car doesn't match any fingerprints", fingerprints=fingerprints, error=True)
|
||||
candidate = "mock"
|
||||
|
||||
CarInterface, CarController, CarState = interfaces[candidate]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from opendbc.can.packer import CANPacker
|
||||
from common.realtime import DT_CTRL
|
||||
from selfdrive.car import apply_toyota_steer_torque_limits
|
||||
from selfdrive.car import apply_meas_steer_torque_limits
|
||||
from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, create_cruise_buttons
|
||||
from selfdrive.car.chrysler.values import RAM_CARS, CarControllerParams, ChryslerFlags
|
||||
|
||||
@@ -67,7 +67,7 @@ class CarController:
|
||||
|
||||
# steer torque
|
||||
new_steer = int(round(CC.actuators.steer * self.params.STEER_MAX))
|
||||
apply_steer = apply_toyota_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params)
|
||||
apply_steer = apply_meas_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorqueEps, self.params)
|
||||
if not lkas_active or not lkas_control_bit:
|
||||
apply_steer = 0
|
||||
self.apply_steer_last = apply_steer
|
||||
|
||||
@@ -50,6 +50,7 @@ class CarControllerParams:
|
||||
self.STEER_DELTA_DOWN = 3
|
||||
self.STEER_MAX = 261 # higher than this faults the EPS
|
||||
|
||||
|
||||
STEER_THRESHOLD = 120
|
||||
|
||||
RAM_DT = {CAR.RAM_1500, }
|
||||
@@ -62,6 +63,7 @@ class ChryslerCarInfo(CarInfo):
|
||||
package: str = "Adaptive Cruise Control (ACC)"
|
||||
harness: Enum = Harness.fca
|
||||
|
||||
|
||||
CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = {
|
||||
CAR.PACIFICA_2017_HYBRID: ChryslerCarInfo("Chrysler Pacifica Hybrid 2017-18"),
|
||||
CAR.PACIFICA_2018_HYBRID: None, # same platforms
|
||||
@@ -73,10 +75,10 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = {
|
||||
],
|
||||
CAR.JEEP_CHEROKEE: ChryslerCarInfo("Jeep Grand Cherokee 2016-18", video_link="https://www.youtube.com/watch?v=eLR9o2JkuRk"),
|
||||
CAR.JEEP_CHEROKEE_2019: ChryslerCarInfo("Jeep Grand Cherokee 2019-21", video_link="https://www.youtube.com/watch?v=jBe4lWnRSu4"),
|
||||
CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-22", harness=Harness.ram),
|
||||
CAR.RAM_1500: ChryslerCarInfo("Ram 1500 2019-23", harness=Harness.ram),
|
||||
CAR.RAM_HD: [
|
||||
ChryslerCarInfo("Ram 2500 2020-22", harness=Harness.ram),
|
||||
ChryslerCarInfo("Ram 3500 2020-22", harness=Harness.ram),
|
||||
ChryslerCarInfo("Ram 3500 2019-22", harness=Harness.ram),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -93,13 +95,13 @@ CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = {
|
||||
|
||||
FINGERPRINTS = {
|
||||
CAR.PACIFICA_2017_HYBRID: [{
|
||||
168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 788:3, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 3, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 958: 8, 959: 8, 969: 4, 974: 5, 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, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1892: 8, 2016: 8, 2024: 8
|
||||
168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 788: 3, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 840: 8, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 3, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 956: 8, 958: 8, 959: 8, 969: 4, 974: 5, 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, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1225: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1284: 8, 1537: 8, 1538: 8, 1562: 8, 1568: 8, 1856: 8, 1858: 8, 1860: 8, 1865: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1892: 8, 2016: 8, 2024: 8
|
||||
}],
|
||||
CAR.PACIFICA_2018: [{
|
||||
55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 8, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 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, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8
|
||||
},
|
||||
{
|
||||
55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 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, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8
|
||||
55: 8, 58: 6, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 926: 3, 937: 8, 947: 8, 948: 8, 956: 8, 969: 4, 974: 5, 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, 1098: 8, 1100: 8, 1537: 8, 1538: 8, 1562: 8
|
||||
}],
|
||||
CAR.PACIFICA_2020: [{
|
||||
55: 8, 179: 8, 181: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 516: 7, 517: 7, 520: 8, 524: 8, 526: 6, 528: 8, 532: 8, 536: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 650: 8, 656: 4, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 711: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 776: 8, 779: 8, 782: 8, 784: 8, 792: 8, 793: 8, 794: 8, 795: 8, 799: 8, 800: 8, 801: 8, 802: 8, 803: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 847: 1, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 886: 8, 897: 8, 906: 8, 924: 8, 926: 3, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 962: 8, 969: 4, 973: 8, 974: 5, 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, 1098: 8, 1100: 8, 1216: 8, 1218: 8, 1220: 8, 1223: 7, 1225: 8, 1227: 8, 1235: 8, 1242: 8, 1246: 8, 1250: 8, 1251: 8, 1252: 8, 1284: 8, 1543: 8, 1568: 8, 1570: 8, 1856: 8, 1858: 8, 1860: 8, 1863: 8, 1865: 8, 1867: 8, 1875: 8, 1882: 8, 1886: 8, 1890: 8, 1891: 8, 1892: 8, 1898: 8, 2015: 8, 2016: 8, 2017:8, 2024: 8, 2025: 8
|
||||
@@ -135,7 +137,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, 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
|
||||
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, 1538: 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
|
||||
}],
|
||||
}
|
||||
|
||||
@@ -180,79 +182,153 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
)
|
||||
|
||||
FW_VERSIONS = {
|
||||
CAR.RAM_1500: {
|
||||
CAR.JEEP_CHEROKEE_2019: {
|
||||
(Ecu.combinationMeter, 0x742, None): [
|
||||
b'68294063AH',
|
||||
b'68294063AG',
|
||||
b'68434860AC',
|
||||
b'68527375AD',
|
||||
b'68453503AC',
|
||||
b'68402971AD',
|
||||
],
|
||||
(Ecu.srs, 0x744, None): [
|
||||
b'68441329AB',
|
||||
b'68490898AA',
|
||||
b'68428609AB',
|
||||
b'68500728AA',
|
||||
b'68355363AB',
|
||||
],
|
||||
(Ecu.abs, 0x747, None): [
|
||||
b'68432418AD',
|
||||
b'68432418AB',
|
||||
b'68436004AE',
|
||||
b'68438454AD',
|
||||
b'68436004AD',
|
||||
b'68535469AB',
|
||||
b'68438454AC',
|
||||
b'68408639AD',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x753, None): [
|
||||
b'68320950AL',
|
||||
b'68320950AJ',
|
||||
b'68454268AB',
|
||||
b'68475160AG',
|
||||
b'04672892AB',
|
||||
b'68475160AE',
|
||||
b'68456722AC',
|
||||
],
|
||||
(Ecu.eps, 0x75A, None): [
|
||||
b'68273275AG',
|
||||
b'68469901AA',
|
||||
b'68552788AA',
|
||||
b'68453431AA',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'68448163AJ',
|
||||
b'68500630AD',
|
||||
b'68539650AD',
|
||||
b'05035674AB ',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'05035707AA',
|
||||
],
|
||||
},
|
||||
|
||||
CAR.RAM_1500: {
|
||||
(Ecu.combinationMeter, 0x742, None): [
|
||||
b'68294051AG',
|
||||
b'68294051AI',
|
||||
b'68294052AG',
|
||||
b'68294063AG',
|
||||
b'68294063AH',
|
||||
b'68294063AI',
|
||||
b'68434846AC',
|
||||
b'68434858AC',
|
||||
b'68434860AC',
|
||||
b'68453503AC',
|
||||
b'68453505AC',
|
||||
b'68453511AC',
|
||||
b'68453513AD',
|
||||
b'68453514AD',
|
||||
b'68510283AG',
|
||||
b'68527375AD',
|
||||
],
|
||||
(Ecu.srs, 0x744, None): [
|
||||
b'68428609AB',
|
||||
b'68441329AB',
|
||||
b'68473844AB',
|
||||
b'68490898AA',
|
||||
b'68500728AA',
|
||||
b'68615033AA',
|
||||
],
|
||||
(Ecu.abs, 0x747, None): [
|
||||
b'68292406AH',
|
||||
b'68432418AB',
|
||||
b'68432418AD',
|
||||
b'68436004AD',
|
||||
b'68436004AE',
|
||||
b'68438454AC',
|
||||
b'68438454AD',
|
||||
b'68438456AE',
|
||||
b'68438456AF',
|
||||
b'68535469AB',
|
||||
b'68535470AC',
|
||||
b'68586307AB',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x753, None): [
|
||||
b'04672892AB',
|
||||
b'04672932AB',
|
||||
b'68320950AH',
|
||||
b'68320950AI',
|
||||
b'68320950AJ',
|
||||
b'68320950AL',
|
||||
b'68320950AM',
|
||||
b'68454268AB',
|
||||
b'68475160AE',
|
||||
b'68475160AF',
|
||||
b'68475160AG',
|
||||
],
|
||||
(Ecu.eps, 0x75A, None): [
|
||||
b'68273275AF',
|
||||
b'68273275AG',
|
||||
b'68312176AE',
|
||||
b'68312176AG',
|
||||
b'68440789AC',
|
||||
b'68466110AB',
|
||||
b'68469901AA',
|
||||
b'68522583AB',
|
||||
b'68522585AB',
|
||||
b'68552788AA',
|
||||
b'68552790AA',
|
||||
b'68585112AB',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'05036065AE ',
|
||||
b'05036066AE ',
|
||||
b'68378701AI ',
|
||||
b'68378758AM ',
|
||||
b'68448163AJ',
|
||||
b'68448165AK',
|
||||
b'68500630AD',
|
||||
b'68500630AE',
|
||||
b'68539650AD',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'68360078AL',
|
||||
b'68384328AD',
|
||||
b'68360085AL',
|
||||
b'68360080AM',
|
||||
b'68360081AM',
|
||||
b'68502994AD',
|
||||
b'68360085AL',
|
||||
b'68384328AD',
|
||||
b'68384332AD',
|
||||
b'68445533AB',
|
||||
b'68540431AB',
|
||||
b'68484467AC',
|
||||
b'68502994AD',
|
||||
b'68540431AB',
|
||||
],
|
||||
},
|
||||
|
||||
CAR.RAM_HD: {
|
||||
(Ecu.combinationMeter, 0x742, None): [
|
||||
b'68361606AH',
|
||||
b'68437735AC',
|
||||
b'68492693AD',
|
||||
b'68525485AB',
|
||||
b'68525487AB',
|
||||
b'68525498AB',
|
||||
],
|
||||
(Ecu.srs, 0x744, None): [
|
||||
b'68399794AC',
|
||||
b'68428503AA',
|
||||
b'68428505AA',
|
||||
b'68428507AA',
|
||||
],
|
||||
(Ecu.abs, 0x747, None): [
|
||||
b'68334977AH',
|
||||
b'68455481AC',
|
||||
b'68504022AA',
|
||||
b'68504022AB',
|
||||
b'68530686AB',
|
||||
b'68504022AC',
|
||||
b'68530686AB',
|
||||
b'68530686AC',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x753, None): [
|
||||
b'04672895AB',
|
||||
b'56029827AG',
|
||||
b'56029827AH',
|
||||
b'68462657AE',
|
||||
b'68484694AD',
|
||||
b'68484694AE',
|
||||
],
|
||||
(Ecu.eps, 0x761, None): [
|
||||
@@ -260,7 +336,13 @@ FW_VERSIONS = {
|
||||
b'68507906AB',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'52370131AF',
|
||||
b'52370231AF',
|
||||
b'52370231AG',
|
||||
b'52370931CT',
|
||||
b'52401032AE',
|
||||
b'52421132AF',
|
||||
b'68527616AD ',
|
||||
b'M2370131MB',
|
||||
b'M2421132MB',
|
||||
],
|
||||
|
||||
@@ -9,6 +9,8 @@ from selfdrive.car import make_can_msg
|
||||
from selfdrive.boardd.boardd import can_list_to_can_capnp
|
||||
from system.swaglog import cloudlog
|
||||
|
||||
EcuAddrBusType = Tuple[int, Optional[int], int]
|
||||
|
||||
|
||||
def make_tester_present_msg(addr, bus, subaddr=None):
|
||||
dat = [0x02, SERVICE_TYPE.TESTER_PRESENT, 0x0]
|
||||
@@ -33,16 +35,16 @@ def is_tester_present_response(msg: capnp.lib.capnp._DynamicStructReader, subadd
|
||||
return False
|
||||
|
||||
|
||||
def get_all_ecu_addrs(logcan: messaging.SubSocket, sendcan: messaging.PubSocket, bus: int, timeout: float = 1, debug: bool = True) -> Set[Tuple[int, Optional[int], int]]:
|
||||
def get_all_ecu_addrs(logcan: messaging.SubSocket, sendcan: messaging.PubSocket, bus: int, timeout: float = 1, debug: bool = True) -> Set[EcuAddrBusType]:
|
||||
addr_list = [0x700 + i for i in range(256)] + [0x18da00f1 + (i << 8) for i in range(256)]
|
||||
queries: Set[Tuple[int, Optional[int], int]] = {(addr, None, bus) for addr in addr_list}
|
||||
queries: Set[EcuAddrBusType] = {(addr, None, bus) for addr in addr_list}
|
||||
responses = queries
|
||||
return get_ecu_addrs(logcan, sendcan, queries, responses, timeout=timeout, debug=debug)
|
||||
|
||||
|
||||
def get_ecu_addrs(logcan: messaging.SubSocket, sendcan: messaging.PubSocket, queries: Set[Tuple[int, Optional[int], int]],
|
||||
responses: Set[Tuple[int, Optional[int], int]], timeout: float = 1, debug: bool = False) -> Set[Tuple[int, Optional[int], int]]:
|
||||
ecu_responses: Set[Tuple[int, Optional[int], int]] = set() # set((addr, subaddr, bus),)
|
||||
def get_ecu_addrs(logcan: messaging.SubSocket, sendcan: messaging.PubSocket, queries: Set[EcuAddrBusType],
|
||||
responses: Set[EcuAddrBusType], timeout: float = 1, debug: bool = False) -> Set[EcuAddrBusType]:
|
||||
ecu_responses: Set[EcuAddrBusType] = set() # set((addr, subaddr, bus),)
|
||||
try:
|
||||
msgs = [make_tester_present_msg(addr, bus, subaddr) for addr, subaddr, bus in queries]
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class CarState(CarStateBase):
|
||||
# steering wheel
|
||||
ret.steeringAngleDeg = cp.vl["SteeringPinion_Data"]["StePinComp_An_Est"]
|
||||
ret.steeringTorque = cp.vl["EPAS_INFO"]["SteeringColumnTorque"]
|
||||
ret.steeringPressed = abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE
|
||||
ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE, 5)
|
||||
ret.steerFaultTemporary = cp.vl["EPAS_INFO"]["EPAS_Failure"] == 1
|
||||
ret.steerFaultPermanent = cp.vl["EPAS_INFO"]["EPAS_Failure"] in (2, 3)
|
||||
# ret.espDisabled = False # TODO: find traction control signal
|
||||
|
||||
@@ -24,12 +24,13 @@ class CarControllerParams:
|
||||
BUTTONS_STEP = 10 / 2
|
||||
|
||||
CURVATURE_MAX = 0.02 # Max curvature for steering command, m^-1
|
||||
STEER_DRIVER_ALLOWANCE = 0.8 # Driver intervention threshold, Nm
|
||||
STEER_DRIVER_ALLOWANCE = 1.0 # Driver intervention threshold, Nm
|
||||
|
||||
# Curvature rate limits
|
||||
# TODO: unify field names used by curvature and angle control cars
|
||||
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.005, 0.00056, 0.0002])
|
||||
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.008, 0.00089, 0.00032])
|
||||
# ~2 m/s^3 up, ~-3 m/s^3 down
|
||||
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.004, 0.00044, 0.00016])
|
||||
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[5, 15, 25], angle_v=[0.006, 0.00066, 0.00024])
|
||||
|
||||
ACCEL_MAX = 2.0 # m/s^s max acceleration
|
||||
ACCEL_MIN = -3.5 # m/s^s max deceleration
|
||||
@@ -164,6 +165,7 @@ FW_VERSIONS = {
|
||||
b'M1MC-14D003-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x760, None): [
|
||||
b'L1MC-2D053-BA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'L1MC-2D053-BB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'L1MC-2D053-BF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'L1MC-2D053-KB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
@@ -177,6 +179,7 @@ FW_VERSIONS = {
|
||||
b'LC5T-14F397-AH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x7E0, None): [
|
||||
b'LB5A-14C204-BUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'LB5A-14C204-EAC\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'MB5A-14C204-MD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'MB5A-14C204-RC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import capnp
|
||||
import copy
|
||||
from dataclasses import dataclass, field
|
||||
import struct
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
@@ -57,10 +58,12 @@ class Request:
|
||||
whitelist_ecus: List[int] = field(default_factory=list)
|
||||
rx_offset: int = 0x8
|
||||
bus: int = 1
|
||||
# Whether this query should be run on the first auxiliary panda (CAN FD cars for example)
|
||||
auxiliary: bool = False
|
||||
# FW responses from these queries will not be used for fingerprinting
|
||||
logging: bool = False
|
||||
# These requests are done once OBD multiplexing is disabled, after all others
|
||||
non_obd: bool = False
|
||||
# boardd toggles OBD multiplexing on/off as needed
|
||||
obd_multiplexing: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -71,3 +74,10 @@ class FwQueryConfig:
|
||||
non_essential_ecus: Dict[capnp.lib.capnp._EnumModule, List[str]] = field(default_factory=dict)
|
||||
# Ecus added for data collection, not to be fingerprinted on
|
||||
extra_ecus: List[Tuple[capnp.lib.capnp._EnumModule, int, Optional[int]]] = field(default_factory=list)
|
||||
|
||||
def __post_init__(self):
|
||||
for i in range(len(self.requests)):
|
||||
if self.requests[i].auxiliary:
|
||||
new_request = copy.deepcopy(self.requests[i])
|
||||
new_request.bus += 4
|
||||
self.requests.append(new_request)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
from collections import defaultdict
|
||||
from typing import Any, Optional, Set, Tuple
|
||||
from typing import Any, Dict, List, Set
|
||||
from tqdm import tqdm
|
||||
|
||||
import panda.python.uds as uds
|
||||
from cereal import car
|
||||
from common.params import Params
|
||||
from selfdrive.car.ecu_addrs import get_ecu_addrs
|
||||
from selfdrive.car.ecu_addrs import EcuAddrBusType, get_ecu_addrs
|
||||
from selfdrive.car.interfaces import get_interface_attr
|
||||
from selfdrive.car.fingerprints import FW_VERSIONS
|
||||
from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery
|
||||
@@ -19,7 +19,7 @@ FW_QUERY_CONFIGS = get_interface_attr('FW_QUERY_CONFIG', ignore_none=True)
|
||||
VERSIONS = get_interface_attr('FW_VERSIONS', ignore_none=True)
|
||||
|
||||
MODEL_TO_BRAND = {c: b for b, e in VERSIONS.items() for c in e}
|
||||
REQUESTS = [(brand, r) for brand, config in FW_QUERY_CONFIGS.items() for r in config.requests]
|
||||
REQUESTS = [(brand, config, r) for brand, config in FW_QUERY_CONFIGS.items() for r in config.requests]
|
||||
|
||||
|
||||
def chunks(l, n=128):
|
||||
@@ -39,6 +39,8 @@ def build_fw_dict(fw_versions, filter_brand=None):
|
||||
def get_brand_addrs():
|
||||
brand_addrs = defaultdict(set)
|
||||
for brand, cars in VERSIONS.items():
|
||||
# Add ecus in database + extra ecus to match against
|
||||
brand_addrs[brand] |= {(addr, sub_addr) for _, addr, sub_addr in FW_QUERY_CONFIGS[brand].extra_ecus}
|
||||
for fw in cars.values():
|
||||
brand_addrs[brand] |= {(addr, sub_addr) for _, addr, sub_addr in fw.keys()}
|
||||
return brand_addrs
|
||||
@@ -146,38 +148,43 @@ def match_fw_to_car(fw_versions, allow_exact=True, allow_fuzzy=True):
|
||||
return True, set()
|
||||
|
||||
|
||||
def get_present_ecus(logcan, sendcan, num_pandas=1) -> Set[Tuple[int, Optional[int], int]]:
|
||||
queries = list()
|
||||
parallel_queries = list()
|
||||
def get_present_ecus(logcan, sendcan, num_pandas=1) -> Set[EcuAddrBusType]:
|
||||
params = Params()
|
||||
# queries are split by OBD multiplexing mode
|
||||
queries: Dict[bool, List[List[EcuAddrBusType]]] = {True: [], False: []}
|
||||
parallel_queries: Dict[bool, List[EcuAddrBusType]] = {True: [], False: []}
|
||||
responses = set()
|
||||
|
||||
for brand, r in REQUESTS:
|
||||
for brand, config, r in REQUESTS:
|
||||
# Skip query if no panda available
|
||||
if r.bus > num_pandas * 4 - 1:
|
||||
continue
|
||||
|
||||
for brand_versions in VERSIONS[brand].values():
|
||||
for ecu_type, addr, sub_addr in brand_versions:
|
||||
for ecu_type, addr, sub_addr in list(brand_versions) + config.extra_ecus:
|
||||
# Only query ecus in whitelist if whitelist is not empty
|
||||
if len(r.whitelist_ecus) == 0 or ecu_type in r.whitelist_ecus:
|
||||
a = (addr, sub_addr, r.bus)
|
||||
# Build set of queries
|
||||
if sub_addr is None:
|
||||
if a not in parallel_queries:
|
||||
parallel_queries.append(a)
|
||||
if a not in parallel_queries[r.obd_multiplexing]:
|
||||
parallel_queries[r.obd_multiplexing].append(a)
|
||||
else: # subaddresses must be queried one by one
|
||||
if [a] not in queries:
|
||||
queries.append([a])
|
||||
if [a] not in queries[r.obd_multiplexing]:
|
||||
queries[r.obd_multiplexing].append([a])
|
||||
|
||||
# Build set of expected responses to filter
|
||||
response_addr = uds.get_rx_addr_for_tx_addr(addr, r.rx_offset)
|
||||
responses.add((response_addr, sub_addr, r.bus))
|
||||
|
||||
queries.insert(0, parallel_queries)
|
||||
for obd_multiplexing in queries:
|
||||
queries[obd_multiplexing].insert(0, parallel_queries[obd_multiplexing])
|
||||
|
||||
ecu_responses = set()
|
||||
for query in queries:
|
||||
ecu_responses.update(get_ecu_addrs(logcan, sendcan, set(query), responses, timeout=0.1))
|
||||
for obd_multiplexing in queries:
|
||||
set_obd_multiplexing(params, obd_multiplexing)
|
||||
for query in queries[obd_multiplexing]:
|
||||
ecu_responses.update(get_ecu_addrs(logcan, sendcan, set(query), responses, timeout=0.1))
|
||||
return ecu_responses
|
||||
|
||||
|
||||
@@ -185,9 +192,9 @@ def get_brand_ecu_matches(ecu_rx_addrs):
|
||||
"""Returns dictionary of brands and matches with ECUs in their FW versions"""
|
||||
|
||||
brand_addrs = get_brand_addrs()
|
||||
brand_matches = {brand: set() for brand, _ in REQUESTS}
|
||||
brand_matches = {brand: set() for brand, _, _ in REQUESTS}
|
||||
|
||||
brand_rx_offsets = set((brand, r.rx_offset) for brand, r in REQUESTS)
|
||||
brand_rx_offsets = set((brand, r.rx_offset) for brand, _, r in REQUESTS)
|
||||
for addr, sub_addr, _ in ecu_rx_addrs:
|
||||
# Since we can't know what request an ecu responded to, add matches for all possible rx offsets
|
||||
for brand, rx_offset in brand_rx_offsets:
|
||||
@@ -198,13 +205,13 @@ def get_brand_ecu_matches(ecu_rx_addrs):
|
||||
return brand_matches
|
||||
|
||||
|
||||
def disable_obd_multiplexing(params):
|
||||
if not params.get_bool("ObdMultiplexingDisabled"):
|
||||
params.put_bool("FirmwareObdQueryDone", True)
|
||||
|
||||
cloudlog.warning("Waiting for OBD multiplexing to be disabled")
|
||||
params.get_bool("ObdMultiplexingDisabled", block=True)
|
||||
cloudlog.warning("OBD multiplexing disabled")
|
||||
def set_obd_multiplexing(params: Params, obd_multiplexing: bool):
|
||||
if params.get_bool("ObdMultiplexingEnabled") != obd_multiplexing:
|
||||
cloudlog.warning(f"Setting OBD multiplexing to {obd_multiplexing}")
|
||||
params.remove("ObdMultiplexingChanged")
|
||||
params.put_bool("ObdMultiplexingEnabled", obd_multiplexing)
|
||||
params.get_bool("ObdMultiplexingChanged", block=True)
|
||||
cloudlog.warning("OBD multiplexing set successfully")
|
||||
|
||||
|
||||
def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, num_pandas=1, debug=False, progress=False):
|
||||
@@ -212,7 +219,6 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, num_pand
|
||||
|
||||
all_car_fw = []
|
||||
brand_matches = get_brand_ecu_matches(ecu_rx_addrs)
|
||||
matched_brand: Optional[str] = None
|
||||
|
||||
for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True):
|
||||
car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, num_pandas=num_pandas, debug=debug, progress=progress)
|
||||
@@ -220,21 +226,14 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, num_pand
|
||||
# Try to match using FW returned from this brand only
|
||||
matches = match_fw_to_car_exact(build_fw_dict(car_fw))
|
||||
if len(matches) == 1:
|
||||
matched_brand = brand
|
||||
break
|
||||
|
||||
disable_obd_multiplexing(Params())
|
||||
|
||||
# Do non-OBD queries for matched brand, or all if no match is found
|
||||
for brand in FW_QUERY_CONFIGS.keys():
|
||||
if brand == matched_brand or matched_brand is None:
|
||||
all_car_fw.extend(get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, num_pandas=num_pandas, obd_multiplexed=False, debug=debug, progress=progress))
|
||||
|
||||
return all_car_fw
|
||||
|
||||
|
||||
def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, num_pandas=1, obd_multiplexed=True, debug=False, progress=False):
|
||||
def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, num_pandas=1, debug=False, progress=False):
|
||||
versions = VERSIONS.copy()
|
||||
params = Params()
|
||||
|
||||
# Each brand can define extra ECUs to query for data collection
|
||||
for brand, config in FW_QUERY_CONFIGS.items():
|
||||
@@ -250,19 +249,15 @@ 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 candidate, ecu in brand_versions.items():
|
||||
for ecu in brand_versions.values():
|
||||
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)
|
||||
@@ -274,16 +269,17 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1,
|
||||
|
||||
# Get versions and build capnp list to put into CarParams
|
||||
car_fw = []
|
||||
requests = [(brand, r) for brand, r in REQUESTS if query_brand is None or brand == query_brand]
|
||||
requests = [(brand, config, r) for brand, config, r in REQUESTS if query_brand is None or brand == query_brand]
|
||||
for addr in tqdm(addrs, disable=not progress):
|
||||
for addr_chunk in chunks(addr):
|
||||
for brand, r in requests:
|
||||
for brand, config, r in requests:
|
||||
# Skip query if no panda available
|
||||
if r.bus > num_pandas * 4 - 1:
|
||||
continue
|
||||
# Or if request is not designated for current multiplexing mode
|
||||
elif r.non_obd == obd_multiplexed:
|
||||
continue
|
||||
|
||||
# Toggle OBD multiplexing for each request
|
||||
if r.bus % 4 == 1:
|
||||
set_obd_multiplexing(params, r.obd_multiplexing)
|
||||
|
||||
try:
|
||||
addrs = [(a, s) for (b, a, s) in addr_chunk if b in (brand, 'any') and
|
||||
@@ -294,15 +290,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()
|
||||
|
||||
ecu_key = (brand, tx_addr, sub_addr)
|
||||
f.ecu = ecu_types.get(ecu_key, Ecu.unknown)
|
||||
f.ecu = ecu_types.get((brand, tx_addr, sub_addr), 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
|
||||
f.logging = r.logging or (f.ecu, tx_addr, sub_addr) in config.extra_ecus
|
||||
f.obdMultiplexing = r.obd_multiplexing
|
||||
|
||||
if sub_addr is not None:
|
||||
f.subAddress = sub_addr
|
||||
|
||||
@@ -3,7 +3,7 @@ from common.conversions import Conversions as CV
|
||||
from common.numpy_fast import interp
|
||||
from common.realtime import DT_CTRL
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car import apply_driver_steer_torque_limits
|
||||
from selfdrive.car.gm import gmcan
|
||||
from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
|
||||
|
||||
@@ -30,7 +30,6 @@ class CarController:
|
||||
self.cancel_counter = 0
|
||||
|
||||
self.lka_steering_cmd_counter = 0
|
||||
self.sent_lka_steering_cmd = False
|
||||
self.lka_icon_status_last = (False, False)
|
||||
|
||||
self.params = CarControllerParams(self.CP)
|
||||
@@ -59,24 +58,22 @@ class CarController:
|
||||
# - until we're in sync with camera so counters align when relay closes, preventing a fault.
|
||||
# openpilot can subtly drift, so this is activated throughout a drive to stay synced
|
||||
out_of_sync = self.lka_steering_cmd_counter % 4 != (CS.cam_lka_steering_cmd_counter + 1) % 4
|
||||
if not self.sent_lka_steering_cmd or out_of_sync:
|
||||
if CS.loopback_lka_steering_cmd_ts_nanos == 0 or out_of_sync:
|
||||
steer_step = self.params.STEER_STEP
|
||||
|
||||
if CS.loopback_lka_steering_cmd_updated:
|
||||
self.lka_steering_cmd_counter += 1
|
||||
self.sent_lka_steering_cmd = True
|
||||
self.lka_steering_cmd_counter += 1 if CS.loopback_lka_steering_cmd_updated else 0
|
||||
|
||||
# Avoid GM EPS faults when transmitting messages too close together: skip this transmit if we
|
||||
# received the ASCMLKASteeringCmd loopback confirmation too recently
|
||||
last_lka_steer_msg_ms = (now_nanos - CS.loopback_lka_steering_cmd_ts_nanos) * 1e-6
|
||||
if (self.frame - self.last_steer_frame) >= steer_step and last_lka_steer_msg_ms > MIN_STEER_MSG_INTERVAL_MS:
|
||||
# Initialize ASCMLKASteeringCmd counter using the camera until we get a msg on the bus
|
||||
if not self.sent_lka_steering_cmd:
|
||||
if CS.loopback_lka_steering_cmd_ts_nanos == 0:
|
||||
self.lka_steering_cmd_counter = CS.pt_lka_steering_cmd_counter + 1
|
||||
|
||||
if CC.latActive:
|
||||
new_steer = int(round(actuators.steer * self.params.STEER_MAX))
|
||||
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
|
||||
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
|
||||
else:
|
||||
apply_steer = 0
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ class CarState(CarStateBase):
|
||||
|
||||
# Variables used for avoiding LKAS faults
|
||||
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
|
||||
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
if self.loopback_lka_steering_cmd_updated:
|
||||
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
if self.CP.networkLocation == NetworkLocation.fwdCamera:
|
||||
self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
|
||||
|
||||
@@ -3,12 +3,11 @@ 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
|
||||
from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR
|
||||
from selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD
|
||||
from selfdrive.controls.lib.drive_helpers import apply_center_deadzone
|
||||
from selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG
|
||||
from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
EventName = car.CarEvent.EventName
|
||||
@@ -45,48 +44,12 @@ 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 = [-1.0, -0.9, -0.75, -0.5, 0.0, 0.5, 0.75, 0.9, 1.0]
|
||||
steer_lataccel_factors = [1.5, 1.15, 1.02, 1.0, 1.0, 1.0, 1.02, 1.15, 1.5]
|
||||
steer_correction_factor = interp(
|
||||
steer_torque,
|
||||
steer_break_pts,
|
||||
steer_lataccel_factors
|
||||
)
|
||||
|
||||
vego_break_pts = [0.0, 10.0, 15.0, 20.0, 100.0]
|
||||
vego_lataccel_factors = [1.5, 1.5, 1.25, 1.0, 1.0]
|
||||
vego_correction_factor = interp(
|
||||
vego,
|
||||
vego_break_pts,
|
||||
vego_lataccel_factors,
|
||||
)
|
||||
|
||||
return (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"
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
|
||||
ret.autoResumeSng = False
|
||||
use_off_car_defaults = len(fingerprint[0]) == 0 # Pick sensible carParams during offline doc generation/CI jobs
|
||||
|
||||
if candidate in EV_CAR:
|
||||
ret.transmissionType = TransmissionType.direct
|
||||
@@ -115,7 +78,6 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling
|
||||
ret.vEgoStopping = 0.25
|
||||
ret.vEgoStarting = 0.25
|
||||
ret.longitudinalActuatorDelayUpperBound = 0.5
|
||||
|
||||
if experimental_long:
|
||||
ret.pcmCruise = False
|
||||
@@ -125,7 +87,7 @@ class CarInterface(CarInterfaceBase):
|
||||
else: # ASCM, OBD-II harness
|
||||
ret.openpilotLongitudinalControl = True
|
||||
ret.networkLocation = NetworkLocation.gateway
|
||||
ret.radarUnavailable = False
|
||||
ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint[CanBus.OBSTACLE] and not use_off_car_defaults
|
||||
ret.pcmCruise = False # stock non-adaptive cruise control is kept off
|
||||
# supports stop and go, but initial engage must (conservatively) be above 18mph
|
||||
ret.minEnableSpeed = 18 * CV.MPH_TO_MS
|
||||
@@ -138,7 +100,8 @@ 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, CAR.EQUINOX}
|
||||
ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL, CAR.EQUINOX} 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.
|
||||
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
|
||||
@@ -149,6 +112,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
ret.steerLimitTimer = 0.4
|
||||
ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz
|
||||
ret.longitudinalActuatorDelayUpperBound = 0.5 # large delay to initially start braking
|
||||
|
||||
if candidate == CAR.VOLT:
|
||||
ret.mass = 1607. + STD_CARGO_KG
|
||||
@@ -184,7 +148,13 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerRatio = 14.4 # end to end is 13.46
|
||||
ret.centerToFront = ret.wheelbase * 0.4
|
||||
ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_acadia()
|
||||
ret.longitudinalActuatorDelayUpperBound = 0.5 # large delay to initially start braking
|
||||
|
||||
elif candidate == CAR.BUICK_LACROSSE:
|
||||
ret.mass = 1712. + STD_CARGO_KG
|
||||
ret.wheelbase = 2.91
|
||||
ret.steerRatio = 15.8
|
||||
ret.centerToFront = ret.wheelbase * 0.4 # wild guess
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
elif candidate == CAR.BUICK_REGAL:
|
||||
ret.mass = 3779. * CV.LB_TO_KG + STD_CARGO_KG # (3849+3708)/2
|
||||
@@ -223,7 +193,7 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.steerRatio = 16.8
|
||||
ret.centerToFront = ret.wheelbase * 0.4
|
||||
tire_stiffness_factor = 1.0
|
||||
ret.steerActuatorDelay = 0.12
|
||||
ret.steerActuatorDelay = 0.2
|
||||
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 = 15
|
||||
STEER_DRIVER_ALLOWANCE = 65
|
||||
STEER_DELTA_DOWN = 25
|
||||
STEER_DRIVER_ALLOWANCE = 50
|
||||
STEER_DRIVER_MULTIPLIER = 4
|
||||
STEER_DRIVER_FACTOR = 100
|
||||
NEAR_STOP_BRAKE_PHASE = 0.5 # m/s
|
||||
@@ -66,6 +66,7 @@ class CAR:
|
||||
CADILLAC_ATS = "CADILLAC ATS Premium Performance 2018"
|
||||
MALIBU = "CHEVROLET MALIBU PREMIER 2017"
|
||||
ACADIA = "GMC ACADIA DENALI 2018"
|
||||
BUICK_LACROSSE = "BUICK LACROSSE 2017"
|
||||
BUICK_REGAL = "BUICK REGAL ESSENCE 2018"
|
||||
ESCALADE = "CADILLAC ESCALADE 2017"
|
||||
ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016"
|
||||
@@ -99,6 +100,7 @@ CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = {
|
||||
CAR.CADILLAC_ATS: GMCarInfo("Cadillac ATS Premium Performance 2018"),
|
||||
CAR.MALIBU: GMCarInfo("Chevrolet Malibu Premier 2017"),
|
||||
CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"),
|
||||
CAR.BUICK_LACROSSE: GMCarInfo("Buick LaCrosse 2017-19", "Driver Confidence Package 2"),
|
||||
CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"),
|
||||
CAR.ESCALADE: GMCarInfo("Cadillac Escalade 2017", "Driver Assist Package"),
|
||||
CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"),
|
||||
@@ -151,6 +153,15 @@ FINGERPRINTS = {
|
||||
# Volt Premier w/ ACC 2018
|
||||
{
|
||||
170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 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, 578: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 715: 8, 717: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 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, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1516: 8, 1601: 8, 1618: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1930: 7, 2016: 8, 2018: 8, 2020: 8, 2024: 8, 2028: 8
|
||||
},
|
||||
# Volt Premier 2018 w/ flashed firmware, no radar
|
||||
{
|
||||
170: 8, 171: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 209: 7, 211: 2, 241: 6, 288: 5, 289: 1, 290: 1, 298: 2, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 368: 8, 381: 2, 384: 8, 386: 5, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 3, 508: 8, 512: 3, 528: 4, 530: 8, 532: 6, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 761: 7, 810: 8, 821: 4, 823: 7, 832: 8, 840: 5, 842: 5, 844: 8, 853: 8, 866: 4, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 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, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7
|
||||
}],
|
||||
CAR.BUICK_LACROSSE: [
|
||||
# LaCrosse Premium AWD 2017
|
||||
{
|
||||
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, 353: 3, 381: 6, 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, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 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, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 5, 707: 8, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 872: 1, 882: 8, 890: 1, 892: 2, 893: 1, 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, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 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, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1916: 7, 1918: 7, 1919: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8
|
||||
}],
|
||||
CAR.BUICK_REGAL : [
|
||||
# Regal TourX Essence w/ ACC 2018
|
||||
|
||||
@@ -186,7 +186,7 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
[StdQueries.UDS_VERSION_RESPONSE],
|
||||
bus=1,
|
||||
logging=True,
|
||||
non_obd=True,
|
||||
obd_multiplexing=False,
|
||||
),
|
||||
],
|
||||
extra_ecus=[
|
||||
@@ -368,10 +368,12 @@ FW_VERSIONS = {
|
||||
b'57114-TWA-A050\x00\x00',
|
||||
b'57114-TWA-A530\x00\x00',
|
||||
b'57114-TWA-B520\x00\x00',
|
||||
b'57114-TWB-H030\x00\x00',
|
||||
],
|
||||
(Ecu.srs, 0x18da53f1, None): [
|
||||
b'77959-TWA-A440\x00\x00',
|
||||
b'77959-TWA-L420\x00\x00',
|
||||
b'77959-TWB-H220\x00\x00',
|
||||
],
|
||||
(Ecu.combinationMeter, 0x18da60f1, None): [
|
||||
b'78109-TWA-A010\x00\x00',
|
||||
@@ -385,6 +387,7 @@ FW_VERSIONS = {
|
||||
b'78109-TWA-A230\x00\x00',
|
||||
b'78109-TWA-L010\x00\x00',
|
||||
b'78109-TWA-L210\x00\x00',
|
||||
b'78109-TWA-H210\x00\x00',
|
||||
],
|
||||
(Ecu.shiftByWire, 0x18da0bf1, None): [
|
||||
b'54008-TWA-A910\x00\x00',
|
||||
@@ -396,16 +399,19 @@ FW_VERSIONS = {
|
||||
(Ecu.fwdCamera, 0x18dab5f1, None): [
|
||||
b'36161-TWA-A070\x00\x00',
|
||||
b'36161-TWA-A330\x00\x00',
|
||||
b'36161-TWB-H040\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x18dab0f1, None): [
|
||||
b'36802-TWA-A070\x00\x00',
|
||||
b'36802-TWA-A080\x00\x00',
|
||||
b'36802-TWA-A330\x00\x00',
|
||||
b'36802-TWB-H060\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x18da30f1, None): [
|
||||
b'39990-TVA-A160\x00\x00',
|
||||
b'39990-TVA-A150\x00\x00',
|
||||
b'39990-TVA-A340\x00\x00',
|
||||
b'39990-TWB-H120\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.CIVIC: {
|
||||
|
||||
@@ -3,7 +3,7 @@ from common.conversions import Conversions as CV
|
||||
from common.numpy_fast import clip
|
||||
from common.realtime import DT_CTRL
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car import apply_driver_steer_torque_limits
|
||||
from selfdrive.car.hyundai import hyundaicanfd, hyundaican
|
||||
from selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR
|
||||
|
||||
@@ -60,7 +60,7 @@ class CarController:
|
||||
|
||||
# steering torque
|
||||
new_steer = int(round(actuators.steer * self.params.STEER_MAX))
|
||||
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
|
||||
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
|
||||
|
||||
if not CC.latActive:
|
||||
apply_steer = 0
|
||||
|
||||
@@ -224,7 +224,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
|
||||
HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control", "https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c),
|
||||
HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_e),
|
||||
],
|
||||
CAR.KIA_SORENTO_4TH_GEN: HyundaiCarInfo("Kia Sorento 2022-23", harness=Harness.hyundai_k),
|
||||
CAR.KIA_SORENTO_4TH_GEN: HyundaiCarInfo("Kia Sorento 2021-23", harness=Harness.hyundai_k),
|
||||
CAR.KIA_SORENTO_PHEV_4TH_GEN: HyundaiCarInfo("Kia Sorento Plug-in Hybrid 2022-23", harness=Harness.hyundai_a),
|
||||
CAR.KIA_SPORTAGE_HYBRID_5TH_GEN: HyundaiCarInfo("Kia Sportage Hybrid 2023", harness=Harness.hyundai_n),
|
||||
CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c),
|
||||
@@ -335,10 +335,15 @@ FINGERPRINTS = {
|
||||
|
||||
HYUNDAI_VERSION_REQUEST_LONG = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||
p16(0xf100) # Long description
|
||||
|
||||
HYUNDAI_VERSION_REQUEST_ALT = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||
p16(0xf110) # Alt long description
|
||||
|
||||
HYUNDAI_VERSION_REQUEST_MULTI = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
|
||||
p16(uds.DATA_IDENTIFIER_TYPE.VEHICLE_MANUFACTURER_SPARE_PART_NUMBER) + \
|
||||
p16(uds.DATA_IDENTIFIER_TYPE.APPLICATION_SOFTWARE_IDENTIFICATION) + \
|
||||
p16(0xf100)
|
||||
|
||||
HYUNDAI_VERSION_RESPONSE = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER + 0x40])
|
||||
|
||||
FW_QUERY_CONFIG = FwQueryConfig(
|
||||
@@ -355,22 +360,46 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.engine, Ecu.transmission, Ecu.eps, Ecu.abs, Ecu.fwdRadar],
|
||||
),
|
||||
# CAN-FD queries (camera)
|
||||
|
||||
# CAN-FD queries (from camera)
|
||||
# TODO: combine shared whitelists with CAN requests
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_LONG],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.fwdCamera, Ecu.fwdRadar, Ecu.cornerRadar],
|
||||
bus=4,
|
||||
whitelist_ecus=[Ecu.fwdCamera, Ecu.fwdRadar, Ecu.cornerRadar, Ecu.hvac],
|
||||
bus=0,
|
||||
auxiliary=True,
|
||||
),
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_LONG],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.fwdCamera, Ecu.adas, Ecu.cornerRadar],
|
||||
bus=5,
|
||||
whitelist_ecus=[Ecu.fwdCamera, Ecu.adas, Ecu.cornerRadar, Ecu.hvac],
|
||||
bus=1,
|
||||
auxiliary=True,
|
||||
obd_multiplexing=False,
|
||||
),
|
||||
|
||||
# CAN-FD debugging queries
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_ALT],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.parking],
|
||||
bus=0,
|
||||
auxiliary=True,
|
||||
),
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_ALT],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.parking],
|
||||
bus=1,
|
||||
auxiliary=True,
|
||||
obd_multiplexing=False,
|
||||
),
|
||||
],
|
||||
extra_ecus=[
|
||||
(Ecu.adas, 0x730, None), # ADAS Driving ECU on HDA2 platforms
|
||||
(Ecu.parking, 0x7b1, None), # ADAS Parking ECU (may exist on all platforms)
|
||||
(Ecu.hvac, 0x7b3, None), # HVAC Control Assembly
|
||||
(Ecu.cornerRadar, 0x7b7, None),
|
||||
],
|
||||
)
|
||||
@@ -512,7 +541,6 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00DN8_ SCC FHCUP 1.00 1.01 99110-L1000 ',
|
||||
b'\xf1\x00DN89110-L0000 \xaa\xaa\xaa\xaa\xaa\xaa\xaa ',
|
||||
b'\xf1\x8799110L0000\xf1\x00DN8_ SCC F-CUP 1.00 1.00 99110-L0000 ',
|
||||
b'\xf1\x8799110L0000\xf1\x00DN8_ SCC FHCUP 1.00 1.00 99110-L0000 ',
|
||||
],
|
||||
(Ecu.abs, 0x7d1, None): [
|
||||
b'\xf1\x00DN ESC \x07 106 \x07\x01 58910-L0100',
|
||||
@@ -525,7 +553,6 @@ FW_VERSIONS = {
|
||||
b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 104\x19\x08\x01 58910-L0100',
|
||||
b'\xf1\x8758910-L0100\xf1\x00DN ESC \x06 106 \x07\x01 58910-L0100',
|
||||
b'\xf1\x8758910-L0100\xf1\x00DN ESC \x07 104\x19\x08\x01 58910-L0100',
|
||||
b'\xf1\x8758910-L0300\xf1\x00DN ESC \x03 100 \x08\x01 58910-L0300',
|
||||
b'\xf1\x00DN ESC \x06 106 \x07\x01 58910-L0100',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
@@ -587,6 +614,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00HT6WA280BLHT6WAD10A1SDN8G25NB4\x00\x00\x00\x00\x00\x00g!l[',
|
||||
b'\xf1\x00T02601BL T02730A1 VDN8T25XXX730NS5\xf7_\x92\xf5',
|
||||
b'\xf1\x00T02601BL T02832A1 VDN8T25XXX832NS8G\x0e\xfeE',
|
||||
b'\xf1\x00T02601BL T02900A1 VDN8T25XXX900NSCF\xe4!Y',
|
||||
b'\xf1\x87954A02N060\x00\x00\x00\x00\x00\xf1\x81T02730A1 \xf1\x00T02601BL T02730A1 VDN8T25XXX730NS5\xf7_\x92\xf5',
|
||||
b'\xf1\x87SAKFBA2926554GJ2VefVww\x87xwwwww\x88\x87xww\x87wTo\xfb\xffvUo\xff\x8d\x16\xf1\x81U903\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U903\x00\x00\x00\x00\x00\x00SDN8T16NB0z{\xd4v',
|
||||
b'\xf1\x87SAKFBA3030524GJ2UVugww\x97yx\x88\x87\x88vw\x87gww\x87wto\xf9\xfffUo\xff\xa2\x0c\xf1\x81U903\x00\x00\x00\x00\x00\x00\xf1\x00bcsh8p54 U903\x00\x00\x00\x00\x00\x00SDN8T16NB0z{\xd4v',
|
||||
@@ -1553,6 +1581,8 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00CV1 MFC AT EUR LHD 1.00 1.06 99210-CV000 220328',
|
||||
b'\xf1\x00CV1 MFC AT EUR RHD 1.00 1.00 99210-CV100 220630',
|
||||
b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.00 99210-CV100 220630',
|
||||
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.04 99210-CV000 210823',
|
||||
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.06 99210-CV000 220328',
|
||||
],
|
||||
},
|
||||
CAR.IONIQ_5: {
|
||||
@@ -1563,9 +1593,11 @@ FW_VERSIONS = {
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.02 99211-GI010 211206',
|
||||
b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.06 99211-GI000 210813',
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.05 99211-GI010 220614',
|
||||
b'\xf1\x00NE1 MFC AT KOR LHD 1.00 1.05 99211-GI010 220614',
|
||||
b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.01 99211-GI010 211007',
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.01 99211-GI010 211007',
|
||||
b'\xf1\x00NE1 MFC AT EUR RHD 1.00 1.02 99211-GI010 211206',
|
||||
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.03 99211-GI010 220401',
|
||||
],
|
||||
},
|
||||
CAR.TUCSON_4TH_GEN: {
|
||||
@@ -1628,6 +1660,7 @@ FW_VERSIONS = {
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.02 99211-CU100 211215',
|
||||
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.02 99211-CU000 211215',
|
||||
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.03 99211-CU000 221118',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00JW1_ RDR ----- 1.00 1.00 99110-CU000 ',
|
||||
@@ -1636,14 +1669,17 @@ FW_VERSIONS = {
|
||||
CAR.KIA_SORENTO_4TH_GEN: {
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00MQ4 MFC AT USA LHD 1.00 1.05 99210-R5000 210623',
|
||||
b'\xf1\x00MQ4 MFC AT USA LHD 1.00 1.03 99210-R5000 200903',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00MQ4_ SCC FHCUP 1.00 1.06 99110-P2000 ',
|
||||
b'\xf1\x00MQ4_ SCC F-CUP 1.00 1.06 99110-P2000 ',
|
||||
],
|
||||
},
|
||||
CAR.KIA_NIRO_HEV_2ND_GEN: {
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00SG2HMFC AT USA LHD 1.01 1.08 99211-AT000 220531',
|
||||
b'\xf1\x00SG2HMFC AT USA LHD 1.01 1.09 99211-AT000 220801',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00SG2_ RDR ----- 1.00 1.01 99110-AT000 ',
|
||||
|
||||
@@ -18,7 +18,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, float, bool], float]
|
||||
TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, bool], float]
|
||||
|
||||
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
|
||||
ACCEL_MAX = 2.0
|
||||
@@ -131,7 +131,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, vego, friction_compensation):
|
||||
def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, 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),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from cereal import car
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car import apply_driver_steer_torque_limits
|
||||
from selfdrive.car.mazda import mazdacan
|
||||
from selfdrive.car.mazda.values import CarControllerParams, Buttons
|
||||
|
||||
@@ -23,8 +23,8 @@ class CarController:
|
||||
if CC.latActive:
|
||||
# calculate steer and also set limits due to driver torque
|
||||
new_steer = int(round(CC.actuators.steer * CarControllerParams.STEER_MAX))
|
||||
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last,
|
||||
CS.out.steeringTorque, CarControllerParams)
|
||||
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last,
|
||||
CS.out.steeringTorque, CarControllerParams)
|
||||
|
||||
if CC.cruiseControl.cancel:
|
||||
# If brake is pressed, let us wait >70ms before trying to disable crz to avoid
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from opendbc.can.packer import CANPacker
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car import apply_driver_steer_torque_limits
|
||||
from selfdrive.car.subaru import subarucan
|
||||
from selfdrive.car.subaru.values import DBC, GLOBAL_GEN2, PREGLOBAL_CARS, CarControllerParams
|
||||
|
||||
@@ -34,7 +34,7 @@ class CarController:
|
||||
# limits due to driver torque
|
||||
|
||||
new_steer = int(round(apply_steer))
|
||||
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.p)
|
||||
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.p)
|
||||
|
||||
if not CC.latActive:
|
||||
apply_steer = 0
|
||||
|
||||
@@ -273,9 +273,11 @@ FW_VERSIONS = {
|
||||
b'\xa3 \031\024\000',
|
||||
b'\xa3 \x14\x01',
|
||||
b'\xf1\x00\xbb\r\x05',
|
||||
b'\xa3 \x18&\x00',
|
||||
],
|
||||
(Ecu.eps, 0x746, None): [
|
||||
b'\x8d\xc0\x04\x00',
|
||||
b'\x8d\xc0\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x787, None): [
|
||||
b'\x00\x00e!\x1f@ \x11',
|
||||
@@ -292,6 +294,7 @@ FW_VERSIONS = {
|
||||
b'\xcb\"`p\a',
|
||||
b'\xf1\x00\xa2\x10\n',
|
||||
b'\xcf"`p\x07',
|
||||
b'\xb6\xa2`A\x07',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\032\xf6B0\000',
|
||||
@@ -299,6 +302,7 @@ FW_VERSIONS = {
|
||||
b'\032\xf6b`\000',
|
||||
b'\x1a\xf6B`\x00',
|
||||
b'\x1a\xf6b0\x00',
|
||||
b'\x1a\xe6B1\x00',
|
||||
],
|
||||
},
|
||||
CAR.FORESTER_PREGLOBAL: {
|
||||
|
||||
@@ -27,6 +27,8 @@ non_tested_cars = [
|
||||
HYUNDAI.KIA_OPTIMA_H,
|
||||
HONDA.ODYSSEY_CHN,
|
||||
VOLKSWAGEN.CRAFTER_MK2, # need a route from an ACC-equipped Crafter
|
||||
TOYOTA.RAV4_TSS2_2023,
|
||||
TOYOTA.RAV4H_TSS2_2023,
|
||||
]
|
||||
|
||||
CarTestRoute = namedtuple('CarTestRoute', ['route', 'car_model', 'segment'], defaults=(None,))
|
||||
@@ -50,6 +52,7 @@ routes = [
|
||||
|
||||
CarTestRoute("7cc2a8365b4dd8a9|2018-12-02--12-10-44", GM.ACADIA),
|
||||
CarTestRoute("aa20e335f61ba898|2019-02-05--16-59-04", GM.BUICK_REGAL),
|
||||
CarTestRoute("75a6bcb9b8b40373|2023-03-11--22-47-33", GM.BUICK_LACROSSE),
|
||||
CarTestRoute("ef8f2185104d862e|2023-02-09--18-37-13", GM.ESCALADE),
|
||||
CarTestRoute("46460f0da08e621e|2021-10-26--07-21-46", GM.ESCALADE_ESV),
|
||||
CarTestRoute("c950e28c26b5b168|2018-05-30--22-03-41", GM.VOLT),
|
||||
@@ -207,6 +210,7 @@ routes = [
|
||||
CarTestRoute("0cd0b7f7e31a3853|2021-12-03--03-12-05", VOLKSWAGEN.AUDI_Q3_MK2),
|
||||
CarTestRoute("8f205bdd11bcbb65|2021-03-26--01-00-17", VOLKSWAGEN.SEAT_ATECA_MK1),
|
||||
CarTestRoute("fc6b6c9a3471c846|2021-05-27--13-39-56", VOLKSWAGEN.SEAT_LEON_MK3),
|
||||
CarTestRoute("0bbe367c98fa1538|2023-03-04--17-46-11", VOLKSWAGEN.SKODA_FABIA_MK4),
|
||||
CarTestRoute("12d6ae3057c04b0d|2021-09-15--00-04-07", VOLKSWAGEN.SKODA_KAMIQ_MK1),
|
||||
CarTestRoute("12d6ae3057c04b0d|2021-09-04--21-21-21", VOLKSWAGEN.SKODA_KAROQ_MK1),
|
||||
CarTestRoute("90434ff5d7c8d603|2021-03-15--12-07-31", VOLKSWAGEN.SKODA_KODIAQ_MK1),
|
||||
|
||||
@@ -10,7 +10,6 @@ from common.realtime import DT_CTRL
|
||||
from selfdrive.car.car_helpers import interfaces
|
||||
from selfdrive.car.fingerprints import all_known_cars
|
||||
from selfdrive.car.interfaces import get_torque_params
|
||||
from selfdrive.car.hyundai.values import CAR as HYUNDAI
|
||||
|
||||
CAR_MODELS = all_known_cars()
|
||||
|
||||
@@ -22,14 +21,6 @@ MAX_LAT_ACCEL = 3.0 # m/s^2
|
||||
# jerk is measured over half a second
|
||||
JERK_MEAS_FRAMES = 0.5 / DT_CTRL
|
||||
|
||||
# TODO: update the max measured lateral accel for these cars
|
||||
ABOVE_LIMITS_CARS = [
|
||||
HYUNDAI.KONA_EV,
|
||||
HYUNDAI.KONA_HEV,
|
||||
HYUNDAI.KONA,
|
||||
HYUNDAI.KONA_EV_2022,
|
||||
]
|
||||
|
||||
car_model_jerks: DefaultDict[str, Dict[str, float]] = defaultdict(dict)
|
||||
|
||||
|
||||
@@ -52,9 +43,6 @@ class TestLateralLimits(unittest.TestCase):
|
||||
if CP.notCar:
|
||||
raise unittest.SkipTest
|
||||
|
||||
if CP.carFingerprint in ABOVE_LIMITS_CARS:
|
||||
raise unittest.SkipTest
|
||||
|
||||
CarControllerParams = importlib.import_module(f'selfdrive.car.{CP.carName}.values').CarControllerParams
|
||||
cls.control_params = CarControllerParams(CP)
|
||||
cls.torque_params = get_torque_params(cls.car_model)
|
||||
|
||||
@@ -7,6 +7,10 @@ NISSAN LEAF 2018 Instrument Cluster: [.nan, 1.5, .nan]
|
||||
NISSAN LEAF 2018: [.nan, 1.5, .nan]
|
||||
NISSAN ROGUE 2019: [.nan, 1.5, .nan]
|
||||
|
||||
# Toyota LTA also has torque
|
||||
TOYOTA RAV4 2023: [.nan, 3.0, .nan]
|
||||
TOYOTA RAV4 HYBRID 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]
|
||||
|
||||
@@ -30,7 +30,7 @@ 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, 3.2961956260770484, 0.12359762054065548]
|
||||
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]
|
||||
|
||||
@@ -50,12 +50,14 @@ 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from cereal import car
|
||||
from common.numpy_fast import clip, interp
|
||||
from selfdrive.car import apply_toyota_steer_torque_limits, create_gas_interceptor_command, make_can_msg
|
||||
from selfdrive.car import apply_meas_steer_torque_limits, create_gas_interceptor_command, make_can_msg
|
||||
from selfdrive.car.toyota.toyotacan import create_steer_command, create_ui_command, \
|
||||
create_accel_command, create_acc_cancel_command, \
|
||||
create_fcw_command, create_lta_steer_command
|
||||
@@ -60,7 +60,7 @@ class CarController:
|
||||
|
||||
# steer torque
|
||||
new_steer = int(round(actuators.steer * CarControllerParams.STEER_MAX))
|
||||
apply_steer = apply_toyota_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.torque_rate_limits)
|
||||
apply_steer = apply_meas_steer_torque_limits(new_steer, self.last_steer, CS.out.steeringTorqueEps, self.torque_rate_limits)
|
||||
|
||||
# Count up to MAX_STEER_RATE_FRAMES, at which point we need to cut torque to avoid a steering fault
|
||||
if lat_active and abs(CS.out.steeringRateDeg) >= MAX_STEER_RATE:
|
||||
@@ -76,6 +76,11 @@ class CarController:
|
||||
apply_steer_req = 0
|
||||
self.steer_rate_counter = 0
|
||||
|
||||
# Never actuate with LKA on cars that only support LTA
|
||||
if self.CP.steerControlType == car.CarParams.SteerControlType.angle:
|
||||
apply_steer = 0
|
||||
apply_steer_req = 0
|
||||
|
||||
# TODO: probably can delete this. CS.pcm_acc_status uses a different signal
|
||||
# than CS.cruiseState.enabled. confirm they're not meaningfully different
|
||||
if not CC.enabled and CS.pcm_acc_status:
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
from cereal import car
|
||||
from common.conversions import Conversions as CV
|
||||
from panda import Panda
|
||||
from selfdrive.car.toyota.values import Ecu, CAR, ToyotaFlags, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, UNSUPPORTED_DSU_CAR, CarControllerParams, NO_STOP_TIMER_CAR
|
||||
from selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
|
||||
MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR
|
||||
from selfdrive.car import STD_CARGO_KG, scale_tire_stiffness, get_safety_config
|
||||
from selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
@@ -20,16 +21,22 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)]
|
||||
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
|
||||
|
||||
if candidate in (CAR.RAV4, CAR.PRIUS_V, CAR.COROLLA, CAR.LEXUS_ESH, CAR.LEXUS_CTH):
|
||||
# BRAKE_MODULE is on a different address for these cars
|
||||
if DBC[candidate]["pt"] == "toyota_new_mc_pt_generated":
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_ALT_BRAKE
|
||||
|
||||
if candidate in ANGLE_CONTROL_CAR:
|
||||
ret.dashcamOnly = True
|
||||
ret.steerControlType = car.CarParams.SteerControlType.angle
|
||||
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_LTA
|
||||
else:
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
|
||||
|
||||
ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay
|
||||
ret.steerLimitTimer = 0.4
|
||||
ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop
|
||||
|
||||
stop_and_go = False
|
||||
steering_angle_deadzone_deg = 0.0
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, steering_angle_deadzone_deg)
|
||||
|
||||
if candidate == CAR.PRIUS:
|
||||
stop_and_go = True
|
||||
@@ -40,9 +47,8 @@ class CarInterface(CarInterfaceBase):
|
||||
# Only give steer angle deadzone to for bad angle sensor prius
|
||||
for fw in car_fw:
|
||||
if fw.ecu == "eps" and not fw.fwVersion == b'8965B47060\x00\x00\x00\x00\x00\x00':
|
||||
steering_angle_deadzone_deg = 0.2
|
||||
ret.steerActuatorDelay = 0.25
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, steering_angle_deadzone_deg)
|
||||
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, steering_angle_deadzone_deg=0.2)
|
||||
|
||||
elif candidate == CAR.PRIUS_V:
|
||||
stop_and_go = True
|
||||
@@ -102,7 +108,8 @@ class CarInterface(CarInterfaceBase):
|
||||
tire_stiffness_factor = 0.7983
|
||||
ret.mass = 3505. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid
|
||||
|
||||
elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022):
|
||||
elif candidate in (CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022,
|
||||
CAR.RAV4_TSS2_2023, CAR.RAV4H_TSS2_2023):
|
||||
stop_and_go = True
|
||||
ret.wheelbase = 2.68986
|
||||
ret.steerRatio = 14.3
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
|
||||
from selfdrive.car.toyota.values import TSS2_CAR, ANGLE_CONTROL_CAR
|
||||
|
||||
|
||||
class TestToyotaInterfaces(unittest.TestCase):
|
||||
def test_angle_car_set(self):
|
||||
self.assertTrue(len(ANGLE_CONTROL_CAR - TSS2_CAR) == 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -17,7 +17,7 @@ def create_lta_steer_command(packer, steer, steer_req, raw_cnt):
|
||||
"SETME_X1": 1,
|
||||
"SETME_X3": 3,
|
||||
"PERCENTAGE": 100,
|
||||
"SETME_X64": 0x64,
|
||||
"SETME_X64": 0,
|
||||
"ANGLE": 0,
|
||||
"STEER_ANGLE_CMD": steer,
|
||||
"STEER_REQUEST": steer_req,
|
||||
|
||||
@@ -67,8 +67,10 @@ class CAR:
|
||||
RAV4H = "TOYOTA RAV4 HYBRID 2017"
|
||||
RAV4_TSS2 = "TOYOTA RAV4 2019"
|
||||
RAV4_TSS2_2022 = "TOYOTA RAV4 2022"
|
||||
RAV4_TSS2_2023 = "TOYOTA RAV4 2023"
|
||||
RAV4H_TSS2 = "TOYOTA RAV4 HYBRID 2019"
|
||||
RAV4H_TSS2_2022 = "TOYOTA RAV4 HYBRID 2022"
|
||||
RAV4H_TSS2_2023 = "TOYOTA RAV4 HYBRID 2023"
|
||||
MIRAI = "TOYOTA MIRAI 2021" # TSS 2.5
|
||||
SIENNA = "TOYOTA SIENNA 2018"
|
||||
|
||||
@@ -115,11 +117,11 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
|
||||
CAR.AVALONH_TSS2: ToyotaCarInfo("Toyota Avalon Hybrid 2022"),
|
||||
CAR.CAMRY: ToyotaCarInfo("Toyota Camry 2018-20", video_link="https://www.youtube.com/watch?v=fkcjviZY9CM", footnotes=[Footnote.CAMRY]),
|
||||
CAR.CAMRYH: ToyotaCarInfo("Toyota Camry Hybrid 2018-20", video_link="https://www.youtube.com/watch?v=Q2DYY0AWKgk"),
|
||||
CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-22", footnotes=[Footnote.CAMRY]),
|
||||
CAR.CAMRY_TSS2: ToyotaCarInfo("Toyota Camry 2021-23", footnotes=[Footnote.CAMRY]),
|
||||
CAR.CAMRYH_TSS2: ToyotaCarInfo("Toyota Camry Hybrid 2021-23"),
|
||||
CAR.CHR: ToyotaCarInfo("Toyota C-HR 2017-20"),
|
||||
CAR.CHR_TSS2: ToyotaCarInfo("Toyota C-HR 2021"),
|
||||
CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-19"),
|
||||
CAR.CHRH: ToyotaCarInfo("Toyota C-HR Hybrid 2017-20"),
|
||||
CAR.CHRH_TSS2: ToyotaCarInfo("Toyota C-HR Hybrid 2021-22"),
|
||||
CAR.COROLLA: ToyotaCarInfo("Toyota Corolla 2017-19"),
|
||||
CAR.COROLLA_TSS2: [
|
||||
@@ -157,14 +159,16 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
|
||||
],
|
||||
CAR.RAV4_TSS2: ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"),
|
||||
CAR.RAV4_TSS2_2022: ToyotaCarInfo("Toyota RAV4 2022"),
|
||||
CAR.RAV4_TSS2_2023: ToyotaCarInfo("Toyota RAV4 2023"),
|
||||
CAR.RAV4H_TSS2: ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"),
|
||||
CAR.RAV4H_TSS2_2022: ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"),
|
||||
CAR.RAV4H_TSS2_2023: ToyotaCarInfo("Toyota RAV4 Hybrid 2023"),
|
||||
CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"),
|
||||
CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", min_enable_speed=MIN_ACC_SPEED),
|
||||
|
||||
# Lexus
|
||||
CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+"),
|
||||
CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18", "Lexus Safety System+"),
|
||||
CAR.LEXUS_ESH: ToyotaCarInfo("Lexus ES Hybrid 2017-18"),
|
||||
CAR.LEXUS_ES_TSS2: ToyotaCarInfo("Lexus ES 2019-22"),
|
||||
CAR.LEXUS_ESH_TSS2: ToyotaCarInfo("Lexus ES Hybrid 2019-23", video_link="https://youtu.be/BZ29osRVJeg?t=12"),
|
||||
CAR.LEXUS_IS: ToyotaCarInfo("Lexus IS 2017-19"),
|
||||
@@ -172,7 +176,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
|
||||
CAR.LEXUS_NXH: ToyotaCarInfo("Lexus NX Hybrid 2018-19"),
|
||||
CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"),
|
||||
CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 2020-21"),
|
||||
CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2017-20"),
|
||||
CAR.LEXUS_RC: ToyotaCarInfo("Lexus RC 2018-20"),
|
||||
CAR.LEXUS_RX: [
|
||||
ToyotaCarInfo("Lexus RX 2016", "Lexus Safety System+"),
|
||||
ToyotaCarInfo("Lexus RX 2017-19"),
|
||||
@@ -527,14 +531,18 @@ FW_VERSIONS = {
|
||||
CAR.CAMRY_TSS2: {
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'8965B33630\x00\x00\x00\x00\x00\x00',
|
||||
b'8965B33640\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'\x01F152606370\x00\x00\x00\x00\x00\x00',
|
||||
b'\x01F152606390\x00\x00\x00\x00\x00\x00',
|
||||
b'\x01F152606400\x00\x00\x00\x00\x00\x00',
|
||||
b'\x01F152606431\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x018966306Q5000\x00\x00\x00\x00',
|
||||
b'\x018966306Q9000\x00\x00\x00\x00',
|
||||
b'\x018966306R3000\x00\x00\x00\x00',
|
||||
b'\x018966306T3100\x00\x00\x00\x00',
|
||||
b'\x018966306T3200\x00\x00\x00\x00',
|
||||
b'\x018966306T4000\x00\x00\x00\x00',
|
||||
@@ -542,12 +550,15 @@ FW_VERSIONS = {
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F6201200\x00\x00\x00\x00',
|
||||
b'\x018821F6201300\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F0602100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
|
||||
b'\x028646F0602200\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
|
||||
b'\x028646F3305200\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
|
||||
b'\x028646F3305200\x00\x00\x00\x008646G3304000\x00\x00\x00\x00',
|
||||
b'\x028646F3305300\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
|
||||
b'\x028646F3305500\x00\x00\x00\x008646G3304000\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.CAMRYH_TSS2: {
|
||||
@@ -712,6 +723,7 @@ FW_VERSIONS = {
|
||||
b'8646FF404000 ',
|
||||
b'8646FF406000 ',
|
||||
b'8646FF407000 ',
|
||||
b'8646FF407100 ',
|
||||
],
|
||||
},
|
||||
CAR.CHRH_TSS2: {
|
||||
@@ -1453,6 +1465,23 @@ FW_VERSIONS = {
|
||||
b'\x028646F0R02100\x00\x00\x00\x008646G0R01100\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.RAV4_TSS2_2023: {
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'\x01F15260R450\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'\x028965B0R11000\x00\x00\x00\x008965B0R12000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x01896634AJ2000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F0R03100\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F0R05100\x00\x00\x00\x008646G0R02100\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.RAV4H_TSS2: {
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x01896634A15000\x00\x00\x00\x00',
|
||||
@@ -1540,6 +1569,23 @@ FW_VERSIONS = {
|
||||
b'\x028646F0R02100\x00\x00\x00\x008646G0R01100\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.RAV4H_TSS2_2023: {
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'\x01F15264283200\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.eps, 0x7a1, None): [
|
||||
b'\x028965B0R11000\x00\x00\x00\x008965B0R12000\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x01896634AE1001\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F0R03100\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F0R05100\x00\x00\x00\x008646G0R02100\x00\x00\x00\x00',
|
||||
],
|
||||
},
|
||||
CAR.SIENNA: {
|
||||
(Ecu.engine, 0x700, None): [
|
||||
b'\x01896630832100\x00\x00\x00\x00',
|
||||
@@ -1636,6 +1682,7 @@ FW_VERSIONS = {
|
||||
b'\x028966333S8000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00',
|
||||
b'\x028966333T0100\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00',
|
||||
b'\x028966333V4000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00',
|
||||
b'\x028966333W1000\x00\x00\x00\x00897CF3305001\x00\x00\x00\x00',
|
||||
b'\x02896633T09000\x00\x00\x00\x00897CF3307001\x00\x00\x00\x00',
|
||||
b'\x01896633T38000\x00\x00\x00\x00',
|
||||
b'\x01896633T58000\x00\x00\x00\x00',
|
||||
@@ -1727,6 +1774,7 @@ FW_VERSIONS = {
|
||||
b'\x018966378B2100\x00\x00\x00\x00',
|
||||
b'\x018966378B3000\x00\x00\x00\x00',
|
||||
b'\x018966378B4100\x00\x00\x00\x00',
|
||||
b'\x018966378G2000\x00\x00\x00\x00',
|
||||
b'\x018966378G3000\x00\x00\x00\x00',
|
||||
b'\x018966378B2000\x00\x00\x00\x00',
|
||||
],
|
||||
@@ -1749,6 +1797,7 @@ FW_VERSIONS = {
|
||||
CAR.LEXUS_NXH_TSS2: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\x0237887000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
b'\x02378A0000\x00\x00\x00\x00\x00\x00\x00\x00A4701000\x00\x00\x00\x00\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.abs, 0x7b0, None): [
|
||||
b'F152678210\x00\x00\x00\x00\x00\x00',
|
||||
@@ -1758,6 +1807,7 @@ FW_VERSIONS = {
|
||||
],
|
||||
(Ecu.fwdRadar, 0x750, 0xf): [
|
||||
b'\x018821F3301400\x00\x00\x00\x00',
|
||||
b'\x018821F3301300\x00\x00\x00\x00',
|
||||
],
|
||||
(Ecu.fwdCamera, 0x750, 0x6d): [
|
||||
b'\x028646F78030A0\x00\x00\x00\x008646G2601200\x00\x00\x00\x00',
|
||||
@@ -2094,6 +2144,7 @@ DBC = {
|
||||
CAR.AVALONH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.RAV4_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.RAV4_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.RAV4_TSS2_2023: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.COROLLA_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.COROLLAH_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.LEXUS_ES_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
@@ -2104,6 +2155,7 @@ DBC = {
|
||||
CAR.LEXUS_CTH: dbc_dict('toyota_new_mc_pt_generated', 'toyota_adas'),
|
||||
CAR.RAV4H_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
CAR.RAV4H_TSS2_2022: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.RAV4H_TSS2_2023: dbc_dict('toyota_nodsu_pt_generated', None),
|
||||
CAR.LEXUS_NXH: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_NX: dbc_dict('toyota_tnga_k_pt_generated', 'toyota_adas'),
|
||||
CAR.LEXUS_NX_TSS2: dbc_dict('toyota_nodsu_pt_generated', 'toyota_tss2_adas'),
|
||||
@@ -2118,8 +2170,8 @@ DBC = {
|
||||
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})
|
||||
|
||||
# Toyota/Lexus Safety Sense 2.0 and 2.5
|
||||
TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022,
|
||||
CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2,
|
||||
TSS2_CAR = {CAR.RAV4_TSS2, CAR.RAV4_TSS2_2022, CAR.RAV4_TSS2_2023, CAR.COROLLA_TSS2, CAR.COROLLAH_TSS2, CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022,
|
||||
CAR.RAV4H_TSS2_2023, CAR.LEXUS_RX_TSS2, CAR.LEXUS_RXH_TSS2, CAR.HIGHLANDER_TSS2, CAR.HIGHLANDERH_TSS2, CAR.PRIUS_TSS2, CAR.CAMRY_TSS2, CAR.CAMRYH_TSS2,
|
||||
CAR.MIRAI, CAR.LEXUS_NX_TSS2, CAR.LEXUS_NXH_TSS2, CAR.ALPHARD_TSS2, CAR.AVALON_TSS2, CAR.AVALONH_TSS2, CAR.ALPHARDH_TSS2, CAR.CHR_TSS2, CAR.CHRH_TSS2}
|
||||
|
||||
NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH}
|
||||
@@ -2128,10 +2180,13 @@ NO_DSU_CAR = TSS2_CAR | {CAR.CHR, CAR.CHRH, CAR.CAMRY, CAR.CAMRYH}
|
||||
UNSUPPORTED_DSU_CAR = {CAR.LEXUS_IS, CAR.LEXUS_RC}
|
||||
|
||||
# these cars have a radar which sends ACC messages instead of the camera
|
||||
RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.CHR_TSS2, CAR.CHRH_TSS2}
|
||||
RADAR_ACC_CAR = {CAR.RAV4H_TSS2_2022, CAR.RAV4_TSS2_2022, CAR.RAV4H_TSS2_2023, CAR.RAV4_TSS2_2023, CAR.CHR_TSS2, CAR.CHRH_TSS2}
|
||||
|
||||
# these cars use the Lane Tracing Assist (LTA) message for lateral control
|
||||
ANGLE_CONTROL_CAR = {CAR.RAV4H_TSS2_2023, CAR.RAV4_TSS2_2023}
|
||||
|
||||
EV_HYBRID_CAR = {CAR.AVALONH_2019, CAR.AVALONH_TSS2, CAR.CAMRYH, CAR.CAMRYH_TSS2, CAR.CHRH, CAR.CHRH_TSS2, CAR.COROLLAH_TSS2, CAR.HIGHLANDERH, CAR.HIGHLANDERH_TSS2, CAR.PRIUS,
|
||||
CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH,
|
||||
CAR.PRIUS_V, CAR.RAV4H, CAR.RAV4H_TSS2, CAR.RAV4H_TSS2_2022, CAR.RAV4H_TSS2_2023, CAR.LEXUS_CTH, CAR.MIRAI, CAR.LEXUS_ESH, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_NXH, CAR.LEXUS_RXH,
|
||||
CAR.LEXUS_RXH_TSS2, CAR.LEXUS_NXH_TSS2, CAR.PRIUS_TSS2, CAR.ALPHARDH_TSS2}
|
||||
|
||||
# no resume button press required
|
||||
|
||||
@@ -3,7 +3,7 @@ from opendbc.can.packer import CANPacker
|
||||
from common.numpy_fast import clip
|
||||
from common.conversions import Conversions as CV
|
||||
from common.realtime import DT_CTRL
|
||||
from selfdrive.car import apply_std_steer_torque_limits
|
||||
from selfdrive.car import apply_driver_steer_torque_limits
|
||||
from selfdrive.car.volkswagen import mqbcan, pqcan
|
||||
from selfdrive.car.volkswagen.values import CANBUS, PQ_CARS, CarControllerParams
|
||||
|
||||
@@ -44,7 +44,7 @@ class CarController:
|
||||
|
||||
if CC.latActive:
|
||||
new_steer = int(round(actuators.steer * self.CCP.STEER_MAX))
|
||||
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP)
|
||||
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP)
|
||||
if apply_steer == 0:
|
||||
hcaEnabled = False
|
||||
self.hcaEnabledFrameCount = 0
|
||||
|
||||
@@ -228,13 +228,13 @@ class CarState(CarStateBase):
|
||||
ret.cruiseState.available = bool(pt_cp.vl["Motor_5"]["GRA_Hauptschalter"])
|
||||
ret.cruiseState.enabled = pt_cp.vl["Motor_2"]["GRA_Status"] in (1, 2)
|
||||
if self.CP.pcmCruise:
|
||||
ret.accFaulted = ext_cp.vl["ACC_GRA_Anziege"]["ACA_StaACC"] in (6, 7)
|
||||
ret.accFaulted = ext_cp.vl["ACC_GRA_Anzeige"]["ACA_StaACC"] in (6, 7)
|
||||
else:
|
||||
ret.accFaulted = pt_cp.vl["Motor_2"]["GRA_Status"] == 3
|
||||
|
||||
# Update ACC setpoint. When the setpoint reads as 255, the driver has not
|
||||
# yet established an ACC setpoint, so treat it as zero.
|
||||
ret.cruiseState.speed = ext_cp.vl["ACC_GRA_Anziege"]["ACA_V_Wunsch"] * CV.KPH_TO_MS
|
||||
ret.cruiseState.speed = ext_cp.vl["ACC_GRA_Anzeige"]["ACA_V_Wunsch"] * CV.KPH_TO_MS
|
||||
if ret.cruiseState.speed > 70: # 255 kph in m/s == no current setpoint
|
||||
ret.cruiseState.speed = 0
|
||||
|
||||
@@ -516,12 +516,12 @@ class PqExtraSignals:
|
||||
# Additional signal and message lists for optional or bus-portable controllers
|
||||
fwd_radar_signals = [
|
||||
("ACS_Typ_ACC", "ACC_System"), # Basic vs FtS (no SnG support on PQ)
|
||||
("ACA_StaACC", "ACC_GRA_Anziege"), # ACC drivetrain coordinator status
|
||||
("ACA_V_Wunsch", "ACC_GRA_Anziege"), # ACC set speed
|
||||
("ACA_StaACC", "ACC_GRA_Anzeige"), # ACC drivetrain coordinator status
|
||||
("ACA_V_Wunsch", "ACC_GRA_Anzeige"), # ACC set speed
|
||||
]
|
||||
fwd_radar_checks = [
|
||||
("ACC_System", 50), # From J428 ACC radar control module
|
||||
("ACC_GRA_Anziege", 25), # From J428 ACC radar control module
|
||||
("ACC_GRA_Anzeige", 25), # From J428 ACC radar control module
|
||||
]
|
||||
bsm_radar_signals = [
|
||||
("SWA_Infostufe_SWA_li", "SWA_1"), # Blind spot object info, left
|
||||
|
||||
@@ -187,6 +187,10 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.mass = 1227 + STD_CARGO_KG
|
||||
ret.wheelbase = 2.64
|
||||
|
||||
elif candidate == CAR.SKODA_FABIA_MK4:
|
||||
ret.mass = 1266 + STD_CARGO_KG
|
||||
ret.wheelbase = 2.56
|
||||
|
||||
elif candidate == CAR.SKODA_KAMIQ_MK1:
|
||||
ret.mass = 1265 + STD_CARGO_KG
|
||||
ret.wheelbase = 2.66
|
||||
|
||||
@@ -88,4 +88,4 @@ def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, lead_distance
|
||||
# kmh_mph handling probably needed to resolve rounding errors in displayed setpoint
|
||||
}
|
||||
|
||||
return packer.make_can_msg("ACC_GRA_Anziege", bus, values)
|
||||
return packer.make_can_msg("ACC_GRA_Anzeige", bus, values)
|
||||
|
||||
@@ -36,7 +36,7 @@ class CarControllerParams:
|
||||
|
||||
if CP.carFingerprint in PQ_CARS:
|
||||
self.LDW_STEP = 5 # LDW_1 message frequency 20Hz
|
||||
self.ACC_HUD_STEP = 4 # ACC_GRA_Anziege frequency 25Hz
|
||||
self.ACC_HUD_STEP = 4 # ACC_GRA_Anzeige frequency 25Hz
|
||||
self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm
|
||||
self.STEER_DELTA_UP = 6 # Max HCA reached in 1.00s (STEER_MAX / (50Hz * 1.00))
|
||||
self.STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60))
|
||||
@@ -129,6 +129,7 @@ class CAR:
|
||||
AUDI_Q3_MK2 = "AUDI Q3 2ND GEN" # Chassis 8U/F3/FS, Mk2 Audi Q3 and variants
|
||||
SEAT_ATECA_MK1 = "SEAT ATECA 1ST GEN" # Chassis 5F, Mk1 SEAT Ateca and CUPRA Ateca
|
||||
SEAT_LEON_MK3 = "SEAT LEON 3RD GEN" # Chassis 5F, Mk3 SEAT Leon and variants
|
||||
SKODA_FABIA_MK4 = "SKODA FABIA 4TH GEN" # Chassis PJ, Mk4 Skoda Fabia
|
||||
SKODA_KAMIQ_MK1 = "SKODA KAMIQ 1ST GEN" # Chassis NW, Mk1 Skoda Kamiq
|
||||
SKODA_KAROQ_MK1 = "SKODA KAROQ 1ST GEN" # Chassis NU, Mk1 Skoda Karoq
|
||||
SKODA_KODIAQ_MK1 = "SKODA KODIAQ 1ST GEN" # Chassis NS, Mk1 Skoda Kodiaq
|
||||
@@ -239,9 +240,10 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
|
||||
CAR.AUDI_Q3_MK2: VWCarInfo("Audi Q3 2019-23"),
|
||||
CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"),
|
||||
CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"),
|
||||
CAR.SKODA_FABIA_MK4: VWCarInfo("Škoda Fabia 2022-23", footnotes=[Footnote.VW_MQB_A0]),
|
||||
CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.VW_MQB_A0, Footnote.KAMIQ]),
|
||||
CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21"),
|
||||
CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"),
|
||||
CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2017-23"),
|
||||
CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020", footnotes=[Footnote.VW_MQB_A0]),
|
||||
CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-22"),
|
||||
CAR.SKODA_OCTAVIA_MK3: [
|
||||
@@ -291,6 +293,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x873G0906259N \xf1\x890004',
|
||||
b'\xf1\x873G0906259P \xf1\x890001',
|
||||
b'\xf1\x875NA907115H \xf1\x890002',
|
||||
b'\xf1\x873G0906259G \xf1\x890004',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x8709G927158L \xf1\x893611',
|
||||
@@ -302,17 +305,19 @@ FW_VERSIONS = {
|
||||
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e1616001613121157161111572900',
|
||||
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e1616001613121177161113772900',
|
||||
b'\xf1\x873Q0959655DL\xf1\x890732\xf1\x82\0161812141812171105141123052J00',
|
||||
b'\xf1\x873Q0959655CK\xf1\x890711\xf1\x82\x0e1712141712141105121122052900',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571B41815A1',
|
||||
b'\xf1\x873Q0909144L \xf1\x895081\xf1\x82\x0571B00817A1',
|
||||
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\00567B0020800',
|
||||
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567B0020800',
|
||||
b'\xf1\x875WA907145M \xf1\x891051\xf1\x82\x002MB4092M7N',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x872Q0907572AA\xf1\x890396',
|
||||
b'\xf1\x872Q0907572T \xf1\x890383',
|
||||
b'\xf1\x875Q0907572J \xf1\x890654',
|
||||
b'\xf1\x875Q0907572R \xf1\x890771',
|
||||
],
|
||||
},
|
||||
CAR.ATLAS_MK1: {
|
||||
@@ -392,6 +397,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x8704L906021DT\xf1\x895520',
|
||||
b'\xf1\x8704L906021DT\xf1\x898127',
|
||||
b'\xf1\x8704L906021N \xf1\x895518',
|
||||
b'\xf1\x8704L906026BN\xf1\x891197',
|
||||
b'\xf1\x8704L906026BP\xf1\x897608',
|
||||
b'\xf1\x8704L906026NF\xf1\x899528',
|
||||
b'\xf1\x8704L906056CL\xf1\x893823',
|
||||
@@ -512,6 +518,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x875Q0909144P \xf1\x891043\xf1\x82\x0511A00403A0',
|
||||
b'\xf1\x875Q0909144R \xf1\x891061\xf1\x82\x0516A00604A1',
|
||||
b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\x0516A00404A1',
|
||||
b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\x0516A00504A1',
|
||||
b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\x0516A00604A1',
|
||||
b'\xf1\x875Q0909144S \xf1\x891063\xf1\x82\x0516A07A02A1',
|
||||
b'\xf1\x875Q0909144T \xf1\x891072\xf1\x82\x0521A00507A1',
|
||||
@@ -739,12 +746,14 @@ FW_VERSIONS = {
|
||||
b'\xf1\x8783A907115B \xf1\x890005',
|
||||
b'\xf1\x8783A907115F \xf1\x890002',
|
||||
b'\xf1\x8783A907115G \xf1\x890001',
|
||||
b'\xf1\x8783A907115K \xf1\x890001',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x8709G927158DT\xf1\x893698',
|
||||
b'\xf1\x8709G927158FM\xf1\x893757',
|
||||
b'\xf1\x8709G927158GC\xf1\x893821',
|
||||
b'\xf1\x8709G927158GD\xf1\x893820',
|
||||
b'\xf1\x8709G927158GM\xf1\x893936',
|
||||
b'\xf1\x870D9300043 \xf1\x895202',
|
||||
b'\xf1\x870DL300011N \xf1\x892001',
|
||||
b'\xf1\x870DL300011N \xf1\x892012',
|
||||
@@ -775,6 +784,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x875QM909144B \xf1\x891081\xf1\x82\x0521A60604A1',
|
||||
b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\x0521A60604A1',
|
||||
b'\xf1\x875QM909144C \xf1\x891082\xf1\x82\00521A60804A1',
|
||||
b'\xf1\x875QM907144D \xf1\x891063\xf1\x82\x002SA6092SOM',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x872Q0907572AA\xf1\x890396',
|
||||
@@ -1006,6 +1016,23 @@ FW_VERSIONS = {
|
||||
b'\xf1\x875Q0907572P \xf1\x890682',
|
||||
],
|
||||
},
|
||||
CAR.SKODA_FABIA_MK4: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x8705E906018CF\xf1\x891905',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x870CW300051M \xf1\x891936',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x875QF959655AT\xf1\x890755\xf1\x82\x1311110011110011111100110200--1111120749',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x872Q1909144S \xf1\x896042',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x872Q0907572AA\xf1\x890396',
|
||||
],
|
||||
},
|
||||
CAR.SKODA_KAMIQ_MK1: {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x8705C906032M \xf1\x891333',
|
||||
@@ -1049,27 +1076,43 @@ FW_VERSIONS = {
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x8704E906027DD\xf1\x893123',
|
||||
b'\xf1\x8704L906026DE\xf1\x895418',
|
||||
b'\xf1\x8704L906026EJ\xf1\x893661',
|
||||
b'\xf1\x8704L906026HT\xf1\x893617',
|
||||
b'\xf1\x8783A907115E \xf1\x890001',
|
||||
b'\xf1\x8705E906018DJ\xf1\x890915',
|
||||
b'\xf1\x875NA907115E \xf1\x890003',
|
||||
b'\xf1\x875NA907115E \xf1\x890005',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x870D9300043 \xf1\x895202',
|
||||
b'\xf1\x870DL300011N \xf1\x892014',
|
||||
b'\xf1\x870DL300012M \xf1\x892107',
|
||||
b'\xf1\x870DL300012N \xf1\x892110',
|
||||
b'\xf1\x870DL300013G \xf1\x892119',
|
||||
b'\xf1\x870GC300014N \xf1\x892801',
|
||||
b'\xf1\x870GC300046Q \xf1\x892802',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\0161213001211001205212111052100',
|
||||
b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\0161213001211001205212112052100',
|
||||
b'\xf1\x873Q0959655AP\xf1\x890306\xf1\x82\r11110011110011421111314211',
|
||||
b'\xf1\x873Q0959655BJ\xf1\x890703\xf1\x82\x0e1213001211001205212111052100',
|
||||
b'\xf1\x873Q0959655BK\xf1\x890703\xf1\x82\x0e1213001211001244212111442100',
|
||||
b'\xf1\x873Q0959655CN\xf1\x890720\xf1\x82\x0e1213001211001205212112052100',
|
||||
b'\xf1\x873Q0959655CQ\xf1\x890720\xf1\x82\x0e1213111211001205212112052111',
|
||||
b'\xf1\x873Q0959655DJ\xf1\x890731\xf1\x82\x0e1513001511001205232113052J00',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6050405',
|
||||
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6060405',
|
||||
b'\xf1\x875Q0909143P \xf1\x892051\xf1\x820527T6070405',
|
||||
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G500',
|
||||
b'\xf1\x875Q0910143C \xf1\x892211\xf1\x82\x0567T600G600',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x757, None): [
|
||||
b'\xf1\x872Q0907572Q \xf1\x890342',
|
||||
b'\xf1\x872Q0907572R \xf1\x890372',
|
||||
b'\xf1\x872Q0907572T \xf1\x890383',
|
||||
b'\xf1\x872Q0907572AA\xf1\x890396',
|
||||
b'\xf1\x872Q0907572AB\xf1\x890397',
|
||||
],
|
||||
},
|
||||
CAR.SKODA_OCTAVIA_MK3: {
|
||||
@@ -1139,6 +1182,7 @@ FW_VERSIONS = {
|
||||
b'\xf1\x8704L906026FP\xf1\x891196',
|
||||
b'\xf1\x8704L906026KB\xf1\x894071',
|
||||
b'\xf1\x8704L906026KD\xf1\x894798',
|
||||
b'\xf1\x873G0906259 \xf1\x890004',
|
||||
b'\xf1\x873G0906259B \xf1\x890002',
|
||||
b'\xf1\x873G0906264A \xf1\x890002',
|
||||
],
|
||||
@@ -1148,12 +1192,14 @@ FW_VERSIONS = {
|
||||
b'\xf1\x870D9300012 \xf1\x894940',
|
||||
b'\xf1\x870D9300041H \xf1\x894905',
|
||||
b'\xf1\x870GC300043 \xf1\x892301',
|
||||
b'\xf1\x870D9300043F \xf1\x895202',
|
||||
],
|
||||
(Ecu.srs, 0x715, None): [
|
||||
b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\x12111200111121001121110012211292221111',
|
||||
b'\xf1\x875Q0959655AE\xf1\x890130\xf1\x82\022111200111121001121118112231292221111',
|
||||
b'\xf1\x875Q0959655AK\xf1\x890130\xf1\x82\022111200111121001121110012211292221111',
|
||||
b'\xf1\x875Q0959655BH\xf1\x890336\xf1\x82\02331310031313100313131013141319331413100',
|
||||
b'\xf1\x875Q0959655CA\xf1\x890403\xf1\x82\x1331310031313100313151013141319331423100',
|
||||
],
|
||||
(Ecu.eps, 0x712, None): [
|
||||
b'\xf1\x875Q0909143K \xf1\x892033\xf1\x820514UZ070203',
|
||||
|
||||
@@ -112,9 +112,6 @@ class Controls:
|
||||
if not self.disengage_on_accelerator:
|
||||
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS
|
||||
|
||||
if self.CP.dashcamOnly and self.params.get_bool("DashcamOverride"):
|
||||
self.CP.dashcamOnly = False
|
||||
|
||||
# read params
|
||||
self.is_metric = self.params.get_bool("IsMetric")
|
||||
self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled")
|
||||
@@ -280,8 +277,9 @@ class Controls:
|
||||
|
||||
# Alert if fan isn't spinning for 5 seconds
|
||||
if self.sm['peripheralState'].pandaType != log.PandaState.PandaType.unknown:
|
||||
if self.sm['peripheralState'].fanSpeedRpm == 0 and self.sm['deviceState'].fanSpeedPercentDesired > 50:
|
||||
if (self.sm.frame - self.last_functional_fan_frame) * DT_CTRL > 5.0:
|
||||
if self.sm['peripheralState'].fanSpeedRpm < 500 and self.sm['deviceState'].fanSpeedPercentDesired > 50:
|
||||
# allow enough time for the fan controller in the panda to recover from stalls
|
||||
if (self.sm.frame - self.last_functional_fan_frame) * DT_CTRL > 15.0:
|
||||
self.events.add(EventName.fanMalfunction)
|
||||
else:
|
||||
self.last_functional_fan_frame = self.sm.frame
|
||||
|
||||
@@ -292,7 +292,7 @@ def calibration_invalid_alert(CP: car.CarParams, CS: car.CarState, sm: messaging
|
||||
rpy = sm['liveCalibration'].rpyCalib
|
||||
yaw = math.degrees(rpy[2] if len(rpy) == 3 else math.nan)
|
||||
pitch = math.degrees(rpy[1] if len(rpy) == 3 else math.nan)
|
||||
angles = f"Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°"
|
||||
angles = f"Remount Device (Pitch: {pitch:.1f}°, Yaw: {yaw:.1f}°)"
|
||||
return NormalPermanentAlert("Calibration Invalid", angles)
|
||||
|
||||
|
||||
@@ -317,9 +317,9 @@ def modeld_lagging_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
|
||||
|
||||
|
||||
def wrong_car_mode_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
|
||||
text = "Cruise Mode Disabled"
|
||||
text = "Enable Adaptive Cruise to Engage"
|
||||
if CP.carName == "honda":
|
||||
text = "Main Switch Off"
|
||||
text = "Enable Main Switch to Engage"
|
||||
return NoEntryAlert(text)
|
||||
|
||||
|
||||
|
||||
@@ -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, CS.vEgo, friction_compensation=False)
|
||||
lateral_accel_deadzone, 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, CS.vEgo, friction_compensation=True)
|
||||
lateral_accel_deadzone, friction_compensation=True)
|
||||
|
||||
freeze_integrator = steer_limited or CS.steeringPressed or CS.vEgo < 5
|
||||
output_torque = self.pid.update(pid_log.error,
|
||||
|
||||
@@ -122,8 +122,9 @@ class LongitudinalPlanner:
|
||||
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j)
|
||||
|
||||
self.v_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.v_solution)
|
||||
self.a_desired_trajectory_full = np.interp(T_IDXS, T_IDXS_MPC, self.mpc.a_solution)
|
||||
self.v_desired_trajectory = self.v_desired_trajectory_full[:CONTROL_N]
|
||||
self.a_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC, self.mpc.a_solution)
|
||||
self.a_desired_trajectory = self.a_desired_trajectory_full[:CONTROL_N]
|
||||
self.j_desired_trajectory = np.interp(T_IDXS[:CONTROL_N], T_IDXS_MPC[:-1], self.mpc.j_solution)
|
||||
|
||||
# TODO counter is only needed because radar is glitchy, remove once radar is gone
|
||||
|
||||
@@ -19,9 +19,11 @@ def publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner):
|
||||
ui_send = messaging.new_message('uiPlan')
|
||||
ui_send.valid = sm.all_checks(service_list=['carState', 'controlsState', 'modelV2'])
|
||||
uiPlan = ui_send.uiPlan
|
||||
uiPlan.frameId = sm['modelV2'].frameId
|
||||
uiPlan.position.x = np.interp(plan_odo, model_odo, lateral_planner.lat_mpc.x_sol[:,0]).tolist()
|
||||
uiPlan.position.y = np.interp(plan_odo, model_odo, lateral_planner.lat_mpc.x_sol[:,1]).tolist()
|
||||
uiPlan.position.z = np.interp(plan_odo, model_odo, lateral_planner.path_xyz[:,2]).tolist()
|
||||
uiPlan.accel = longitudinal_planner.a_desired_trajectory_full.tolist()
|
||||
pm.send('uiPlan', ui_send)
|
||||
|
||||
def plannerd_thread(sm=None, pm=None):
|
||||
|
||||
@@ -72,7 +72,6 @@ class TestStartup(unittest.TestCase):
|
||||
params.clear_all()
|
||||
params.put_bool("Passive", False)
|
||||
params.put_bool("OpenpilotEnabledToggle", True)
|
||||
params.put_bool("ObdMultiplexingDisabled", True)
|
||||
|
||||
# Build capnn version of FW array
|
||||
if fw_versions is not None:
|
||||
@@ -109,6 +108,10 @@ class TestStartup(unittest.TestCase):
|
||||
finger = _FINGERPRINTS[car_model][0]
|
||||
|
||||
for _ in range(1000):
|
||||
# controlsd waits for boardd to echo back that it has changed the multiplexing mode
|
||||
if not params.get_bool("ObdMultiplexingChanged"):
|
||||
params.put_bool("ObdMultiplexingChanged", True)
|
||||
|
||||
msgs = [[addr, 0, b'\x00'*length, 0] for addr, length in finger.items()]
|
||||
pm.send('can', can_list_to_can_capnp(msgs))
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ SUPPORTED_FW_VERSIONS = {
|
||||
b"DN8_ SCC FHCUP 1.00 1.00 99110-L0000\x19\x08)\x15T ": ConfigValues(
|
||||
default_config=b"\x00\x00\x00\x01\x00\x00",
|
||||
tracks_enabled=b"\x00\x00\x00\x01\x00\x01"),
|
||||
b"DN8_ SCC F-CUP 1.00 1.00 99110-L0000\x19\x08)\x15T ": ConfigValues(
|
||||
default_config=b"\x00\x00\x00\x01\x00\x00",
|
||||
tracks_enabled=b"\x00\x00\x00\x01\x00\x01"),
|
||||
# 2021 SONATA HYBRID
|
||||
b"DNhe SCC FHCUP 1.00 1.02 99110-L5000 \x01#\x15# ": ConfigValues(
|
||||
default_config=b"\x00\x00\x00\x01\x00\x00",
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import time
|
||||
import statistics
|
||||
import cereal.messaging as messaging
|
||||
|
||||
from typing import Dict
|
||||
|
||||
camera_states = [
|
||||
'roadCameraState',
|
||||
'wideRoadCameraState',
|
||||
'driverCameraState'
|
||||
]
|
||||
|
||||
def fmt(val):
|
||||
ref = 0.05
|
||||
return f"{val:.6f} ({100 * val / ref:.2f}%)"
|
||||
|
||||
if __name__ == "__main__":
|
||||
sm = messaging.SubMaster(camera_states)
|
||||
|
||||
prev_sof = {state: None for state in camera_states}
|
||||
diffs: Dict[str, list] = {state: [] for state in camera_states}
|
||||
|
||||
st = time.monotonic()
|
||||
while True:
|
||||
sm.update()
|
||||
|
||||
for state in camera_states:
|
||||
if sm.updated[state]:
|
||||
if prev_sof[state] is not None:
|
||||
diffs[state].append((sm[state].timestampSof - prev_sof[state]) / 1e9)
|
||||
prev_sof[state] = sm[state].timestampSof
|
||||
|
||||
if time.monotonic() - st > 10:
|
||||
for state in camera_states:
|
||||
values = diffs[state]
|
||||
ref = 0.05
|
||||
print(f"{state} \tMean: {fmt(statistics.mean(values))} \t Min: {fmt(min(values))} \t Max: {fmt(max(values))} \t Std: {statistics.stdev(values):.6f} \t Num frames: {len(values)}")
|
||||
diffs[state] = []
|
||||
|
||||
print()
|
||||
st = time.monotonic()
|
||||
@@ -74,7 +74,7 @@ if __name__ == "__main__":
|
||||
|
||||
elif msg.which() == "carParams":
|
||||
CP = msg.carParams
|
||||
car_fw = CP.carFw
|
||||
car_fw = [fw for fw in CP.carFw if not fw.logging]
|
||||
if len(car_fw) == 0:
|
||||
print("no fw")
|
||||
break
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
ubloxd
|
||||
ubloxd_test
|
||||
params_learner
|
||||
paramsd
|
||||
locationd
|
||||
test/test_glonass_runner
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
Import('env', 'common', 'cereal', 'messaging', 'libkf', 'transformations')
|
||||
|
||||
loc_libs = [cereal, messaging, 'zmq', common, 'capnp', 'kj', 'kaitai', 'pthread']
|
||||
|
||||
if GetOption('kaitai'):
|
||||
generated = Dir('generated').srcnode().abspath
|
||||
cmd = f"kaitai-struct-compiler --target cpp_stl --outdir {generated} $SOURCES"
|
||||
env.Command(['generated/ubx.cpp', 'generated/ubx.h'], 'ubx.ksy', cmd)
|
||||
env.Command(['generated/gps.cpp', 'generated/gps.h'], 'gps.ksy', cmd)
|
||||
glonass = env.Command(['generated/glonass.cpp', 'generated/glonass.h'], 'glonass.ksy', cmd)
|
||||
|
||||
# kaitai issue: https://github.com/kaitai-io/kaitai_struct/issues/910
|
||||
patch = env.Command(None, 'glonass_fix.patch', 'git apply $SOURCES')
|
||||
env.Depends(patch, glonass)
|
||||
|
||||
glonass_obj = env.Object('generated/glonass.cpp')
|
||||
env.Program("ubloxd", ["ubloxd.cc", "ublox_msg.cc", "generated/ubx.cpp", "generated/gps.cpp", glonass_obj], LIBS=loc_libs)
|
||||
loc_libs = [cereal, messaging, 'zmq', common, 'capnp', 'kj', 'pthread']
|
||||
|
||||
ekf_sym_cc = env.SharedObject("#rednose/helpers/ekf_sym.cc")
|
||||
locationd_sources = ["locationd.cc", "models/live_kf.cc", ekf_sym_cc]
|
||||
@@ -25,7 +11,4 @@ lenv.Depends(locationd, libkf)
|
||||
|
||||
if File("liblocationd.cc").exists():
|
||||
liblocationd = lenv.SharedLibrary("liblocationd", ["liblocationd.cc"] + locationd_sources, LIBS=loc_libs + transformations)
|
||||
lenv.Depends(liblocationd, libkf)
|
||||
|
||||
if GetOption('test'):
|
||||
env.Program("test/test_glonass_runner", ['test/test_glonass_runner.cc', 'test/test_glonass_kaitai.cc', glonass_obj], LIBS=[loc_libs])
|
||||
lenv.Depends(liblocationd, libkf)
|
||||
+167
-162
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import time
|
||||
@@ -8,7 +7,7 @@ from collections import defaultdict
|
||||
from concurrent.futures import Future, ProcessPoolExecutor
|
||||
from datetime import datetime
|
||||
from enum import IntEnum
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
import numpy as np
|
||||
|
||||
@@ -17,9 +16,9 @@ from common.params import Params, put_nonblocking
|
||||
from laika import AstroDog
|
||||
from laika.constants import SECS_IN_HR, SECS_IN_MIN
|
||||
from laika.downloader import DownloadFailed
|
||||
from laika.ephemeris import Ephemeris, EphemerisType, convert_ublox_gps_ephem, convert_ublox_glonass_ephem, parse_qcom_ephem
|
||||
from laika.ephemeris import EphemerisType, GPSEphemeris, GLONASSEphemeris, ephemeris_structs, parse_qcom_ephem
|
||||
from laika.gps_time import GPSTime
|
||||
from laika.helpers import ConstellationId
|
||||
from laika.helpers import ConstellationId, get_sv_id
|
||||
from laika.raw_gnss import GNSSMeasurement, correct_measurements, process_measurements, read_raw_ublox, read_raw_qcom
|
||||
from laika.opt import calc_pos_fix, get_posfix_sympy_fun, calc_vel_fix, get_velfix_sympy_func
|
||||
from selfdrive.locationd.models.constants import GENERATED_DIR, ObservationKind
|
||||
@@ -28,15 +27,53 @@ from selfdrive.locationd.models.gnss_kf import States as GStates
|
||||
from system.swaglog import cloudlog
|
||||
|
||||
MAX_TIME_GAP = 10
|
||||
EPHEMERIS_CACHE = 'LaikadEphemeris'
|
||||
EPHEMERIS_CACHE = 'LaikadEphemerisV3'
|
||||
DOWNLOADS_CACHE_FOLDER = "/tmp/comma_download_cache/"
|
||||
CACHE_VERSION = 0.2
|
||||
POS_FIX_RESIDUAL_THRESHOLD = 100.0
|
||||
|
||||
|
||||
class LogEphemerisType(IntEnum):
|
||||
nav = 0
|
||||
nasaUltraRapid = 1
|
||||
glonassIacUltraRapid = 2
|
||||
qcom = 3
|
||||
|
||||
class EphemerisSource(IntEnum):
|
||||
gnssChip = 0
|
||||
internet = 1
|
||||
cache = 2
|
||||
unknown = 3
|
||||
|
||||
def get_log_eph_type(ephem):
|
||||
if ephem.eph_type == EphemerisType.NAV:
|
||||
source_type = LogEphemerisType.nav
|
||||
elif ephem.eph_type == EphemerisType.QCOM_POLY:
|
||||
source_type = LogEphemerisType.qcom
|
||||
else:
|
||||
assert ephem.file_epoch is not None
|
||||
file_src = ephem.file_source
|
||||
if file_src == 'igu': # example nasa: '2214/igu22144_00.sp3.Z'
|
||||
source_type = LogEphemerisType.nasaUltraRapid
|
||||
elif file_src == 'Sta': # example nasa: '22166/ultra/Stark_1D_22061518.sp3'
|
||||
source_type = LogEphemerisType.glonassIacUltraRapid
|
||||
else:
|
||||
raise Exception(f"Didn't expect file source {file_src}")
|
||||
return source_type
|
||||
|
||||
def get_log_eph_source(ephem):
|
||||
if ephem.file_name == 'qcom' or ephem.file_name == 'ublox':
|
||||
source = EphemerisSource.gnssChip
|
||||
elif ephem.file_name == EPHEMERIS_CACHE:
|
||||
source = EphemerisSource.cache
|
||||
else:
|
||||
source = EphemerisSource.internet
|
||||
return source
|
||||
|
||||
|
||||
class Laikad:
|
||||
def __init__(self, valid_const=("GPS", "GLONASS"), auto_fetch_navs=True, auto_update=False,
|
||||
valid_ephem_types=(EphemerisType.NAV,),
|
||||
def __init__(self, valid_const=(ConstellationId.GPS, ConstellationId.GLONASS), auto_fetch_navs=True, auto_update=False,
|
||||
valid_ephem_types=(EphemerisType.NAV, EphemerisType.QCOM_POLY),
|
||||
save_ephemeris=False, use_qcom=False):
|
||||
"""
|
||||
valid_const: GNSS constellation which can be used
|
||||
@@ -51,10 +88,11 @@ class Laikad:
|
||||
self.auto_fetch_navs = auto_fetch_navs
|
||||
self.orbit_fetch_executor: Optional[ProcessPoolExecutor] = None
|
||||
self.orbit_fetch_future: Optional[Future] = None
|
||||
|
||||
self.last_fetch_navs_t = None
|
||||
self.got_first_gnss_msg = False
|
||||
self.last_cached_t = None
|
||||
|
||||
self.last_report_time = GPSTime(0, 0)
|
||||
self.last_fetch_navs_t = GPSTime(0, 0)
|
||||
self.last_cached_t = GPSTime(0, 0)
|
||||
self.save_ephemeris = save_ephemeris
|
||||
self.load_cache()
|
||||
|
||||
@@ -64,59 +102,94 @@ class Laikad:
|
||||
self.last_fix_t = None
|
||||
self.gps_week = None
|
||||
self.use_qcom = use_qcom
|
||||
self.first_log_time = None
|
||||
self.ttff = -1
|
||||
|
||||
def load_cache(self):
|
||||
if not self.save_ephemeris:
|
||||
return
|
||||
|
||||
cache = Params().get(EPHEMERIS_CACHE)
|
||||
if not cache:
|
||||
cache_bytes = Params().get(EPHEMERIS_CACHE)
|
||||
if not cache_bytes:
|
||||
return
|
||||
|
||||
nav_dict = {}
|
||||
try:
|
||||
cache = json.loads(cache, object_hook=deserialize_hook)
|
||||
if cache['version'] == CACHE_VERSION:
|
||||
self.astro_dog.add_navs(cache['navs'])
|
||||
self.last_fetch_navs_t = cache['last_fetch_navs_t']
|
||||
else:
|
||||
cache['navs'] = {}
|
||||
except json.decoder.JSONDecodeError:
|
||||
ephem_cache = ephemeris_structs.EphemerisCache.from_bytes(cache_bytes)
|
||||
glonass_navs = [GLONASSEphemeris(data_struct, file_name=EPHEMERIS_CACHE) for data_struct in ephem_cache.glonassEphemerides]
|
||||
gps_navs = [GPSEphemeris(data_struct, file_name=EPHEMERIS_CACHE) for data_struct in ephem_cache.gpsEphemerides]
|
||||
for e in sum([glonass_navs, gps_navs], []):
|
||||
if e.prn not in nav_dict:
|
||||
nav_dict[e.prn] = []
|
||||
nav_dict[e.prn].append(e)
|
||||
self.astro_dog.add_navs(nav_dict)
|
||||
except Exception:
|
||||
cloudlog.exception("Error parsing cache")
|
||||
timestamp = self.last_fetch_navs_t.as_datetime() if self.last_fetch_navs_t is not None else 'Nan'
|
||||
cloudlog.debug(
|
||||
f"Loaded navs ({sum([len(v) for v in cache['navs']])}) cache with timestamp: {timestamp}. Unique orbit and nav sats: {list(cache['navs'].keys())} " +
|
||||
f"With time range: {[f'{start.as_datetime()}, {end.as_datetime()}' for (start,end) in self.astro_dog.navs_fetched_times._ranges]}")
|
||||
f"Loaded navs ({sum([len(nav_dict[prn]) for prn in nav_dict.keys()])}). Unique orbit and nav sats: {list(nav_dict.keys())} ")
|
||||
|
||||
def cache_ephemeris(self, t: GPSTime):
|
||||
if self.save_ephemeris and (self.last_cached_t is None or t - self.last_cached_t > SECS_IN_MIN):
|
||||
put_nonblocking(EPHEMERIS_CACHE, json.dumps(
|
||||
{'version': CACHE_VERSION, 'last_fetch_navs_t': self.last_fetch_navs_t, 'navs': self.astro_dog.navs},
|
||||
cls=CacheSerializer))
|
||||
def cache_ephemeris(self):
|
||||
|
||||
if self.save_ephemeris and (self.last_report_time - self.last_cached_t > SECS_IN_MIN):
|
||||
nav_list: List = sum([v for k,v in self.astro_dog.navs.items()], [])
|
||||
ephem_cache = ephemeris_structs.EphemerisCache(**{'glonassEphemerides': [e.data for e in nav_list if e.prn[0]=='R'],
|
||||
'gpsEphemerides': [e.data for e in nav_list if e.prn[0]=='G']})
|
||||
|
||||
put_nonblocking(EPHEMERIS_CACHE, ephem_cache.to_bytes())
|
||||
cloudlog.debug("Cache saved")
|
||||
self.last_cached_t = t
|
||||
self.last_cached_t = self.last_report_time
|
||||
|
||||
def create_ephem_statuses(self):
|
||||
ephemeris_statuses = []
|
||||
prns_to_check = list(self.astro_dog.get_all_ephem_prns())
|
||||
prns_to_check.sort()
|
||||
for prn in prns_to_check:
|
||||
eph = self.astro_dog.get_eph(prn, self.last_report_time)
|
||||
if eph is not None:
|
||||
status = log.GnssMeasurements.EphemerisStatus.new_message()
|
||||
status.constellationId = ConstellationId.from_rinex_char(prn[0]).value
|
||||
status.svId = get_sv_id(prn)
|
||||
status.type = get_log_eph_type(eph).value
|
||||
status.source = get_log_eph_source(eph).value
|
||||
ephemeris_statuses.append(status)
|
||||
return ephemeris_statuses
|
||||
|
||||
|
||||
def get_lsq_fix(self, t, measurements):
|
||||
if self.last_fix_t is None or abs(self.last_fix_t - t) > 0:
|
||||
min_measurements = 7 if any(p.constellation_id == ConstellationId.GLONASS for p in measurements) else 6
|
||||
position_solution, pr_residuals = calc_pos_fix(measurements, self.posfix_functions, min_measurements=min_measurements)
|
||||
min_measurements = 5 if any(p.constellation_id == ConstellationId.GLONASS for p in measurements) else 4
|
||||
position_solution, pr_residuals, pos_std = calc_pos_fix(measurements, self.posfix_functions, min_measurements=min_measurements)
|
||||
if len(position_solution) < 3:
|
||||
return None
|
||||
position_estimate = position_solution[:3]
|
||||
#TODO median abs residual is decent estimate of std, can be improved with measurements stds and/or DOP
|
||||
position_std = np.median(np.abs(pr_residuals)) * np.ones(3)
|
||||
velocity_solution, prr_residuals = calc_vel_fix(measurements, position_estimate, self.velfix_function, min_measurements=min_measurements)
|
||||
|
||||
position_std_residual = np.median(np.abs(pr_residuals))
|
||||
position_std = np.median(np.abs(pos_std))/10
|
||||
position_std = max(position_std_residual, position_std) * np.ones(3)
|
||||
|
||||
velocity_solution, prr_residuals, vel_std = calc_vel_fix(measurements, position_estimate, self.velfix_function, min_measurements=min_measurements)
|
||||
if len(velocity_solution) < 3:
|
||||
return None
|
||||
|
||||
velocity_estimate = velocity_solution[:3]
|
||||
velocity_std = np.median(np.abs(prr_residuals)) * np.ones(3)
|
||||
|
||||
velocity_std_residual = np.median(np.abs(prr_residuals))
|
||||
velocity_std = np.median(np.abs(vel_std))/10
|
||||
velocity_std = max(velocity_std, velocity_std_residual) * np.ones(3)
|
||||
|
||||
return position_estimate, position_std, velocity_estimate, velocity_std
|
||||
|
||||
def is_good_report(self, gnss_msg):
|
||||
if gnss_msg.which() == 'drMeasurementReport' and self.use_qcom:
|
||||
constellation_id = ConstellationId.from_qcom_source(gnss_msg.drMeasurementReport.source)
|
||||
# TODO support GLONASS
|
||||
return constellation_id in [ConstellationId.GPS, ConstellationId.SBAS]
|
||||
# TODO: Understand and use remaining unknown constellations
|
||||
try:
|
||||
good_constellation = constellation_id in [ConstellationId.GPS, ConstellationId.SBAS]
|
||||
except NotImplementedError:
|
||||
good_constellation = False
|
||||
# gpsWeek 65535 is received rarely from quectel, this cannot be
|
||||
# passed to GnssMeasurements's gpsWeek (Int16)
|
||||
good_week = not getattr(gnss_msg, gnss_msg.which()).gpsWeek > np.iinfo(np.int16).max
|
||||
return good_constellation and good_week
|
||||
elif gnss_msg.which() == 'measurementReport' and not self.use_qcom:
|
||||
return True
|
||||
else:
|
||||
@@ -133,6 +206,7 @@ class Laikad:
|
||||
week = report.gpsWeek
|
||||
tow = report.rcvTow
|
||||
new_meas = read_raw_ublox(report)
|
||||
self.last_report_time = GPSTime(week, tow)
|
||||
return week, tow, new_meas
|
||||
|
||||
def is_ephemeris(self, gnss_msg):
|
||||
@@ -147,28 +221,34 @@ class Laikad:
|
||||
if self.gps_week is None:
|
||||
return
|
||||
ephem = parse_qcom_ephem(gnss_msg.drSvPoly, self.gps_week)
|
||||
self.astro_dog.add_qcom_polys({ephem.prn: [ephem]})
|
||||
|
||||
else:
|
||||
if gnss_msg.which() == 'ephemeris':
|
||||
ephem = convert_ublox_gps_ephem(gnss_msg.ephemeris)
|
||||
data_struct = ephemeris_structs.Ephemeris.new_message(**gnss_msg.ephemeris.to_dict())
|
||||
ephem = GPSEphemeris(data_struct, file_name='ublox')
|
||||
elif gnss_msg.which() == 'glonassEphemeris':
|
||||
ephem = convert_ublox_glonass_ephem(gnss_msg.glonassEphemeris)
|
||||
data_struct = ephemeris_structs.GlonassEphemeris.new_message(**gnss_msg.glonassEphemeris.to_dict())
|
||||
ephem = GLONASSEphemeris(data_struct, file_name='ublox')
|
||||
else:
|
||||
cloudlog.error(f"Unsupported ephemeris type: {gnss_msg.which()}")
|
||||
return
|
||||
self.astro_dog.add_navs({ephem.prn: [ephem]})
|
||||
self.cache_ephemeris(t=ephem.epoch)
|
||||
self.astro_dog.add_navs({ephem.prn: [ephem]})
|
||||
self.cache_ephemeris()
|
||||
|
||||
def process_report(self, new_meas, t):
|
||||
# Filter measurements with unexpected pseudoranges for GPS and GLONASS satellites
|
||||
new_meas = [m for m in new_meas if 1e7 < m.observables['C1C'] < 3e7]
|
||||
processed_measurements = process_measurements(new_meas, self.astro_dog)
|
||||
if self.last_fix_pos is not None:
|
||||
corrected_measurements = correct_measurements(processed_measurements, self.last_fix_pos, self.astro_dog)
|
||||
instant_fix = self.get_lsq_fix(t, corrected_measurements)
|
||||
#instant_fix = self.get_lsq_fix(t, processed_measurements)
|
||||
est_pos = self.last_fix_pos
|
||||
else:
|
||||
corrected_measurements = []
|
||||
instant_fix = self.get_lsq_fix(t, processed_measurements)
|
||||
est_pos = self.gnss_kf.x[GStates.ECEF_POS].tolist()
|
||||
corrected_measurements = correct_measurements(processed_measurements, est_pos, self.astro_dog)
|
||||
return corrected_measurements
|
||||
|
||||
def calc_fix(self, t, measurements):
|
||||
instant_fix = self.get_lsq_fix(t, measurements)
|
||||
if instant_fix is None:
|
||||
return None
|
||||
else:
|
||||
@@ -176,60 +256,53 @@ class Laikad:
|
||||
self.last_fix_t = t
|
||||
self.last_fix_pos = position_estimate
|
||||
self.lat_fix_pos_std = position_std
|
||||
if (t*1e9) % 10 == 0:
|
||||
cloudlog.debug(f"Measurements Incoming/Processed/Corrected: {len(new_meas), len(processed_measurements), len(corrected_measurements)}")
|
||||
return position_estimate, position_std, velocity_estimate, velocity_std, corrected_measurements, processed_measurements
|
||||
return position_estimate, position_std, velocity_estimate, velocity_std
|
||||
|
||||
def process_gnss_msg(self, gnss_msg, gnss_mono_time: int, block=False):
|
||||
out_msg = messaging.new_message("gnssMeasurements")
|
||||
t = gnss_mono_time * 1e-9
|
||||
msg_dict: Dict[str, Any] = {"measTime": gnss_mono_time}
|
||||
if self.first_log_time is None:
|
||||
self.first_log_time = 1e-9 * gnss_mono_time
|
||||
if self.is_ephemeris(gnss_msg):
|
||||
self.read_ephemeris(gnss_msg)
|
||||
return None
|
||||
elif self.is_good_report(gnss_msg):
|
||||
|
||||
week, tow, new_meas = self.read_report(gnss_msg)
|
||||
if len(new_meas) == 0:
|
||||
return None
|
||||
|
||||
self.gps_week = week
|
||||
t = gnss_mono_time * 1e-9
|
||||
if week > 0:
|
||||
self.got_first_gnss_msg = True
|
||||
latest_msg_t = GPSTime(week, tow)
|
||||
if self.auto_fetch_navs:
|
||||
self.fetch_navs(latest_msg_t, block)
|
||||
|
||||
output = self.process_report(new_meas, t)
|
||||
if output is None:
|
||||
return None
|
||||
position_estimate, position_std, velocity_estimate, velocity_std, corrected_measurements, _ = output
|
||||
corrected_measurements = self.process_report(new_meas, t)
|
||||
msg_dict['correctedMeasurements'] = [create_measurement_msg(m) for m in corrected_measurements]
|
||||
|
||||
self.update_localizer(position_estimate, t, corrected_measurements)
|
||||
meas_msgs = [create_measurement_msg(m) for m in corrected_measurements]
|
||||
msg = messaging.new_message("gnssMeasurements")
|
||||
fix = self.calc_fix(t, corrected_measurements)
|
||||
measurement_msg = log.LiveLocationKalman.Measurement.new_message
|
||||
if fix is not None:
|
||||
position_estimate, position_std, velocity_estimate, velocity_std = fix
|
||||
if self.ttff <= 0:
|
||||
self.ttff = max(1e-3, t - self.first_log_time)
|
||||
msg_dict["positionECEF"] = measurement_msg(value=position_estimate, std=position_std.tolist(), valid=bool(self.last_fix_t == t))
|
||||
msg_dict["velocityECEF"] = measurement_msg(value=velocity_estimate, std=velocity_std.tolist(), valid=bool(self.last_fix_t == t))
|
||||
|
||||
self.update_localizer(self.last_fix_pos, t, corrected_measurements)
|
||||
P_diag = self.gnss_kf.P.diagonal()
|
||||
kf_valid = all(self.kf_valid(t))
|
||||
msg.gnssMeasurements = {
|
||||
"gpsWeek": week,
|
||||
"gpsTimeOfWeek": tow,
|
||||
"kalmanPositionECEF": measurement_msg(value=self.gnss_kf.x[GStates.ECEF_POS].tolist(),
|
||||
msg_dict["kalmanPositionECEF"] = measurement_msg(value=self.gnss_kf.x[GStates.ECEF_POS].tolist(),
|
||||
std=np.sqrt(P_diag[GStates.ECEF_POS]).tolist(),
|
||||
valid=kf_valid),
|
||||
"kalmanVelocityECEF": measurement_msg(value=self.gnss_kf.x[GStates.ECEF_VELOCITY].tolist(),
|
||||
valid=kf_valid)
|
||||
msg_dict["kalmanVelocityECEF"] = measurement_msg(value=self.gnss_kf.x[GStates.ECEF_VELOCITY].tolist(),
|
||||
std=np.sqrt(P_diag[GStates.ECEF_VELOCITY]).tolist(),
|
||||
valid=kf_valid),
|
||||
"positionECEF": measurement_msg(value=position_estimate, std=position_std.tolist(), valid=bool(self.last_fix_t == t)),
|
||||
"velocityECEF": measurement_msg(value=velocity_estimate, std=velocity_std.tolist(), valid=bool(self.last_fix_t == t)),
|
||||
|
||||
"measTime": gnss_mono_time,
|
||||
"correctedMeasurements": meas_msgs
|
||||
}
|
||||
return msg
|
||||
|
||||
#elif gnss_msg.which() == 'ionoData':
|
||||
# TODO: add this, Needed to better correct messages offline. First fix ublox_msg.cc to sent them.
|
||||
valid=kf_valid)
|
||||
|
||||
msg_dict['gpsWeek'] = self.last_report_time.week
|
||||
msg_dict['gpsTimeOfWeek'] = self.last_report_time.tow
|
||||
msg_dict['timeToFirstFix'] = self.ttff
|
||||
msg_dict['ephemerisStatuses'] = self.create_ephem_statuses()
|
||||
out_msg.gnssMeasurements = msg_dict
|
||||
return out_msg
|
||||
|
||||
def update_localizer(self, est_pos, t: float, measurements: List[GNSSMeasurement]):
|
||||
# Check time and outputs are valid
|
||||
@@ -241,7 +314,7 @@ class Laikad:
|
||||
cloudlog.error("Time gap of over 10s detected, gnss kalman reset")
|
||||
elif not valid[2]:
|
||||
cloudlog.error("Gnss kalman filter state is nan")
|
||||
if len(est_pos) > 0:
|
||||
if est_pos is not None and len(est_pos) > 0:
|
||||
cloudlog.info(f"Reset kalman filter with {est_pos}")
|
||||
self.init_gnss_localizer(est_pos)
|
||||
else:
|
||||
@@ -266,7 +339,7 @@ class Laikad:
|
||||
|
||||
def fetch_navs(self, t: GPSTime, block):
|
||||
# Download new navs if 1 hour of navs data left
|
||||
if t + SECS_IN_HR not in self.astro_dog.navs_fetched_times and (self.last_fetch_navs_t is None or abs(t - self.last_fetch_navs_t) > SECS_IN_MIN):
|
||||
if t + SECS_IN_HR not in self.astro_dog.navs_fetched_times and (abs(t - self.last_fetch_navs_t) > SECS_IN_MIN):
|
||||
astro_dog_vars = self.astro_dog.valid_const, self.astro_dog.auto_update, self.astro_dog.valid_ephem_types, self.astro_dog.cache_dir
|
||||
ret = None
|
||||
|
||||
@@ -284,7 +357,7 @@ class Laikad:
|
||||
self.last_fetch_navs_t = ret[2]
|
||||
else:
|
||||
self.astro_dog.navs, self.astro_dog.navs_fetched_times, self.last_fetch_navs_t = ret
|
||||
self.cache_ephemeris(t=t)
|
||||
self.cache_ephemeris()
|
||||
|
||||
|
||||
def get_orbit_data(t: GPSTime, valid_const, auto_update, valid_ephem_types, cache_dir):
|
||||
@@ -314,31 +387,8 @@ def create_measurement_msg(meas: GNSSMeasurement):
|
||||
c.satPos = meas.sat_pos_final.tolist()
|
||||
c.satVel = meas.sat_vel.tolist()
|
||||
c.satVel = meas.sat_vel.tolist()
|
||||
ephem = meas.sat_ephemeris
|
||||
assert ephem is not None
|
||||
week, time_of_week = -1, -1
|
||||
if ephem.eph_type == EphemerisType.NAV:
|
||||
source_type = EphemerisSourceType.nav
|
||||
elif ephem.eph_type == EphemerisType.QCOM_POLY:
|
||||
source_type = EphemerisSourceType.qcom
|
||||
else:
|
||||
assert ephem.file_epoch is not None
|
||||
week = ephem.file_epoch.week
|
||||
time_of_week = ephem.file_epoch.tow
|
||||
file_src = ephem.file_source
|
||||
if file_src == 'igu': # example nasa: '2214/igu22144_00.sp3.Z'
|
||||
source_type = EphemerisSourceType.nasaUltraRapid
|
||||
elif file_src == 'Sta': # example nasa: '22166/ultra/Stark_1D_22061518.sp3'
|
||||
source_type = EphemerisSourceType.glonassIacUltraRapid
|
||||
else:
|
||||
raise Exception(f"Didn't expect file source {file_src}")
|
||||
|
||||
c.ephemerisSource.type = source_type.value
|
||||
c.ephemerisSource.gpsWeek = week
|
||||
c.ephemerisSource.gpsTimeOfWeek = int(time_of_week)
|
||||
return c
|
||||
|
||||
|
||||
def kf_add_observations(gnss_kf: GNSSKalman, t: float, measurements: List[GNSSMeasurement]):
|
||||
ekf_data = defaultdict(list)
|
||||
for m in measurements:
|
||||
@@ -354,69 +404,29 @@ def kf_add_observations(gnss_kf: GNSSKalman, t: float, measurements: List[GNSSMe
|
||||
gnss_kf.predict_and_observe(t, kind, data)
|
||||
|
||||
|
||||
class CacheSerializer(json.JSONEncoder):
|
||||
|
||||
def default(self, o):
|
||||
if isinstance(o, Ephemeris):
|
||||
return o.to_json()
|
||||
if isinstance(o, GPSTime):
|
||||
return o.__dict__
|
||||
if isinstance(o, np.ndarray):
|
||||
return o.tolist()
|
||||
return json.JSONEncoder.default(self, o)
|
||||
|
||||
|
||||
def deserialize_hook(dct):
|
||||
if 'ephemeris' in dct:
|
||||
return Ephemeris.from_json(dct)
|
||||
if 'week' in dct:
|
||||
return GPSTime(dct['week'], dct['tow'])
|
||||
return dct
|
||||
|
||||
|
||||
class EphemerisSourceType(IntEnum):
|
||||
nav = 0
|
||||
nasaUltraRapid = 1
|
||||
glonassIacUltraRapid = 2
|
||||
qcom = 3
|
||||
|
||||
|
||||
def process_msg(laikad, gnss_msg, mono_time, block=False):
|
||||
# TODO: Understand and use remaining unknown constellations
|
||||
if gnss_msg.which() == "drMeasurementReport":
|
||||
if getattr(gnss_msg, gnss_msg.which()).source not in ['glonass', 'gps', 'beidou', 'sbas']:
|
||||
return None
|
||||
|
||||
if getattr(gnss_msg, gnss_msg.which()).gpsWeek > np.iinfo(np.int16).max:
|
||||
# gpsWeek 65535 is received rarely from quectel, this cannot be
|
||||
# passed to GnssMeasurements's gpsWeek (Int16)
|
||||
return None
|
||||
|
||||
return laikad.process_gnss_msg(gnss_msg, mono_time, block=block)
|
||||
|
||||
|
||||
def clear_tmp_cache():
|
||||
if os.path.exists(DOWNLOADS_CACHE_FOLDER):
|
||||
shutil.rmtree(DOWNLOADS_CACHE_FOLDER)
|
||||
os.mkdir(DOWNLOADS_CACHE_FOLDER)
|
||||
|
||||
|
||||
def main(sm=None, pm=None, qc=None):
|
||||
def main(sm=None, pm=None):
|
||||
#clear_tmp_cache()
|
||||
|
||||
use_qcom = not Params().get_bool("UbloxAvailable", block=True)
|
||||
if use_qcom or (qc is not None and qc):
|
||||
raw_gnss_socket = "qcomGnss"
|
||||
if use_qcom:
|
||||
raw_name = "qcomGnss"
|
||||
else:
|
||||
raw_gnss_socket = "ubloxGnss"
|
||||
raw_name = "ubloxGnss"
|
||||
raw_gnss_sock = messaging.sub_sock(raw_name, conflate=False, timeout=1000)
|
||||
|
||||
if sm is None:
|
||||
sm = messaging.SubMaster([raw_gnss_socket, 'clocks'])
|
||||
sm = messaging.SubMaster(['clocks',])
|
||||
if pm is None:
|
||||
pm = messaging.PubMaster(['gnssMeasurements'])
|
||||
|
||||
# disable until set as main gps source, to better analyze startup time
|
||||
use_internet = False #"LAIKAD_NO_INTERNET" not in os.environ
|
||||
use_internet = False # "LAIKAD_NO_INTERNET" not in os.environ
|
||||
|
||||
replay = "REPLAY" in os.environ
|
||||
if replay or "CI" in os.environ:
|
||||
@@ -425,22 +435,17 @@ def main(sm=None, pm=None, qc=None):
|
||||
laikad = Laikad(save_ephemeris=not replay, auto_fetch_navs=use_internet, use_qcom=use_qcom)
|
||||
|
||||
while True:
|
||||
sm.update()
|
||||
|
||||
if sm.updated[raw_gnss_socket]:
|
||||
gnss_msg = sm[raw_gnss_socket]
|
||||
|
||||
msg = process_msg(laikad, gnss_msg, sm.logMonoTime[raw_gnss_socket], replay)
|
||||
if msg is None:
|
||||
# TODO: beautify this, locationd needs a valid message
|
||||
msg = messaging.new_message("gnssMeasurements")
|
||||
pm.send('gnssMeasurements', msg)
|
||||
for in_msg in messaging.drain_sock(raw_gnss_sock):
|
||||
out_msg = laikad.process_gnss_msg(getattr(in_msg, raw_name), in_msg.logMonoTime, replay)
|
||||
pm.send('gnssMeasurements', out_msg)
|
||||
|
||||
sm.update(0)
|
||||
if not laikad.got_first_gnss_msg and sm.updated['clocks']:
|
||||
clocks_msg = sm['clocks']
|
||||
t = GPSTime.from_datetime(datetime.utcfromtimestamp(clocks_msg.wallTimeNanos * 1E-9))
|
||||
if laikad.auto_fetch_navs:
|
||||
laikad.fetch_navs(t, block=replay)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "common/timing.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include "selfdrive/sensord/sensors/constants.h"
|
||||
#include "system/sensord/sensors/constants.h"
|
||||
#define VISION_DECIMATION 2
|
||||
#define SENSOR_DECIMATION 10
|
||||
#include "selfdrive/locationd/models/live_kf.h"
|
||||
|
||||
@@ -1,21 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import unittest
|
||||
from collections import defaultdict
|
||||
from cereal import log
|
||||
import cereal.messaging as messaging
|
||||
from common.params import Params
|
||||
from datetime import datetime
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
#from unittest.mock import patch
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
from common.params import Params
|
||||
from laika.constants import SECS_IN_DAY
|
||||
from laika.downloader import DownloadFailed
|
||||
from laika.ephemeris import EphemerisType, GPSEphemeris
|
||||
from laika.ephemeris import EphemerisType
|
||||
from laika.gps_time import GPSTime
|
||||
from laika.helpers import ConstellationId, TimeRangeHolder
|
||||
from laika.raw_gnss import GNSSMeasurement, read_raw_ublox
|
||||
from selfdrive.locationd.laikad import EPHEMERIS_CACHE, EphemerisSourceType, Laikad, create_measurement_msg
|
||||
from laika.helpers import ConstellationId
|
||||
from laika.raw_gnss import GNSSMeasurement, read_raw_ublox, read_raw_qcom
|
||||
from selfdrive.locationd.laikad import EPHEMERIS_CACHE, Laikad
|
||||
from selfdrive.test.openpilotci import get_url
|
||||
from tools.lib.logreader import LogReader
|
||||
from selfdrive.manager.process_config import managed_processes
|
||||
|
||||
from selfdrive.test.process_replay.helpers import OpenpilotPrefix
|
||||
|
||||
|
||||
def get_ublox_gnss(ubloxraw):
|
||||
with OpenpilotPrefix():
|
||||
managed_processes['ubloxd'].start()
|
||||
timeout_ms = 30
|
||||
pm = messaging.PubMaster(['ubloxRaw'])
|
||||
sock = messaging.sub_sock('ubloxGnss', timeout=timeout_ms)
|
||||
|
||||
log_msgs = []
|
||||
log_t = []
|
||||
for x in tqdm(ubloxraw):
|
||||
pm.send(x.which(), x.as_builder())
|
||||
ret = messaging.recv_one(sock)
|
||||
if ret is not None:
|
||||
msg = log.Event.new_message(ubloxGnss=ret.ubloxGnss.to_dict())
|
||||
msg.logMonoTime = x.logMonoTime
|
||||
log_msgs.append(msg)
|
||||
log_t.append(1e-9 * x.logMonoTime)
|
||||
assert managed_processes['ubloxd'].get_process_state_msg().running
|
||||
assert len(log_msgs) > 1 or len(ubloxraw) == 0
|
||||
managed_processes['ubloxd'].stop()
|
||||
return log_t, log_msgs
|
||||
|
||||
|
||||
|
||||
def get_log(segs=range(0)):
|
||||
@@ -23,7 +53,8 @@ def get_log(segs=range(0)):
|
||||
for i in segs:
|
||||
logs.extend(LogReader(get_url("4cf7a6ad03080c90|2021-09-29--13-46-36", i)))
|
||||
|
||||
all_logs = [m for m in logs if m.which() == 'ubloxGnss']
|
||||
raw_logs = [m for m in logs if m.which() == 'ubloxRaw']
|
||||
all_logs = get_ublox_gnss(raw_logs)[1]
|
||||
low_gnss = []
|
||||
for m in all_logs:
|
||||
if m.ubloxGnss.which() != 'measurementReport':
|
||||
@@ -31,21 +62,31 @@ def get_log(segs=range(0)):
|
||||
|
||||
MAX_MEAS = 7
|
||||
if m.ubloxGnss.measurementReport.numMeas > MAX_MEAS:
|
||||
mb = m.as_builder()
|
||||
mb = log.Event.new_message(ubloxGnss=m.ubloxGnss.to_dict())
|
||||
mb.logMonoTime = m.logMonoTime
|
||||
mb.ubloxGnss.measurementReport.numMeas = MAX_MEAS
|
||||
mb.ubloxGnss.measurementReport.measurements = list(m.ubloxGnss.measurementReport.measurements)[:MAX_MEAS]
|
||||
mb.ubloxGnss.measurementReport.measurements[0].pseudorange += 1000
|
||||
low_gnss.append(mb.as_reader())
|
||||
else:
|
||||
low_gnss.append(m)
|
||||
|
||||
return all_logs, low_gnss
|
||||
|
||||
def get_log_qcom(segs=range(0)):
|
||||
logs = []
|
||||
for i in segs:
|
||||
logs.extend(LogReader(get_url("b0b3cba7abf862d1|2023-03-11--09-40-33", i)))
|
||||
all_logs = [m for m in logs if m.which() == 'qcomGnss']
|
||||
return all_logs
|
||||
|
||||
def verify_messages(lr, laikad, return_one_success=False):
|
||||
good_msgs = []
|
||||
for m in lr:
|
||||
msg = laikad.process_gnss_msg(m.ubloxGnss, m.logMonoTime, block=True)
|
||||
if m.which() == 'ubloxGnss':
|
||||
gnss_msg = m.ubloxGnss
|
||||
else:
|
||||
gnss_msg = m.qcomGnss
|
||||
msg = laikad.process_gnss_msg(gnss_msg, m.logMonoTime, block=True)
|
||||
if msg is not None and len(msg.gnssMeasurements.correctedMeasurements) > 0:
|
||||
good_msgs.append(msg)
|
||||
if return_one_success:
|
||||
@@ -55,10 +96,16 @@ def verify_messages(lr, laikad, return_one_success=False):
|
||||
|
||||
def get_first_gps_time(logs):
|
||||
for m in logs:
|
||||
if m.ubloxGnss.which == 'measurementReport':
|
||||
new_meas = read_raw_ublox(m.ubloxGnss.measurementReport)
|
||||
if len(new_meas) > 0:
|
||||
return new_meas[0].recv_time
|
||||
if m.which() == 'ubloxGnss':
|
||||
if m.ubloxGnss.which == 'measurementReport':
|
||||
new_meas = read_raw_ublox(m.ubloxGnss.measurementReport)
|
||||
if len(new_meas) > 0:
|
||||
return new_meas[0].recv_time
|
||||
else:
|
||||
if m.qcomGnss.which == 'measurementReport':
|
||||
new_meas = read_raw_qcom(m.qcomGnss.measurementReport)
|
||||
if len(new_meas) > 0:
|
||||
return new_meas[0].recv_time
|
||||
|
||||
|
||||
def get_measurement_mock(gpstime, sat_ephemeris):
|
||||
@@ -79,6 +126,7 @@ class TestLaikad(unittest.TestCase):
|
||||
logs, low_gnss = get_log(range(1))
|
||||
cls.logs = logs
|
||||
cls.low_gnss = low_gnss
|
||||
cls.logs_qcom = get_log_qcom(range(1))
|
||||
first_gps_time = get_first_gps_time(logs)
|
||||
cls.first_gps_time = first_gps_time
|
||||
|
||||
@@ -90,9 +138,9 @@ class TestLaikad(unittest.TestCase):
|
||||
laikad = Laikad()
|
||||
laikad.fetch_navs(gpstime, block=False)
|
||||
laikad.orbit_fetch_future.result(30)
|
||||
|
||||
# Get results and save orbits to laikad:
|
||||
laikad.fetch_navs(gpstime, block=False)
|
||||
|
||||
ephem = laikad.astro_dog.navs['G01'][0]
|
||||
self.assertIsNotNone(ephem)
|
||||
|
||||
@@ -105,6 +153,7 @@ class TestLaikad(unittest.TestCase):
|
||||
self.assertIsNotNone(ephem)
|
||||
self.assertNotEqual(ephem, ephem2)
|
||||
|
||||
|
||||
def test_fetch_navs_with_wrong_clocks(self):
|
||||
laikad = Laikad()
|
||||
|
||||
@@ -127,40 +176,11 @@ class TestLaikad(unittest.TestCase):
|
||||
check_has_navs()
|
||||
self.assertEqual(laikad.last_fetch_navs_t, real_current_time)
|
||||
|
||||
def test_ephemeris_source_in_msg(self):
|
||||
data_mock = defaultdict(str)
|
||||
data_mock['sv_id'] = 1
|
||||
|
||||
gpstime = GPS_TIME_PREDICTION_ORBITS_RUSSIAN_SRC
|
||||
laikad = Laikad()
|
||||
laikad.fetch_navs(gpstime, block=True)
|
||||
meas = get_measurement_mock(gpstime, laikad.astro_dog.navs['R01'][0])
|
||||
msg = create_measurement_msg(meas)
|
||||
self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nav)
|
||||
# Verify gps satellite returns same source
|
||||
meas = get_measurement_mock(gpstime, laikad.astro_dog.navs['R01'][0])
|
||||
msg = create_measurement_msg(meas)
|
||||
self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nav)
|
||||
|
||||
# Test nasa source by using older date
|
||||
gpstime = GPSTime.from_datetime(datetime(2021, month=3, day=1))
|
||||
laikad = Laikad()
|
||||
laikad.fetch_navs(gpstime, block=True)
|
||||
meas = get_measurement_mock(gpstime, laikad.astro_dog.navs['G01'][0])
|
||||
msg = create_measurement_msg(meas)
|
||||
self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nav)
|
||||
|
||||
# Test nav source type
|
||||
ephem = GPSEphemeris(data_mock, gpstime)
|
||||
meas = get_measurement_mock(gpstime, ephem)
|
||||
msg = create_measurement_msg(meas)
|
||||
self.assertEqual(msg.ephemerisSource.type.raw, EphemerisSourceType.nav)
|
||||
|
||||
def test_laika_online(self):
|
||||
laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT)
|
||||
correct_msgs = verify_messages(self.logs, laikad)
|
||||
|
||||
correct_msgs_expected = 554
|
||||
correct_msgs_expected = 560
|
||||
self.assertEqual(correct_msgs_expected, len(correct_msgs))
|
||||
self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid]))
|
||||
|
||||
@@ -177,12 +197,15 @@ class TestLaikad(unittest.TestCase):
|
||||
self.assertTrue(kf_valid)
|
||||
|
||||
def test_laika_online_nav_only(self):
|
||||
laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.NAV)
|
||||
# Disable fetch_orbits to test NAV only
|
||||
correct_msgs = verify_messages(self.logs, laikad)
|
||||
correct_msgs_expected = 554
|
||||
self.assertEqual(correct_msgs_expected, len(correct_msgs))
|
||||
self.assertEqual(correct_msgs_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid]))
|
||||
for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]):
|
||||
laikad = Laikad(auto_update=True, valid_ephem_types=EphemerisType.NAV, use_qcom=use_qcom)
|
||||
# Disable fetch_orbits to test NAV only
|
||||
correct_msgs = verify_messages(logs, laikad)
|
||||
correct_msgs_expected = 44 if use_qcom else 560
|
||||
valid_fix_expected = 43 if use_qcom else 560
|
||||
|
||||
self.assertEqual(correct_msgs_expected, len(correct_msgs))
|
||||
self.assertEqual(valid_fix_expected, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid]))
|
||||
|
||||
@mock.patch('laika.downloader.download_and_cache_file')
|
||||
def test_laika_offline(self, downloader_mock):
|
||||
@@ -195,8 +218,9 @@ class TestLaikad(unittest.TestCase):
|
||||
downloader_mock.side_effect = DownloadFailed
|
||||
laikad = Laikad(auto_update=False)
|
||||
correct_msgs = verify_messages(self.logs, laikad)
|
||||
self.assertEqual(0, len(correct_msgs))
|
||||
self.assertEqual(0, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid]))
|
||||
expected_msgs = 376
|
||||
self.assertEqual(expected_msgs, len(correct_msgs))
|
||||
self.assertEqual(expected_msgs, len([m for m in correct_msgs if m.gnssMeasurements.positionECEF.valid]))
|
||||
|
||||
def test_laika_get_orbits(self):
|
||||
laikad = Laikad(auto_update=False)
|
||||
@@ -212,65 +236,87 @@ class TestLaikad(unittest.TestCase):
|
||||
self.assertGreater(len(laikad.astro_dog.navs[prn]), 0)
|
||||
prn = "R01"
|
||||
self.assertGreater(len(laikad.astro_dog.navs[prn]), 0)
|
||||
print(min(laikad.astro_dog.navs[prn], key=lambda e: e.epoch).epoch.as_datetime())
|
||||
|
||||
def test_get_navs_in_process(self):
|
||||
laikad = Laikad(auto_update=False)
|
||||
has_navs = False
|
||||
for m in self.logs:
|
||||
laikad.process_gnss_msg(m.ubloxGnss, m.logMonoTime, block=False)
|
||||
if laikad.orbit_fetch_future is not None:
|
||||
laikad.orbit_fetch_future.result()
|
||||
vals = laikad.astro_dog.navs.values()
|
||||
has_navs = len(vals) > 0 and max([len(v) for v in vals]) > 0
|
||||
if has_navs:
|
||||
break
|
||||
self.assertTrue(has_navs)
|
||||
self.assertGreater(len(laikad.astro_dog.navs_fetched_times._ranges), 0)
|
||||
self.assertEqual(None, laikad.orbit_fetch_future)
|
||||
for auto_fetch_navs in [True, False]:
|
||||
for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]):
|
||||
laikad = Laikad(auto_update=False, use_qcom=use_qcom, auto_fetch_navs=auto_fetch_navs)
|
||||
has_navs = False
|
||||
has_fix = False
|
||||
seen_chip_eph = False
|
||||
seen_internet_eph = False
|
||||
|
||||
for m in logs:
|
||||
gnss_msg = m.qcomGnss if use_qcom else m.ubloxGnss
|
||||
out_msg = laikad.process_gnss_msg(gnss_msg, m.logMonoTime, block=False)
|
||||
if laikad.orbit_fetch_future is not None:
|
||||
laikad.orbit_fetch_future.result()
|
||||
vals = laikad.astro_dog.navs.values()
|
||||
has_navs = len(vals) > 0 and max([len(v) for v in vals]) > 0
|
||||
vals = laikad.astro_dog.qcom_polys.values()
|
||||
has_polys = len(vals) > 0 and max([len(v) for v in vals]) > 0
|
||||
has_fix = has_fix or out_msg.gnssMeasurements.positionECEF.valid
|
||||
if len(out_msg.gnssMeasurements.ephemerisStatuses):
|
||||
seen_chip_eph = seen_chip_eph or any([x.source == 'gnssChip' for x in out_msg.gnssMeasurements.ephemerisStatuses])
|
||||
seen_internet_eph = seen_internet_eph or any([x.source == 'internet' for x in out_msg.gnssMeasurements.ephemerisStatuses])
|
||||
|
||||
self.assertTrue(has_navs or has_polys)
|
||||
self.assertTrue(has_fix)
|
||||
self.assertTrue(seen_chip_eph or auto_fetch_navs)
|
||||
self.assertTrue(seen_internet_eph or not auto_fetch_navs)
|
||||
self.assertEqual(len(laikad.astro_dog.navs_fetched_times._ranges), 0)
|
||||
self.assertEqual(None, laikad.orbit_fetch_future)
|
||||
|
||||
def test_cache(self):
|
||||
laikad = Laikad(auto_update=True, save_ephemeris=True)
|
||||
use_qcom = True
|
||||
for use_qcom, logs in zip([True, False], [self.logs_qcom, self.logs]):
|
||||
laikad = Laikad(auto_update=True, save_ephemeris=True, use_qcom=use_qcom)
|
||||
def wait_for_cache():
|
||||
max_time = 2
|
||||
while Params().get(EPHEMERIS_CACHE) is None:
|
||||
time.sleep(0.1)
|
||||
max_time -= 0.1
|
||||
if max_time < 0:
|
||||
self.fail("Cache has not been written after 2 seconds")
|
||||
|
||||
def wait_for_cache():
|
||||
max_time = 2
|
||||
while Params().get(EPHEMERIS_CACHE) is None:
|
||||
time.sleep(0.1)
|
||||
max_time -= 0.1
|
||||
if max_time < 0:
|
||||
self.fail("Cache has not been written after 2 seconds")
|
||||
# Test cache with no ephemeris
|
||||
laikad.last_report_time = GPSTime(1,0)
|
||||
laikad.cache_ephemeris()
|
||||
wait_for_cache()
|
||||
Params().remove(EPHEMERIS_CACHE)
|
||||
|
||||
# Test cache with no ephemeris
|
||||
laikad.cache_ephemeris(t=GPSTime(0, 0))
|
||||
wait_for_cache()
|
||||
Params().remove(EPHEMERIS_CACHE)
|
||||
#laikad.astro_dog.get_navs(self.first_gps_time)
|
||||
msg = verify_messages(logs, laikad, return_one_success=True)
|
||||
laikad.cache_ephemeris()
|
||||
wait_for_cache()
|
||||
|
||||
#laikad.astro_dog.get_navs(self.first_gps_time)
|
||||
laikad.fetch_navs(self.first_gps_time, block=True)
|
||||
|
||||
# Wait for cache to save
|
||||
wait_for_cache()
|
||||
|
||||
# Check both nav and orbits separate
|
||||
laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.NAV, save_ephemeris=True)
|
||||
# Verify navs are loaded from cache
|
||||
self.dict_has_values(laikad.astro_dog.navs)
|
||||
# Verify cache is working for only nav by running a segment
|
||||
msg = verify_messages(self.logs, laikad, return_one_success=True)
|
||||
self.assertIsNotNone(msg)
|
||||
|
||||
with patch('selfdrive.locationd.laikad.get_orbit_data', return_value=None) as mock_method:
|
||||
# Verify no orbit downloads even if orbit fetch times is reset since the cache has recently been saved and we don't want to download high frequently
|
||||
laikad.astro_dog.orbit_fetched_times = TimeRangeHolder()
|
||||
laikad.fetch_navs(self.first_gps_time, block=False)
|
||||
mock_method.assert_not_called()
|
||||
|
||||
# Verify cache is working for only orbits by running a segment
|
||||
laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT, save_ephemeris=True)
|
||||
msg = verify_messages(self.logs, laikad, return_one_success=True)
|
||||
# Check both nav and orbits separate
|
||||
laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.NAV,
|
||||
save_ephemeris=True, use_qcom=use_qcom, auto_fetch_navs=False)
|
||||
# Verify navs are loaded from cache
|
||||
self.dict_has_values(laikad.astro_dog.navs)
|
||||
# Verify cache is working for only nav by running a segment
|
||||
msg = verify_messages(logs, laikad, return_one_success=True)
|
||||
self.assertTrue(len(msg.gnssMeasurements.ephemerisStatuses))
|
||||
self.assertTrue(any([x.source=='cache' for x in msg.gnssMeasurements.ephemerisStatuses]))
|
||||
self.assertIsNotNone(msg)
|
||||
# Verify orbit data is not downloaded
|
||||
mock_method.assert_not_called()
|
||||
|
||||
|
||||
|
||||
#TODO test cache with only orbits
|
||||
#with patch('selfdrive.locationd.laikad.get_orbit_data', return_value=None) as mock_method:
|
||||
# # Verify no orbit downloads even if orbit fetch times is reset since the cache has recently been saved and we don't want to download high frequently
|
||||
# laikad.astro_dog.orbit_fetched_times = TimeRangeHolder()
|
||||
# laikad.fetch_navs(self.first_gps_time, block=False)
|
||||
# mock_method.assert_not_called()
|
||||
|
||||
# # Verify cache is working for only orbits by running a segment
|
||||
# laikad = Laikad(auto_update=False, valid_ephem_types=EphemerisType.ULTRA_RAPID_ORBIT, save_ephemeris=True)
|
||||
# msg = verify_messages(self.logs, laikad, return_one_success=True)
|
||||
# self.assertIsNotNone(msg)
|
||||
# # Verify orbit data is not downloaded
|
||||
# mock_method.assert_not_called()
|
||||
#break
|
||||
|
||||
def test_low_gnss_meas(self):
|
||||
cnt = 0
|
||||
@@ -282,12 +328,10 @@ class TestLaikad(unittest.TestCase):
|
||||
gm = msg.gnssMeasurements
|
||||
if len(gm.correctedMeasurements) != 0 and gm.positionECEF.valid:
|
||||
cnt += 1
|
||||
self.assertEqual(cnt, 554)
|
||||
self.assertEqual(cnt, 560)
|
||||
|
||||
def dict_has_values(self, dct):
|
||||
self.assertGreater(len(dct), 0)
|
||||
self.assertGreater(min([len(v) for v in dct.values()]), 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -29,14 +29,14 @@ def manager_init() -> None:
|
||||
set_time(cloudlog)
|
||||
|
||||
# save boot log
|
||||
subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))
|
||||
subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"))
|
||||
|
||||
params = Params()
|
||||
params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START)
|
||||
|
||||
default_params: List[Tuple[str, Union[str, bytes]]] = [
|
||||
("CompletedTrainingVersion", "0"),
|
||||
("DisengageOnAccelerator", "1"),
|
||||
("DisengageOnAccelerator", "0"),
|
||||
("GsmMetered", "1"),
|
||||
("HasAcceptedTerms", "0"),
|
||||
("LanguageSetting", "main_en"),
|
||||
@@ -153,7 +153,7 @@ def manager_thread() -> None:
|
||||
for param in ("DoUninstall", "DoShutdown", "DoReboot"):
|
||||
if params.get_bool(param):
|
||||
shutdown = True
|
||||
params.put("LastManagerExitReason", param)
|
||||
params.put("LastManagerExitReason", f"{param} {datetime.datetime.now()}")
|
||||
cloudlog.warning(f"Shutting down manager - {param} set")
|
||||
|
||||
if shutdown:
|
||||
|
||||
@@ -17,11 +17,17 @@ def logging(started, params, CP: car.CarParams) -> bool:
|
||||
run = (not CP.notCar) or not params.get_bool("DisableLogging")
|
||||
return started and run
|
||||
|
||||
def ublox_available() -> bool:
|
||||
return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps')
|
||||
|
||||
def ublox(started, params, CP: car.CarParams) -> bool:
|
||||
use_ublox = os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps')
|
||||
use_ublox = ublox_available()
|
||||
params.put_bool("UbloxAvailable", use_ublox)
|
||||
return started and use_ublox
|
||||
|
||||
def qcomgps(started, params, CP: car.CarParams) -> bool:
|
||||
return started and not ublox_available()
|
||||
|
||||
procs = [
|
||||
# due to qualcomm kernel bugs SIGKILLing camerad sometimes causes page table corruption
|
||||
NativeProcess("camerad", "system/camerad", ["./camerad"], unkillable=True, callback=driverview),
|
||||
@@ -34,12 +40,12 @@ procs = [
|
||||
|
||||
DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"),
|
||||
NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld"], enabled=(not PC or WEBCAM), callback=driverview),
|
||||
NativeProcess("encoderd", "selfdrive/loggerd", ["./encoderd"]),
|
||||
NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"], onroad=False, callback=logging),
|
||||
NativeProcess("encoderd", "system/loggerd", ["./encoderd"]),
|
||||
NativeProcess("loggerd", "system/loggerd", ["./loggerd"], onroad=False, callback=logging),
|
||||
NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]),
|
||||
NativeProcess("mapsd", "selfdrive/navd", ["./map_renderer"], enabled=False),
|
||||
NativeProcess("navmodeld", "selfdrive/modeld", ["./navmodeld"], enabled=False),
|
||||
NativeProcess("sensord", "selfdrive/sensord", ["./sensord"], enabled=not PC),
|
||||
NativeProcess("sensord", "system/sensord", ["./sensord"], enabled=not PC),
|
||||
NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if not PC else None)),
|
||||
NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], offroad=True),
|
||||
NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]),
|
||||
@@ -47,21 +53,21 @@ procs = [
|
||||
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"),
|
||||
PythonProcess("torqued", "selfdrive.locationd.torqued"),
|
||||
PythonProcess("controlsd", "selfdrive.controls.controlsd"),
|
||||
PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True),
|
||||
PythonProcess("deleter", "system.loggerd.deleter", offroad=True),
|
||||
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview),
|
||||
PythonProcess("laikad", "selfdrive.locationd.laikad"),
|
||||
PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=TICI),
|
||||
PythonProcess("rawgpsd", "system.sensord.rawgps.rawgpsd", enabled=TICI, onroad=False, callback=qcomgps),
|
||||
PythonProcess("navd", "selfdrive.navd.navd"),
|
||||
PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True),
|
||||
PythonProcess("paramsd", "selfdrive.locationd.paramsd"),
|
||||
NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=TICI, onroad=False, callback=ublox),
|
||||
PythonProcess("pigeond", "selfdrive.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox),
|
||||
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], enabled=TICI, onroad=False, callback=ublox),
|
||||
PythonProcess("pigeond", "system.sensord.pigeond", enabled=TICI, onroad=False, callback=ublox),
|
||||
PythonProcess("plannerd", "selfdrive.controls.plannerd"),
|
||||
PythonProcess("radard", "selfdrive.controls.radard"),
|
||||
PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True),
|
||||
PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True),
|
||||
PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True),
|
||||
PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True),
|
||||
PythonProcess("uploader", "system.loggerd.uploader", offroad=True),
|
||||
PythonProcess("statsd", "selfdrive.statsd", offroad=True),
|
||||
|
||||
# debug procs
|
||||
|
||||
@@ -70,7 +70,7 @@ lenv.Program('_dmonitoringmodeld', [
|
||||
if use_thneed and arch == "larch64" or GetOption('pc_thneed'):
|
||||
fn = File("models/supercombo").abspath
|
||||
|
||||
tinygrad_opts = ["NATIVE_EXPLOG=1", "VALIDHACKS=1", "OPTWG=1", "IMAGE=2", "GPU=1", "CLCACHE=0"]
|
||||
tinygrad_opts = ["NATIVE_EXPLOG=1", "VALIDHACKS=1", "OPTLOCAL=1", "IMAGE=2", "GPU=1", "ENABLE_METHOD_CACHE=1"]
|
||||
if not GetOption('pc_thneed'):
|
||||
# use FLOAT16 on device for speed + don't cache the CL kernels for space
|
||||
tinygrad_opts += ["FLOAT16=1", "PYOPENCL_NO_CACHE=1"]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
To view the architecture of the ONNX networks, you can use [netron](https://netron.app/)
|
||||
|
||||
## Supercombo
|
||||
### Supercombo input format (Full size: 393738 x float32)
|
||||
### Supercombo input format (Full size: 799906 x float32)
|
||||
* **image stream**
|
||||
* Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256
|
||||
* Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256
|
||||
@@ -16,11 +16,11 @@ To view the architecture of the ONNX networks, you can use [netron](https://netr
|
||||
* Channel 4 represents the half-res U channel
|
||||
* Channel 5 represents the half-res V channel
|
||||
* **desire**
|
||||
* one-hot encoded vector to command model to execute certain actions, bit only needs to be sent for 1 frame : 8
|
||||
* one-hot encoded buffer to command model to execute certain actions, bit needs to be sent for the past 5 seconds (at 20FPS) : 100 * 8
|
||||
* **traffic convention**
|
||||
* one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2
|
||||
* **recurrent state**
|
||||
* The recurrent state vector that is fed back into the GRU for temporal context : 512
|
||||
* **feature buffer**
|
||||
* A buffer of intermediate features that gets appended to the current feature to form a 5 seconds temporal context (at 20FPS) : 99 * 128
|
||||
|
||||
|
||||
### Supercombo output format (Full size: XXX x float32)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:736ddc08497d7596bae4d9515a8efb996676be80e67a6d34d632bb8af2ed3fa9
|
||||
size 45962515
|
||||
oid sha256:5121deb0d5c683b0fbee4c1cad7bc625953bf127b1383fb7599a6b644efd0aea
|
||||
size 46011200
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ from system.swaglog import cloudlog
|
||||
from system.hardware import HARDWARE
|
||||
from common.file_helpers import atomic_write_in_dir
|
||||
from system.version import get_normalized_origin, get_short_branch, get_short_version, is_dirty
|
||||
from selfdrive.loggerd.config import STATS_DIR, STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S
|
||||
from system.loggerd.config import STATS_DIR, STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S
|
||||
|
||||
|
||||
class METRIC_TYPE:
|
||||
|
||||
@@ -1 +1 @@
|
||||
ba947edbb131a2a36ced7c490dfcf3280ad5b167
|
||||
82db08d52b155336e9a1dadd11485d5acdf2eba0
|
||||
|
||||
@@ -238,21 +238,12 @@ def torqued_rcv_callback(msg, CP, cfg, fsm):
|
||||
return recv_socks, fsm.frame == 0 or msg.which() == 'liveLocationKalman'
|
||||
|
||||
|
||||
def ublox_rcv_callback(msg):
|
||||
def ublox_rcv_callback(msg, CP, cfg, fsm):
|
||||
msg_class, msg_id = msg.ubloxRaw[2:4]
|
||||
if (msg_class, msg_id) in {(1, 7 * 16)}:
|
||||
return ["gpsLocationExternal"]
|
||||
return ["gpsLocationExternal"], True
|
||||
elif (msg_class, msg_id) in {(2, 1 * 16 + 5), (10, 9)}:
|
||||
return ["ubloxGnss"]
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def laika_rcv_callback(msg, CP, cfg, fsm):
|
||||
if msg.which() == 'ubloxGnss' and msg.ubloxGnss.which() == "measurementReport":
|
||||
return ["gnssMeasurements"], True
|
||||
elif msg.which() == 'qcomGnss' and msg.qcomGnss.which() == "drMeasurementReport":
|
||||
return ["gnssMeasurements"], True
|
||||
return ["ubloxGnss"], True
|
||||
else:
|
||||
return [], False
|
||||
|
||||
@@ -331,7 +322,7 @@ CONFIGS = [
|
||||
pub_sub={
|
||||
"cameraOdometry": ["liveLocationKalman"],
|
||||
"accelerometer": [], "gyroscope": [],
|
||||
"gpsLocationExternal": [], "liveCalibration": [], "carState": [],
|
||||
"gpsLocationExternal": [], "liveCalibration": [], "carState": [], "gpsLocation": [],
|
||||
},
|
||||
ignore=["logMonoTime", "valid"],
|
||||
init_callback=get_car_params,
|
||||
@@ -371,9 +362,9 @@ CONFIGS = [
|
||||
},
|
||||
ignore=["logMonoTime"],
|
||||
init_callback=get_car_params,
|
||||
should_recv_callback=laika_rcv_callback,
|
||||
should_recv_callback=None,
|
||||
tolerance=NUMPY_TOLERANCE,
|
||||
fake_pubsubmaster=True,
|
||||
fake_pubsubmaster=False,
|
||||
),
|
||||
ProcessConfig(
|
||||
proc_name="torqued",
|
||||
@@ -395,10 +386,10 @@ def replay_process(cfg, lr, fingerprint=None):
|
||||
if cfg.fake_pubsubmaster:
|
||||
return python_replay_process(cfg, lr, fingerprint)
|
||||
else:
|
||||
return cpp_replay_process(cfg, lr, fingerprint)
|
||||
return replay_process_with_sockets(cfg, lr, fingerprint)
|
||||
|
||||
|
||||
def setup_env(simulation=False, CP=None, cfg=None, controlsState=None):
|
||||
def setup_env(simulation=False, CP=None, cfg=None, controlsState=None, lr=None):
|
||||
params = Params()
|
||||
params.clear_all()
|
||||
params.put_bool("OpenpilotEnabledToggle", True)
|
||||
@@ -406,13 +397,19 @@ def setup_env(simulation=False, CP=None, cfg=None, controlsState=None):
|
||||
params.put_bool("DisengageOnAccelerator", True)
|
||||
params.put_bool("WideCameraOnly", False)
|
||||
params.put_bool("DisableLogging", False)
|
||||
params.put_bool("UbloxAvailable", True)
|
||||
params.put_bool("ObdMultiplexingDisabled", True)
|
||||
|
||||
os.environ["NO_RADAR_SLEEP"] = "1"
|
||||
os.environ["REPLAY"] = "1"
|
||||
os.environ['SKIP_FW_QUERY'] = ""
|
||||
os.environ['FINGERPRINT'] = ""
|
||||
os.environ["SKIP_FW_QUERY"] = ""
|
||||
os.environ["FINGERPRINT"] = ""
|
||||
|
||||
if lr is not None:
|
||||
services = {m.which() for m in lr}
|
||||
params.put_bool("UbloxAvailable", "ubloxGnss" in services)
|
||||
|
||||
if lr is not None:
|
||||
services = {m.which() for m in lr}
|
||||
params.put_bool("UbloxAvailable", "ubloxGnss" in services)
|
||||
|
||||
if cfg is not None:
|
||||
# Clear all custom processConfig environment variables
|
||||
@@ -449,9 +446,6 @@ def setup_env(simulation=False, CP=None, cfg=None, controlsState=None):
|
||||
if CP.openpilotLongitudinalControl:
|
||||
params.put_bool("ExperimentalLongitudinalEnabled", True)
|
||||
|
||||
# controlsd process configuration assume all routes are out of dashcam
|
||||
params.put_bool("DashcamOverride", True)
|
||||
|
||||
|
||||
def python_replay_process(cfg, lr, fingerprint=None):
|
||||
sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub]
|
||||
@@ -467,12 +461,6 @@ def python_replay_process(cfg, lr, fingerprint=None):
|
||||
all_msgs = sorted(lr, key=lambda msg: msg.logMonoTime)
|
||||
pub_msgs = [msg for msg in all_msgs if msg.which() in list(cfg.pub_sub.keys())]
|
||||
|
||||
# laikad needs decision between submaster ubloxGnss and qcomGnss, prio given to ubloxGnss
|
||||
if cfg.proc_name == "laikad":
|
||||
args = (*args, not any(m.which() == "ubloxGnss" for m in pub_msgs))
|
||||
service = "qcomGnss" if args[2] else "ubloxGnss"
|
||||
pub_msgs = [m for m in pub_msgs if m.which() == service or m.which() == 'clocks']
|
||||
|
||||
controlsState = None
|
||||
initialized = False
|
||||
for msg in lr:
|
||||
@@ -488,10 +476,10 @@ def python_replay_process(cfg, lr, fingerprint=None):
|
||||
if fingerprint is not None:
|
||||
os.environ['SKIP_FW_QUERY'] = "1"
|
||||
os.environ['FINGERPRINT'] = fingerprint
|
||||
setup_env(cfg=cfg, controlsState=controlsState)
|
||||
setup_env(cfg=cfg, controlsState=controlsState, lr=lr)
|
||||
else:
|
||||
CP = [m for m in lr if m.which() == 'carParams'][0].carParams
|
||||
setup_env(CP=CP, cfg=cfg, controlsState=controlsState)
|
||||
setup_env(CP=CP, cfg=cfg, controlsState=controlsState, lr=lr)
|
||||
|
||||
assert(type(managed_processes[cfg.proc_name]) is PythonProcess)
|
||||
managed_processes[cfg.proc_name].prepare()
|
||||
@@ -520,7 +508,7 @@ def python_replay_process(cfg, lr, fingerprint=None):
|
||||
recv_socks, should_recv = cfg.should_recv_callback(msg, CP, cfg, fsm)
|
||||
else:
|
||||
recv_socks = [s for s in cfg.pub_sub[msg.which()] if
|
||||
(fsm.frame + 1) % int(service_list[msg.which()].frequency / service_list[s].frequency) == 0]
|
||||
(fsm.frame + 1) % max(1, int(service_list[msg.which()].frequency / service_list[s].frequency)) == 0]
|
||||
should_recv = bool(len(recv_socks))
|
||||
|
||||
if msg.which() == 'can':
|
||||
@@ -543,49 +531,53 @@ def python_replay_process(cfg, lr, fingerprint=None):
|
||||
return log_msgs
|
||||
|
||||
|
||||
def cpp_replay_process(cfg, lr, fingerprint=None):
|
||||
sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub] # We get responses here
|
||||
def replay_process_with_sockets(cfg, lr, fingerprint=None):
|
||||
sub_sockets = [s for _, sub in cfg.pub_sub.items() for s in sub]
|
||||
pm = messaging.PubMaster(cfg.pub_sub.keys())
|
||||
|
||||
all_msgs = sorted(lr, key=lambda msg: msg.logMonoTime)
|
||||
pub_msgs = [msg for msg in all_msgs if msg.which() in list(cfg.pub_sub.keys())]
|
||||
log_msgs = []
|
||||
|
||||
# We need to fake SubMaster alive since we can't inject a fake clock
|
||||
setup_env(simulation=True, cfg=cfg)
|
||||
setup_env(simulation=True, cfg=cfg, lr=lr)
|
||||
|
||||
if cfg.proc_name == "laikad":
|
||||
ublox = Params().get_bool("UbloxAvailable")
|
||||
keys = set(cfg.pub_sub.keys()) - ({"qcomGnss", } if ublox else {"ubloxGnss", })
|
||||
pub_msgs = [msg for msg in pub_msgs if msg.which() in keys]
|
||||
|
||||
managed_processes[cfg.proc_name].prepare()
|
||||
managed_processes[cfg.proc_name].start()
|
||||
|
||||
log_msgs = []
|
||||
try:
|
||||
with Timeout(TIMEOUT, error_msg=f"timed out testing process {repr(cfg.proc_name)}"):
|
||||
while not all(pm.all_readers_updated(s) for s in cfg.pub_sub.keys()):
|
||||
# Wait for process to startup
|
||||
with Timeout(10, error_msg=f"timed out waiting for process to start: {repr(cfg.proc_name)}"):
|
||||
while not any(pm.all_readers_updated(s) for s in cfg.pub_sub.keys()):
|
||||
time.sleep(0)
|
||||
|
||||
# Make sure all subscribers are connected
|
||||
sockets = {s: messaging.sub_sock(s, timeout=2000) for s in sub_sockets}
|
||||
for s in sub_sockets:
|
||||
messaging.recv_one_or_none(sockets[s])
|
||||
# Make sure all subscribers are connected
|
||||
sockets = {s: messaging.sub_sock(s, timeout=2000) for s in sub_sockets}
|
||||
for s in sub_sockets:
|
||||
messaging.recv_one_or_none(sockets[s])
|
||||
|
||||
for i, msg in enumerate(pub_msgs):
|
||||
# Do the replay
|
||||
cnt = 0
|
||||
for msg in pub_msgs:
|
||||
with Timeout(TIMEOUT, error_msg=f"timed out testing process {repr(cfg.proc_name)}, {cnt}/{len(pub_msgs)} msgs done"):
|
||||
pm.send(msg.which(), msg.as_builder())
|
||||
while not pm.all_readers_updated(msg.which()):
|
||||
time.sleep(0)
|
||||
|
||||
resp_sockets = cfg.pub_sub[msg.which()] if cfg.should_recv_callback is None else cfg.should_recv_callback(msg)
|
||||
resp_sockets = cfg.pub_sub[msg.which()]
|
||||
if cfg.should_recv_callback is not None:
|
||||
resp_sockets, _ = cfg.should_recv_callback(msg, None, None, None)
|
||||
for s in resp_sockets:
|
||||
response = messaging.recv_one_retry(sockets[s])
|
||||
|
||||
if response is None:
|
||||
print(f"Warning, no response received {i}")
|
||||
else:
|
||||
|
||||
response = response.as_builder()
|
||||
response.logMonoTime = msg.logMonoTime
|
||||
response = response.as_reader()
|
||||
log_msgs.append(response)
|
||||
|
||||
if not len(resp_sockets): # We only need to wait if we didn't already wait for a response
|
||||
while not pm.all_readers_updated(msg.which()):
|
||||
time.sleep(0)
|
||||
m = messaging.recv_one_retry(sockets[s])
|
||||
m = m.as_builder()
|
||||
m.logMonoTime = msg.logMonoTime
|
||||
log_msgs.append(m.as_reader())
|
||||
cnt += 1
|
||||
finally:
|
||||
managed_processes[cfg.proc_name].signal(signal.SIGKILL)
|
||||
managed_processes[cfg.proc_name].stop()
|
||||
|
||||
@@ -1 +1 @@
|
||||
70753c5f491de7432ff22f4ef560820ce9919b2e
|
||||
50f1e873095fe2462d2aadb9c401bda76759c01c
|
||||
|
||||
@@ -18,7 +18,7 @@ from tools.lib.logreader import LogReader
|
||||
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
|
||||
("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 (INDI)
|
||||
("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR)
|
||||
("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2
|
||||
@@ -29,12 +29,12 @@ source_segments = [
|
||||
("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
|
||||
("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1
|
||||
("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
|
||||
|
||||
# Enable when port is tested and dashcamOnly is no longer set
|
||||
#("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.BRONCO_SPORT_MK1
|
||||
#("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS
|
||||
#("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.PASSAT_NMS
|
||||
]
|
||||
@@ -53,7 +53,6 @@ segments = [
|
||||
("SUBARU", "regen1E72BBDCED5|2022-09-27--15-55-31--0"),
|
||||
("GM", "regen45B05A80EF6|2022-09-27--15-57-22--0"),
|
||||
("GM2", "376bf99325883932|2022-10-27--13-41-22--1"),
|
||||
("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"),
|
||||
("NISSAN", "regenC19D899B46D|2022-09-27--15-59-13--0"),
|
||||
("VOLKSWAGEN", "regenD8F7AC4BD0D|2022-09-27--16-41-45--0"),
|
||||
("MAZDA", "regenFC3F9ECBB64|2022-09-27--16-03-09--0"),
|
||||
@@ -71,7 +70,7 @@ def run_test_process(data):
|
||||
res = None
|
||||
if not args.upload_only:
|
||||
lr = LogReader.from_bytes(lr_dat)
|
||||
res, log_msgs = test_process(cfg, lr, ref_log_path, cur_log_fn, args.ignore_fields, args.ignore_msgs)
|
||||
res, log_msgs = test_process(cfg, lr, segment, ref_log_path, cur_log_fn, args.ignore_fields, args.ignore_msgs)
|
||||
# save logs so we can upload when updating refs
|
||||
save_log(cur_log_fn, log_msgs)
|
||||
|
||||
@@ -89,7 +88,7 @@ def get_log_data(segment):
|
||||
return (segment, f.read())
|
||||
|
||||
|
||||
def test_process(cfg, lr, ref_log_path, new_log_path, ignore_fields=None, ignore_msgs=None):
|
||||
def test_process(cfg, lr, segment, ref_log_path, new_log_path, ignore_fields=None, ignore_msgs=None):
|
||||
if ignore_fields is None:
|
||||
ignore_fields = []
|
||||
if ignore_msgs is None:
|
||||
@@ -97,7 +96,10 @@ def test_process(cfg, lr, ref_log_path, new_log_path, ignore_fields=None, ignore
|
||||
|
||||
ref_log_msgs = list(LogReader(ref_log_path))
|
||||
|
||||
log_msgs = replay_process(cfg, lr)
|
||||
try:
|
||||
log_msgs = replay_process(cfg, lr)
|
||||
except Exception as e:
|
||||
raise Exception("failed on segment: " + segment) from e
|
||||
|
||||
# check to make sure openpilot is engaged in the route
|
||||
if cfg.proc_name == "controlsd":
|
||||
|
||||
@@ -15,7 +15,7 @@ from common.basedir import BASEDIR
|
||||
from common.timeout import Timeout
|
||||
from common.params import Params
|
||||
from selfdrive.controls.lib.events import EVENTS, ET
|
||||
from selfdrive.loggerd.config import ROOT
|
||||
from system.loggerd.config import ROOT
|
||||
from selfdrive.test.helpers import set_params_enabled, release_only
|
||||
from tools.lib.logreader import LogReader
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ CONFIGS = [
|
||||
},
|
||||
ignore=[],
|
||||
command="./ubloxd",
|
||||
path="selfdrive/locationd/",
|
||||
path="system/ubloxd",
|
||||
segment="0375fdf7b1ce594d|2019-06-13--08-32-25--3",
|
||||
wait_for_response=True
|
||||
),
|
||||
|
||||
@@ -18,7 +18,7 @@ from common.params import Params
|
||||
from common.realtime import DT_TRML, sec_since_boot
|
||||
from selfdrive.controls.lib.alertmanager import set_offroad_alert
|
||||
from system.hardware import HARDWARE, TICI, AGNOS
|
||||
from selfdrive.loggerd.config import get_available_percent
|
||||
from system.loggerd.config import get_available_percent
|
||||
from selfdrive.statsd import statlog
|
||||
from system.swaglog import cloudlog
|
||||
from selfdrive.thermald.power_monitoring import PowerMonitoring
|
||||
|
||||
@@ -10,7 +10,7 @@ import glob
|
||||
from typing import NoReturn
|
||||
|
||||
from common.file_helpers import mkdirs_exists_ok
|
||||
from selfdrive.loggerd.config import ROOT
|
||||
from system.loggerd.config import ROOT
|
||||
import selfdrive.sentry as sentry
|
||||
from system.swaglog import cloudlog
|
||||
from system.version import get_commit
|
||||
|
||||
@@ -24,8 +24,6 @@ const float MAX_PITCH = 50;
|
||||
const float MIN_PITCH = 0;
|
||||
const float MAP_SCALE = 2;
|
||||
|
||||
const float VALID_POS_STD = 50.0; // m
|
||||
|
||||
const QString ICON_SUFFIX = ".png";
|
||||
|
||||
MapWindow::MapWindow(const QMapboxGLSettings &settings) : m_settings(settings), velocity_filter(0, 10, 0.05) {
|
||||
@@ -125,42 +123,6 @@ void MapWindow::updateState(const UIState &s) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO should check a valid/status flag
|
||||
if (sm.updated("gnssMeasurements") && sm["gnssMeasurements"].getGnssMeasurements().getGpsWeek() > 0){
|
||||
auto laikad_location = sm["gnssMeasurements"].getGnssMeasurements();
|
||||
auto laikad_pos = laikad_location.getPositionECEF();
|
||||
auto laikad_pos_ecef = laikad_pos.getValue();
|
||||
auto laikad_pos_std = laikad_pos.getStd();
|
||||
auto laikad_velocity_ecef = laikad_location.getVelocityECEF().getValue();
|
||||
|
||||
laikad_valid = laikad_pos.getValid() && Eigen::Vector3d(laikad_pos_std[0], laikad_pos_std[1], laikad_pos_std[2]).norm() < VALID_POS_STD;
|
||||
|
||||
if (laikad_valid && !locationd_valid) {
|
||||
ECEF ecef = {.x = laikad_pos_ecef[0], .y = laikad_pos_ecef[1], .z = laikad_pos_ecef[2]};
|
||||
Geodetic laikad_pos_geodetic = ecef2geodetic(ecef);
|
||||
last_position = QMapbox::Coordinate(laikad_pos_geodetic.lat, laikad_pos_geodetic.lon);
|
||||
|
||||
// Compute NED velocity
|
||||
LocalCoord converter(ecef);
|
||||
ECEF next_ecef = {.x = ecef.x + laikad_velocity_ecef[0], .y = ecef.y + laikad_velocity_ecef[1], .z = ecef.z + laikad_velocity_ecef[2]};
|
||||
Eigen::VectorXd ned_vel = converter.ecef2ned(next_ecef).to_vector() - converter.ecef2ned(ecef).to_vector();
|
||||
|
||||
float velocity = ned_vel.norm();
|
||||
velocity_filter.update(velocity);
|
||||
|
||||
// Convert NED velocity to angle
|
||||
if (velocity > 1.0) {
|
||||
float new_bearing = fmod(RAD2DEG(atan2(ned_vel[1], ned_vel[0])) + 360.0, 360.0);
|
||||
if (last_bearing) {
|
||||
float delta = 0.1 * angle_difference(*last_bearing, new_bearing); // Smooth heading
|
||||
last_bearing = fmod(*last_bearing + delta + 360.0, 360.0);
|
||||
} else {
|
||||
last_bearing = new_bearing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sm.updated("navRoute") && sm["navRoute"].getNavRoute().getCoordinates().size()) {
|
||||
qWarning() << "Got new navRoute from navd. Opening map:" << allow_open;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ void DriverViewWindow::mouseReleaseEvent(QMouseEvent* e) {
|
||||
}
|
||||
|
||||
DriverViewScene::DriverViewScene(QWidget* parent) : sm({"driverStateV2"}), QWidget(parent) {
|
||||
face_img = loadPixmap("../assets/img_driver_face.png", {FACE_IMG_SIZE, FACE_IMG_SIZE});
|
||||
face_img = loadPixmap("../assets/img_driver_face_static.png", {FACE_IMG_SIZE, FACE_IMG_SIZE});
|
||||
}
|
||||
|
||||
void DriverViewScene::showEvent(QShowEvent* event) {
|
||||
|
||||
+15
-10
@@ -573,7 +573,10 @@ void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s)
|
||||
const int arc_l = 133;
|
||||
const float arc_t_default = 6.7;
|
||||
const float arc_t_extend = 12.0;
|
||||
QColor arc_color = QColor::fromRgbF(0.09, 0.945, 0.26, 0.4*(1.0-dm_fade_state)*(s->engaged()));
|
||||
QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(),
|
||||
0.545 + 0.4 * s->engaged(),
|
||||
0.545 - 0.285 * s->engaged(),
|
||||
0.4 * (1.0 - dm_fade_state));
|
||||
float delta_x = -scene.driver_pose_sins[1] * arc_l / 2;
|
||||
float delta_y = -scene.driver_pose_sins[0] * arc_l / 2;
|
||||
painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
|
||||
@@ -645,16 +648,18 @@ void AnnotatedCameraWidget::paintGL() {
|
||||
}
|
||||
|
||||
// Wide or narrow cam dependent on speed
|
||||
float v_ego = sm["carState"].getCarState().getVEgo();
|
||||
if ((v_ego < 10) || s->wide_cam_only) {
|
||||
wide_cam_requested = true;
|
||||
} else if (v_ego > 15) {
|
||||
wide_cam_requested = false;
|
||||
bool has_wide_cam = available_streams.count(VISION_STREAM_WIDE_ROAD);
|
||||
if (has_wide_cam) {
|
||||
float v_ego = sm["carState"].getCarState().getVEgo();
|
||||
if ((v_ego < 10) || available_streams.size() == 1) {
|
||||
wide_cam_requested = true;
|
||||
} else if (v_ego > 15) {
|
||||
wide_cam_requested = false;
|
||||
}
|
||||
wide_cam_requested = wide_cam_requested && sm["controlsState"].getControlsState().getExperimentalMode();
|
||||
// for replay of old routes, never go to widecam
|
||||
wide_cam_requested = wide_cam_requested && s->scene.calibration_wide_valid;
|
||||
}
|
||||
wide_cam_requested = wide_cam_requested && sm["controlsState"].getControlsState().getExperimentalMode();
|
||||
// TODO: also detect when ecam vision stream isn't available
|
||||
// for replay of old routes, never go to widecam
|
||||
wide_cam_requested = wide_cam_requested && s->scene.calibration_wide_valid;
|
||||
CameraWidget::setStreamType(wide_cam_requested ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD);
|
||||
|
||||
s->scene.wide_cam = CameraWidget::getStreamType() == VISION_STREAM_WIDE_ROAD;
|
||||
|
||||
@@ -11,14 +11,11 @@
|
||||
#define NVME "/dev/nvme0n1"
|
||||
#define USERDATA "/dev/disk/by-partlabel/userdata"
|
||||
|
||||
void Reset::doReset() {
|
||||
// best effort to wipe nvme and sd card
|
||||
void Reset::doErase() {
|
||||
// best effort to wipe nvme
|
||||
std::system("sudo umount " NVME);
|
||||
std::system("yes | sudo mkfs.ext4 " NVME);
|
||||
|
||||
// we handle two cases here
|
||||
// * user-prompted factory reset
|
||||
// * recovering from a corrupt userdata by formatting
|
||||
int rm = std::system("sudo rm -rf /data/*");
|
||||
std::system("sudo umount " USERDATA);
|
||||
int fmt = std::system("yes | sudo mkfs.ext4 " USERDATA);
|
||||
@@ -30,22 +27,26 @@ void Reset::doReset() {
|
||||
rebootBtn->show();
|
||||
}
|
||||
|
||||
void Reset::startReset() {
|
||||
body->setText(tr("Resetting device...\nThis may take up to a minute."));
|
||||
rejectBtn->hide();
|
||||
rebootBtn->hide();
|
||||
confirmBtn->hide();
|
||||
#ifdef __aarch64__
|
||||
QTimer::singleShot(100, this, &Reset::doErase);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Reset::confirm() {
|
||||
const QString confirm_txt = tr("Are you sure you want to reset your device?");
|
||||
if (body->text() != confirm_txt) {
|
||||
body->setText(confirm_txt);
|
||||
} else {
|
||||
body->setText(tr("Resetting device..."));
|
||||
rejectBtn->hide();
|
||||
rebootBtn->hide();
|
||||
confirmBtn->hide();
|
||||
#ifdef __aarch64__
|
||||
QTimer::singleShot(100, this, &Reset::doReset);
|
||||
#endif
|
||||
startReset();
|
||||
}
|
||||
}
|
||||
|
||||
Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) {
|
||||
Reset::Reset(ResetMode mode, QWidget *parent) : QWidget(parent) {
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||
main_layout->setContentsMargins(45, 220, 45, 45);
|
||||
main_layout->setSpacing(0);
|
||||
@@ -56,7 +57,7 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) {
|
||||
|
||||
main_layout->addSpacing(60);
|
||||
|
||||
body = new QLabel(tr("System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot."));
|
||||
body = new QLabel(tr("Press confirm to erase all content and settings. Press cancel to resume boot."));
|
||||
body->setWordWrap(true);
|
||||
body->setStyleSheet("font-size: 80px; font-weight: light;");
|
||||
main_layout->addWidget(body, 1, Qt::AlignTop | Qt::AlignLeft);
|
||||
@@ -82,10 +83,16 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) {
|
||||
blayout->addWidget(confirmBtn);
|
||||
QObject::connect(confirmBtn, &QPushButton::clicked, this, &Reset::confirm);
|
||||
|
||||
bool recover = mode == ResetMode::RECOVER;
|
||||
rejectBtn->setVisible(!recover);
|
||||
rebootBtn->setVisible(recover);
|
||||
if (recover) {
|
||||
body->setText(tr("Unable to mount data partition. Press confirm to reset your device."));
|
||||
body->setText(tr("Unable to mount data partition. Partition may be corrupted. Press confirm to erase and reset your device."));
|
||||
}
|
||||
|
||||
// automatically start if we're just finishing up an ABL reset
|
||||
if (mode == ResetMode::FORMAT) {
|
||||
startReset();
|
||||
}
|
||||
|
||||
setStyleSheet(R"(
|
||||
@@ -108,9 +115,17 @@ Reset::Reset(bool recover, QWidget *parent) : QWidget(parent) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
bool recover = argc > 1 && strcmp(argv[1], "--recover") == 0;
|
||||
ResetMode mode = ResetMode::USER_RESET;
|
||||
if (argc > 1) {
|
||||
if (strcmp(argv[1], "--recover") == 0) {
|
||||
mode = ResetMode::RECOVER;
|
||||
} else if (strcmp(argv[1], "--format") == 0) {
|
||||
mode = ResetMode::FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
QApplication a(argc, argv);
|
||||
Reset reset(recover);
|
||||
Reset reset(mode);
|
||||
setMainWindow(&reset);
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
@@ -2,18 +2,25 @@
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
enum ResetMode {
|
||||
USER_RESET, // user initiated a factory reset from openpilot
|
||||
RECOVER, // userdata is corrupt for some reason, give a chance to recover
|
||||
FORMAT, // finish up an ABL factory reset
|
||||
};
|
||||
|
||||
class Reset : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Reset(bool recover = false, QWidget *parent = 0);
|
||||
explicit Reset(ResetMode mode, QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QLabel *body;
|
||||
QPushButton *rejectBtn;
|
||||
QPushButton *rebootBtn;
|
||||
QPushButton *confirmBtn;
|
||||
void doReset();
|
||||
void doErase();
|
||||
void startReset();
|
||||
|
||||
private slots:
|
||||
void confirm();
|
||||
|
||||
@@ -34,7 +34,7 @@ bool is_elf(char *fname) {
|
||||
void Setup::download(QString url) {
|
||||
CURL *curl = curl_easy_init();
|
||||
if (!curl) {
|
||||
emit finished(false);
|
||||
emit finished(url, tr("Something went wrong. Reboot the device."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,15 +53,24 @@ void Setup::download(QString url) {
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, (USER_AGENT + version).c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
|
||||
|
||||
int ret = curl_easy_perform(curl);
|
||||
long res_status = 0;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_status);
|
||||
if (ret == CURLE_OK && res_status == 200 && is_elf(tmpfile)) {
|
||||
rename(tmpfile, "/tmp/installer");
|
||||
emit finished(true);
|
||||
|
||||
if (ret != CURLE_OK || res_status != 200) {
|
||||
emit finished(url, tr("Ensure the entered URL is valid, and the device’s internet connection is good."));
|
||||
} else if (!is_elf(tmpfile)) {
|
||||
emit finished(url, tr("No custom software found at this URL."));
|
||||
} else {
|
||||
emit finished(false);
|
||||
rename(tmpfile, "/tmp/installer");
|
||||
|
||||
FILE *fp_url = fopen("/tmp/installer_url", "w");
|
||||
fprintf(fp_url, "%s", url.toStdString().c_str());
|
||||
fclose(fp_url);
|
||||
|
||||
emit finished(url);
|
||||
}
|
||||
|
||||
curl_slist_free_all(list);
|
||||
@@ -234,10 +243,10 @@ QWidget * Setup::downloading() {
|
||||
return widget;
|
||||
}
|
||||
|
||||
QWidget * Setup::download_failed() {
|
||||
QWidget * Setup::download_failed(QLabel *url, QLabel *body) {
|
||||
QWidget *widget = new QWidget();
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(widget);
|
||||
main_layout->setContentsMargins(55, 225, 55, 55);
|
||||
main_layout->setContentsMargins(55, 185, 55, 55);
|
||||
main_layout->setSpacing(0);
|
||||
|
||||
QLabel *title = new QLabel(tr("Download Failed"));
|
||||
@@ -246,7 +255,13 @@ QWidget * Setup::download_failed() {
|
||||
|
||||
main_layout->addSpacing(67);
|
||||
|
||||
QLabel *body = new QLabel(tr("Ensure the entered URL is valid, and the device’s internet connection is good."));
|
||||
url->setWordWrap(true);
|
||||
url->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
url->setStyleSheet("font-family: \"JetBrains Mono\"; font-size: 64px; font-weight: 400; margin-right: 100px;");
|
||||
main_layout->addWidget(url);
|
||||
|
||||
main_layout->addSpacing(48);
|
||||
|
||||
body->setWordWrap(true);
|
||||
body->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
body->setStyleSheet("font-size: 80px; font-weight: 300; margin-right: 100px;");
|
||||
@@ -271,7 +286,7 @@ QWidget * Setup::download_failed() {
|
||||
restart->setProperty("primary", true);
|
||||
blayout->addWidget(restart);
|
||||
QObject::connect(restart, &QPushButton::clicked, this, [=]() {
|
||||
setCurrentIndex(2);
|
||||
setCurrentIndex(1);
|
||||
});
|
||||
|
||||
widget->setStyleSheet(R"(
|
||||
@@ -304,15 +319,19 @@ Setup::Setup(QWidget *parent) : QStackedWidget(parent) {
|
||||
downloading_widget = downloading();
|
||||
addWidget(downloading_widget);
|
||||
|
||||
failed_widget = download_failed();
|
||||
QLabel *url_label = new QLabel();
|
||||
QLabel *body_label = new QLabel();
|
||||
failed_widget = download_failed(url_label, body_label);
|
||||
addWidget(failed_widget);
|
||||
|
||||
QObject::connect(this, &Setup::finished, [=](bool success) {
|
||||
// hide setup on success
|
||||
qDebug() << "finished" << success;
|
||||
if (success) {
|
||||
QObject::connect(this, &Setup::finished, [=](const QString &url, const QString &error) {
|
||||
qDebug() << "finished" << url << error;
|
||||
if (error.isEmpty()) {
|
||||
// hide setup on success
|
||||
QTimer::singleShot(3000, this, &QWidget::hide);
|
||||
} else {
|
||||
url_label->setText(url);
|
||||
body_label->setText(error);
|
||||
setCurrentWidget(failed_widget);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStackedWidget>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
@@ -15,13 +16,13 @@ private:
|
||||
QWidget *getting_started();
|
||||
QWidget *network_setup();
|
||||
QWidget *downloading();
|
||||
QWidget *download_failed();
|
||||
QWidget *download_failed(QLabel *url, QLabel *body);
|
||||
|
||||
QWidget *failed_widget;
|
||||
QWidget *downloading_widget;
|
||||
|
||||
signals:
|
||||
void finished(bool success);
|
||||
void finished(const QString &url, const QString &error = "");
|
||||
|
||||
public slots:
|
||||
void nextPage();
|
||||
|
||||
@@ -96,8 +96,10 @@ mat4 get_fit_view_transform(float widget_aspect_ratio, float frame_aspect_ratio)
|
||||
CameraWidget::CameraWidget(std::string stream_name, VisionStreamType type, bool zoom, QWidget* parent) :
|
||||
stream_name(stream_name), requested_stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
qRegisterMetaType<std::set<VisionStreamType>>("availableStreams");
|
||||
QObject::connect(this, &CameraWidget::vipcThreadConnected, this, &CameraWidget::vipcConnected, Qt::BlockingQueuedConnection);
|
||||
QObject::connect(this, &CameraWidget::vipcThreadFrameReceived, this, &CameraWidget::vipcFrameReceived, Qt::QueuedConnection);
|
||||
QObject::connect(this, &CameraWidget::vipcAvailableStreamsUpdated, this, &CameraWidget::availableStreamsUpdated, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
CameraWidget::~CameraWidget() {
|
||||
@@ -181,6 +183,10 @@ void CameraWidget::stopVipcThread() {
|
||||
}
|
||||
}
|
||||
|
||||
void CameraWidget::availableStreamsUpdated(std::set<VisionStreamType> streams) {
|
||||
available_streams = streams;
|
||||
}
|
||||
|
||||
void CameraWidget::updateFrameMat() {
|
||||
int w = width(), h = height();
|
||||
|
||||
@@ -366,6 +372,13 @@ void CameraWidget::vipcThread() {
|
||||
|
||||
if (!vipc_client->connected) {
|
||||
clearFrames();
|
||||
auto streams = VisionIpcClient::getAvailableStreams(stream_name, false);
|
||||
if (streams.empty()) {
|
||||
QThread::msleep(100);
|
||||
continue;
|
||||
}
|
||||
emit vipcAvailableStreamsUpdated(streams);
|
||||
|
||||
if (!vipc_client->connect(false)) {
|
||||
QThread::msleep(100);
|
||||
continue;
|
||||
@@ -400,4 +413,5 @@ void CameraWidget::vipcThread() {
|
||||
void CameraWidget::clearFrames() {
|
||||
std::lock_guard lk(frame_lock);
|
||||
frames.clear();
|
||||
available_streams.clear();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user