dragonpilot 2022-08-19T01:11:48 for EON/C2

version: dragonpilot v0.8.16 beta for EON/C2
date: 2022-08-19T01:11:48
dp-dev(priv2) master commit: 4aee191bc9d1c5099913455ff9e5fa1c3a7a7903
pull/166/head
Dragonpilot Team 3 years ago committed by Comma Device
parent b437663252
commit 66006fe0e9
  1. 1
      .gitignore
  2. 6
      CHANGELOGS.md
  3. 2
      RELEASES.md
  4. 21
      cereal/.gitignore
  5. 2
      cereal/car.capnp
  6. BIN
      cereal/libcereal_shared.so
  7. BIN
      cereal/visionipc/visionipc_pyx.so
  8. 2
      common/dp_conf.py
  9. BIN
      common/params_pyx.so
  10. 2
      common/version.h
  11. 18
      docs/CARS.md
  12. 2
      opendbc/cadillac_ct6_powertrain.dbc
  13. BIN
      opendbc/can/libdbc.so
  14. 4
      opendbc/generator/gm/gm_global_a_powertrain.dbc
  15. 4
      opendbc/gm_global_a_powertrain_generated.dbc
  16. BIN
      panda/board/obj/bootstub.panda.bin
  17. BIN
      panda/board/obj/panda.bin.signed
  18. BIN
      panda/board/obj/panda.bin.sspoof.signed
  19. BIN
      panda/board/obj/panda.bin.testing.signed
  20. BIN
      panda/board/obj/panda.bin.testing.sspoof.signed
  21. 34
      panda/python/__init__.py
  22. BIN
      rednose/helpers/ekf_sym_pyx.so
  23. BIN
      selfdrive/boardd/boardd
  24. BIN
      selfdrive/boardd/boardd_api_impl.so
  25. 24
      selfdrive/car/chrysler/interface.py
  26. 55
      selfdrive/car/chrysler/values.py
  27. 12
      selfdrive/car/docs_definitions.py
  28. 15
      selfdrive/car/fw_versions.py
  29. 17
      selfdrive/car/gm/carcontroller.py
  30. 16
      selfdrive/car/gm/carstate.py
  31. 7
      selfdrive/car/gm/gmcan.py
  32. 41
      selfdrive/car/gm/interface.py
  33. 19
      selfdrive/car/gm/values.py
  34. 17
      selfdrive/car/honda/interface.py
  35. 2
      selfdrive/car/honda/values.py
  36. 14
      selfdrive/car/hyundai/carcontroller.py
  37. 18
      selfdrive/car/hyundai/carstate.py
  38. 0
      selfdrive/car/hyundai/hyundaicanfd.py
  39. 32
      selfdrive/car/hyundai/interface.py
  40. 26
      selfdrive/car/hyundai/values.py
  41. 1
      selfdrive/car/isotp_parallel_query.py
  42. 2
      selfdrive/car/mazda/values.py
  43. 12
      selfdrive/car/subaru/values.py
  44. 2
      selfdrive/car/torque_data/override.yaml
  45. 1
      selfdrive/car/torque_data/substitute.yaml
  46. 7
      selfdrive/car/toyota/carcontroller.py
  47. 7
      selfdrive/car/toyota/values.py
  48. 47
      selfdrive/car/volkswagen/carcontroller.py
  49. 52
      selfdrive/car/volkswagen/carstate.py
  50. 23
      selfdrive/car/volkswagen/interface.py
  51. 38
      selfdrive/car/volkswagen/mqbcan.py
  52. 67
      selfdrive/car/volkswagen/values.py
  53. 42
      selfdrive/car/volkswagen/volkswagencan.py
  54. 9
      selfdrive/controls/controlsd.py
  55. 4
      selfdrive/controls/lib/desire_helper.py
  56. 5
      selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py
  57. 21
      selfdrive/controls/lib/lateral_planner.py
  58. 4
      selfdrive/controls/plannerd.py
  59. BIN
      selfdrive/locationd/locationd
  60. BIN
      selfdrive/locationd/ubloxd
  61. 8
      selfdrive/mapd/lib/Route.py
  62. BIN
      selfdrive/modeld/_modeld
  63. BIN
      selfdrive/modeld/models/supercombo.thneed
  64. BIN
      selfdrive/modeld/thneed/compile
  65. BIN
      selfdrive/sensord/_sensord
  66. BIN
      selfdrive/ui/_ui
  67. BIN
      selfdrive/ui/qt/spinner
  68. BIN
      selfdrive/ui/qt/text
  69. BIN
      selfdrive/ui/soundd/_soundd
  70. 1
      selfdrive/ui/translations/languages.json
  71. BIN
      selfdrive/ui/translations/main_ja.qm
  72. 26
      selfdrive/ui/translations/main_ja.ts
  73. BIN
      selfdrive/ui/translations/main_ko.qm
  74. 18
      selfdrive/ui/translations/main_ko.ts
  75. BIN
      selfdrive/ui/translations/main_pt.qm
  76. 1939
      selfdrive/ui/translations/main_pt.ts
  77. BIN
      selfdrive/ui/translations/main_zh-CHS.qm
  78. 18
      selfdrive/ui/translations/main_zh-CHS.ts
  79. BIN
      selfdrive/ui/translations/main_zh-CHT.qm
  80. 18
      selfdrive/ui/translations/main_zh-CHT.ts
  81. BIN
      system/camerad/camerad
  82. BIN
      system/clocksd/clocksd

1
.gitignore vendored

@ -54,7 +54,6 @@ selfdrive/modeld/_dmonitoringmodeld
/src/ /src/
one one
/body/
openpilot openpilot
notebooks notebooks
xx xx

@ -1,5 +1,11 @@
dragonpilot [latest] - EON/C2 Release dragonpilot [latest] - EON/C2 Release
======================== ========================
* NEW: Synced to openpilot master 2022.08.15 commits.
* New driving model.
* NEW: Added back honda eps mod toggle.
dragonpilot 2022.08.17 - EON/C2 Release
========================
* NEW: Synced to openpilot master 2022.08.07 commits. * NEW: Synced to openpilot master 2022.08.07 commits.
* NEW: Added back auto shutdown toggle. * NEW: Added back auto shutdown toggle.
* NEW: Added back On-Road Dashcam toggle. (You should not replace this with your dashcam!!!) * NEW: Added back On-Road Dashcam toggle. (You should not replace this with your dashcam!!!)

@ -1,5 +1,7 @@
Version 0.8.16 (2022-XX-XX) Version 0.8.16 (2022-XX-XX)
======================== ========================
* Chevrolet Bolt EUV 2022-23 support thanks to JasonJShuler!
* Hyundai Ioniq 5 2022 support thanks to sunnyhaibin!
* Hyundai Kona Electric 2022 support thanks to sunnyhaibin! * Hyundai Kona Electric 2022 support thanks to sunnyhaibin!
* Subaru Outback 2020-22 support * Subaru Outback 2020-22 support

21
cereal/.gitignore vendored

@ -0,0 +1,21 @@
gen
node_modules
package-lock.json
*.tmp
*.pyc
__pycache__
.*.swp
.*.swo
*.os
*.o
*.a
test_runner
libmessaging.*
libmessaging_shared.*
services.h
.sconsign.dblite
libcereal_shared.*
.mypy_cache/
catch2/

@ -587,7 +587,7 @@ struct CarParams {
stellantis @25; stellantis @25;
faw @26; faw @26;
body @27; body @27;
hyundaiHDA2 @28; hyundaiCanfd @28;
} }
enum SteerControlType { enum SteerControlType {

Binary file not shown.

Binary file not shown.

@ -129,7 +129,7 @@ confs = [
# # hyundai # # hyundai
# {'name': 'dp_hkg_smart_mdps', 'default': False, 'type': 'Bool', 'conf_type': ['param']}, # {'name': 'dp_hkg_smart_mdps', 'default': False, 'type': 'Bool', 'conf_type': ['param']},
# # honda # # honda
# {'name': 'dp_honda_eps_mod', 'default': False, 'type': 'Bool', 'conf_type': ['param']}, {'name': 'dp_honda_eps_mod', 'default': False, 'type': 'Bool', 'conf_type': ['param']},
# {'name': 'dp_honda_kmh_display', 'default': False, 'type': 'Bool', 'conf_type': ['param']}, # {'name': 'dp_honda_kmh_display', 'default': False, 'type': 'Bool', 'conf_type': ['param']},
# # volkswagen # # volkswagen
# # {'name': 'dp_vw_panda', 'default': False, 'type': 'Bool', 'conf_type': ['param']}, # # {'name': 'dp_vw_panda', 'default': False, 'type': 'Bool', 'conf_type': ['param']},

Binary file not shown.

@ -1 +1 @@
#define COMMA_VERSION "2022.08.17" #define COMMA_VERSION "2022.08.19"

@ -19,7 +19,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
- [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns. - [![star](assets/icon-star-empty.svg)](##) - Limited ability to make tighter turns.
# 199 Supported Cars # 201 Supported Cars
|Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque| |Make|Model|Supported Package|openpilot ACC|Stop and Go|Steer to 0|Steering Torque|
|---|---|---|:---:|:---:|:---:|:---:| |---|---|---|:---:|:---:|:---:|:---:|
@ -33,6 +33,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|RS3 2018|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Audi|S3 2015-17|ACC + Lane Assist|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Cadillac|Escalade ESV 2016[<sup>1</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Cadillac|Escalade ESV 2016[<sup>1</sup>](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chevrolet|Bolt EUV 2022-23|Premier/Premier Redline Trim|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chevrolet|Volt 2017-18[<sup>1</sup>](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chevrolet|Volt 2017-18[<sup>1</sup>](#footnotes)|Adaptive Cruise Control|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2017-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Chrysler|Pacifica 2019-20|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -61,7 +62,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Honda|HR-V 2019-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|HR-V 2019-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Insight 2019-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Insight 2019-22|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Inspire 2018|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Inspire 2018|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Odyssey 2018-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Odyssey 2018-20|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Passport 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Passport 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Pilot 2016-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Pilot 2016-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Honda|Ridgeline 2017-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Honda|Ridgeline 2017-22|Honda Sensing|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
@ -69,6 +70,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Ioniq 5 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -93,7 +95,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Kia|EV6 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|EV6 2022|Highway Driving Assist II|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Kia|Forte 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|Forte 2019-21|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Kia|K5 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Kia|K5 2021-22|Smart Cruise Control (SCC)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -121,7 +123,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Lexus|NX Hybrid 2018-19|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|NX Hybrid 2018-19|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|NX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|NX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|RC 2017-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RC 2017-20|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|RX 2016-18|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX 2016-19|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|RX 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX 2020-22|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|RX Hybrid 2016-19|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX Hybrid 2016-19|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Lexus|RX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Lexus|RX Hybrid 2020-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -145,7 +147,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Subaru|XV 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)| |Subaru|XV 2018-19|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
|Subaru|XV 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Subaru|XV 2020-21|EyeSight Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Škoda|Kamiq 2021[<sup>5</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Kamiq 2021[<sup>5</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Škoda|Karoq 2019-21|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Karoq 2019-21[<sup>7</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Škoda|Kodiaq 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Kodiaq 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Škoda|Octavia 2015, 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Octavia 2015, 2018-19|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Škoda|Octavia RS 2016|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Škoda|Octavia RS 2016|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -190,7 +192,7 @@ A supported vehicle is one that just works when you install a comma device. Ever
|Toyota|RAV4 Hybrid 2017-18|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|RAV4 Hybrid 2017-18|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Toyota|RAV4 Hybrid 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|RAV4 Hybrid 2019-21|All|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Toyota|RAV4 Hybrid 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|RAV4 Hybrid 2022|All|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Toyota|Sienna 2018-20|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Toyota|Sienna 2018-20|All|[![star](assets/icon-star-half.svg)](##)[<sup>3</sup>](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Volkswagen|Arteon 2018-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Volkswagen|Arteon 2018-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Volkswagen|Arteon eHybrid 2020-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Volkswagen|Arteon eHybrid 2020-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
|Volkswagen|Arteon R 2020-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)| |Volkswagen|Arteon R 2020-22[<sup>7,8</sup>](#footnotes)|Driver Assistance|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
@ -229,8 +231,8 @@ A supported vehicle is one that just works when you install a comma device. Ever
<sup>3</sup>When the Driver Support Unit (DSU) is disconnected, openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). <b><i>NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).</i></b> <br /> <sup>3</sup>When the Driver Support Unit (DSU) is disconnected, openpilot Adaptive Cruise Control (ACC) will replace stock Adaptive Cruise Control (ACC). <b><i>NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).</i></b> <br />
<sup>4</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br /> <sup>4</sup>openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
<sup>5</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br /> <sup>5</sup>Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform. <br />
<sup>6</sup>Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform. <br /> <sup>6</sup>Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets. <br />
<sup>7</sup>Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). For the newer design, in the interim, choose "VW J533 Development" from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard. <br /> <sup>7</sup>Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway inside the dashboard, choose "VW J533 Development" from the vehicle drop-down for a suitable harness. (Some newer models are also observed to not have a J533 connector.) <br />
<sup>8</sup>Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.) <br /> <sup>8</sup>Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.) <br />
## Community Maintained Cars ## Community Maintained Cars

@ -182,7 +182,7 @@ BO_ 880 ASCMActiveCruiseControlStatus: 6 K124_ASCM
SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCSpeedSetpoint : 19|12@0+ (1,0) [0|0] "km/h" NEO SG_ ACCSpeedSetpoint : 19|12@0+ (0.0625,0) [0|255.9375] "km/h" NEO
SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO
SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO
SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO

Binary file not shown.

@ -138,6 +138,8 @@ BO_ 481 ASCMSteeringButton: 7 K124_ASCM
SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO
SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO
SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX
SG_ RollingCounter : 33|2@0+ (1,0) [0|3] "" NEO
SG_ SteeringButtonChecksum : 43|12@0+ (1,0) [0|255] "" NEO
BO_ 485 PSCMSteeringAngle: 8 K43_PSCM BO_ 485 PSCMSteeringAngle: 8 K43_PSCM
SG_ SteeringWheelAngle : 15|16@0- (0.0625,0) [-2047|2047] "deg" NEO SG_ SteeringWheelAngle : 15|16@0- (0.0625,0) [-2047|2047] "deg" NEO
@ -211,7 +213,7 @@ BO_ 880 ASCMActiveCruiseControlStatus: 6 K124_ASCM
SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCSpeedSetpoint : 19|12@0+ (1,0) [0|0] "km/h" NEO SG_ ACCSpeedSetpoint : 19|12@0+ (0.0625,0) [0|255.9375] "km/h" NEO
SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO
SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO
SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO

@ -158,6 +158,8 @@ BO_ 481 ASCMSteeringButton: 7 K124_ASCM
SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO
SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO
SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX
SG_ RollingCounter : 33|2@0+ (1,0) [0|3] "" NEO
SG_ SteeringButtonChecksum : 43|12@0+ (1,0) [0|255] "" NEO
BO_ 485 PSCMSteeringAngle: 8 K43_PSCM BO_ 485 PSCMSteeringAngle: 8 K43_PSCM
SG_ SteeringWheelAngle : 15|16@0- (0.0625,0) [-2047|2047] "deg" NEO SG_ SteeringWheelAngle : 15|16@0- (0.0625,0) [-2047|2047] "deg" NEO
@ -231,7 +233,7 @@ BO_ 880 ASCMActiveCruiseControlStatus: 6 K124_ASCM
SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCLeadCar : 44|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne2 : 32|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX SG_ ACCAlwaysOne : 0|1@0+ (1,0) [0|0] "" Vector__XXX
SG_ ACCSpeedSetpoint : 19|12@0+ (1,0) [0|0] "km/h" NEO SG_ ACCSpeedSetpoint : 19|12@0+ (0.0625,0) [0|255.9375] "km/h" NEO
SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO SG_ ACCGapLevel : 21|2@0+ (1,0) [0|0] "" NEO
SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO SG_ ACCResumeButton : 1|1@0+ (1,0) [0|0] "" NEO
SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO SG_ ACCCmdActive : 23|1@0+ (1,0) [0|0] "" NEO

Binary file not shown.

@ -150,7 +150,7 @@ class Panda:
SAFETY_STELLANTIS = 25 SAFETY_STELLANTIS = 25
SAFETY_FAW = 26 SAFETY_FAW = 26
SAFETY_BODY = 27 SAFETY_BODY = 27
SAFETY_HYUNDAI_HDA2 = 28 SAFETY_HYUNDAI_CANFD = 28
SERIAL_DEBUG = 0 SERIAL_DEBUG = 0
SERIAL_ESP = 1 SERIAL_ESP = 1
@ -200,10 +200,15 @@ class Panda:
FLAG_TESLA_POWERTRAIN = 1 FLAG_TESLA_POWERTRAIN = 1
FLAG_TESLA_LONG_CONTROL = 2 FLAG_TESLA_LONG_CONTROL = 2
FLAG_VOLKSWAGEN_LONG_CONTROL = 1
FLAG_CHRYSLER_RAM_DT = 1 FLAG_CHRYSLER_RAM_DT = 1
FLAG_CHRYSLER_RAM_HD = 2
FLAG_SUBARU_GEN2 = 1 FLAG_SUBARU_GEN2 = 1
FLAG_GM_HW_CAM = 1
def __init__(self, serial: Optional[str] = None, claim: bool = True): def __init__(self, serial: Optional[str] = None, claim: bool = True):
self._serial = serial self._serial = serial
self._handle = None self._handle = None
@ -335,9 +340,10 @@ class Panda:
except Exception: except Exception:
pass pass
def flash(self, fn=DEFAULT_FW_FN, code=None, reconnect=True): def flash(self, fn=None, code=None, reconnect=True):
if self._mcu_type == MCU_TYPE_H7 and fn == DEFAULT_FW_FN: if not fn:
fn = DEFAULT_H7_FW_FN fn = DEFAULT_H7_FW_FN if self._mcu_type == MCU_TYPE_H7 else DEFAULT_FW_FN
assert os.path.isfile(fn)
print("flash: main version is " + self.get_version()) print("flash: main version is " + self.get_version())
if not self.bootstub: if not self.bootstub:
self.reset(enter_bootstub=True) self.reset(enter_bootstub=True)
@ -358,18 +364,16 @@ class Panda:
self.reconnect() self.reconnect()
def recover(self, timeout: Optional[int] = None, reset: bool = True) -> bool: def recover(self, timeout: Optional[int] = None, reset: bool = True) -> bool:
dfu_serial = PandaDFU.st_serial_to_dfu_serial(self._serial, self._mcu_type)
if reset: if reset:
self.reset(enter_bootstub=True) self.reset(enter_bootstub=True)
self.reset(enter_bootloader=True) self.reset(enter_bootloader=True)
t_start = time.time() if not self.wait_for_dfu(dfu_serial, timeout=timeout):
while len(PandaDFU.list()) == 0:
print("waiting for DFU...")
time.sleep(0.1)
if timeout is not None and (time.time() - t_start) > timeout:
return False return False
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial, self._mcu_type)) dfu = PandaDFU(dfu_serial)
dfu.recover() dfu.recover()
# reflash after recover # reflash after recover
@ -377,6 +381,16 @@ class Panda:
self.flash() self.flash()
return True return True
@staticmethod
def wait_for_dfu(dfu_serial: str, timeout: Optional[int] = None) -> bool:
t_start = time.monotonic()
while dfu_serial not in PandaDFU.list():
print("waiting for DFU...")
time.sleep(0.1)
if timeout is not None and (time.monotonic() - t_start) > timeout:
return False
return True
@staticmethod @staticmethod
def list(): def list():
context = usb1.USBContext() context = usb1.USBContext()

Binary file not shown.

Binary file not shown.

@ -2,7 +2,7 @@
from cereal import car from cereal import car
from panda import Panda from panda import Panda
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.chrysler.values import CAR, DBC, RAM_CARS from selfdrive.car.chrysler.values import CAR, DBC, RAM_HD, RAM_DT
from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.interfaces import CarInterfaceBase
@ -12,14 +12,20 @@ class CarInterface(CarInterfaceBase):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "chrysler" ret.carName = "chrysler"
ret.radarOffCan = DBC[candidate]['radar'] is None ret.dashcamOnly = candidate in RAM_HD
param = Panda.FLAG_CHRYSLER_RAM_DT if candidate in RAM_CARS else None ret.radarOffCan = DBC[candidate]['radar'] is None
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler, param)]
ret.steerActuatorDelay = 0.1 ret.steerActuatorDelay = 0.1
ret.steerLimitTimer = 0.4 ret.steerLimitTimer = 0.4
# safety config
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.chrysler)]
if candidate in RAM_HD:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_CHRYSLER_RAM_HD
elif candidate in RAM_DT:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_CHRYSLER_RAM_DT
ret.minSteerSpeed = 3.8 # m/s ret.minSteerSpeed = 3.8 # m/s
if candidate in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019): if candidate in (CAR.PACIFICA_2019_HYBRID, CAR.PACIFICA_2020, CAR.JEEP_CHEROKEE_2019):
# TODO: allow 2019 cars to steer down to 13 m/s if already engaged. # TODO: allow 2019 cars to steer down to 13 m/s if already engaged.
@ -47,18 +53,24 @@ class CarInterface(CarInterfaceBase):
# Ram # Ram
elif candidate == CAR.RAM_1500: elif candidate == CAR.RAM_1500:
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
ret.wheelbase = 3.88 ret.wheelbase = 3.88
ret.steerRatio = 16.3 ret.steerRatio = 16.3
ret.mass = 2493. + STD_CARGO_KG ret.mass = 2493. + STD_CARGO_KG
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
ret.minSteerSpeed = 14.5 ret.minSteerSpeed = 14.5
if car_fw is not None: if car_fw is not None:
for fw in car_fw: for fw in car_fw:
if fw.ecu == 'eps' and fw.fwVersion in (b"68312176AE", b"68312176AG", b"68273275AG"): if fw.ecu == 'eps' and fw.fwVersion in (b"68312176AE", b"68312176AG", b"68273275AG"):
ret.minSteerSpeed = 0. ret.minSteerSpeed = 0.
elif candidate == CAR.RAM_HD:
ret.steerActuatorDelay = 0.2
ret.wheelbase = 3.785
ret.steerRatio = 15.61
ret.mass = 3405. + STD_CARGO_KG
ret.minSteerSpeed = 16
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning, 1.0, False)
else: else:
raise ValueError(f"Unsupported car: {candidate}") raise ValueError(f"Unsupported car: {candidate}")

@ -22,23 +22,30 @@ class CAR:
# Ram # Ram
RAM_1500 = "RAM 1500 5TH GEN" RAM_1500 = "RAM 1500 5TH GEN"
RAM_HD = "RAM HD 5TH GEN"
class CarControllerParams: class CarControllerParams:
def __init__(self, CP): def __init__(self, CP):
self.STEER_MAX = 261 # higher than this faults the EPS on Chrysler/Jeep. Ram DT allows more
self.STEER_ERROR_MAX = 80 self.STEER_ERROR_MAX = 80
if CP.carFingerprint in RAM_HD:
if CP.carFingerprint in RAM_CARS: self.STEER_DELTA_UP = 14
self.STEER_DELTA_DOWN = 14
self.STEER_MAX = 361 # higher than this faults the EPS
elif CP.carFingerprint in RAM_DT:
self.STEER_DELTA_UP = 6 self.STEER_DELTA_UP = 6
self.STEER_DELTA_DOWN = 6 self.STEER_DELTA_DOWN = 6
self.STEER_MAX = 261 # EPS allows more, up to 350?
else: else:
self.STEER_DELTA_UP = 3 self.STEER_DELTA_UP = 3
self.STEER_DELTA_DOWN = 3 self.STEER_DELTA_DOWN = 3
self.STEER_MAX = 261 # higher than this faults the EPS
STEER_THRESHOLD = 120 STEER_THRESHOLD = 120
RAM_CARS = {CAR.RAM_1500, } RAM_DT = {CAR.RAM_1500, }
RAM_HD = {CAR.RAM_HD, }
RAM_CARS = RAM_DT | RAM_HD
@dataclass @dataclass
class ChryslerCarInfo(CarInfo): class ChryslerCarInfo(CarInfo):
@ -57,6 +64,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: 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.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-22", harness=Harness.ram),
CAR.RAM_HD: [
ChryslerCarInfo("Ram 2500 2020-22", harness=Harness.ram),
ChryslerCarInfo("Ram 3500 2020-22", harness=Harness.ram),
],
} }
# Unique CAN messages: # Unique CAN messages:
@ -177,6 +188,41 @@ FW_VERSIONS = {
b'68500483AB', b'68500483AB',
], ],
}, },
CAR.RAM_HD: {
(Ecu.combinationMeter, 0x742, None): [
b'68361606AH',
b'68492693AD',
],
(Ecu.srs, 0x744, None): [
b'68399794AC',
b'68428503AA',
b'68428505AA',
],
(Ecu.esp, 0x747, None): [
b'68334977AH',
b'68504022AB',
b'68530686AB',
],
(Ecu.fwdRadar, 0x753, None): [
b'04672895AB',
b'56029827AG',
b'68484694AE',
],
(Ecu.eps, 0x761, None): [
b'68421036AC',
b'68507906AB',
],
(Ecu.engine, 0x7e0, None): [
b'52421132AF',
b'M2370131MB',
b'M2421132MB',
],
(Ecu.gateway, 0x18DACBF1, None): [
b'68488419AB',
b'68535476AB',
],
},
} }
DBC = { DBC = {
@ -188,4 +234,5 @@ DBC = {
CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'),
CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'), CAR.JEEP_CHEROKEE_2019: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'),
CAR.RAM_1500: dbc_dict('chrysler_ram_dt_generated', None), CAR.RAM_1500: dbc_dict('chrysler_ram_dt_generated', None),
CAR.RAM_HD: dbc_dict('chrysler_ram_hd_generated', None),
} }

@ -10,6 +10,10 @@ from common.conversions import Conversions as CV
GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2 GOOD_TORQUE_THRESHOLD = 1.0 # m/s^2
MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)" MODEL_YEARS_RE = r"(?<= )((\d{4}-\d{2})|(\d{4}))(,|$)"
# Makes that lack auto-resume with stock long, and auto resume in any configuration
NO_AUTO_RESUME_STOCK_LONG = {"toyota", "gm"}
NO_AUTO_RESUME = NO_AUTO_RESUME_STOCK_LONG | {"nissan", "subaru"}
class Tier(Enum): class Tier(Enum):
GOLD = 0 GOLD = 0
@ -147,11 +151,11 @@ class CarInfo:
else: else:
alc = "" alc = ""
# Exception for Nissan, Subaru, and stock long Toyota which do not auto-resume yet # Exception for cars which do not auto-resume yet
acc = "" acc = ""
if self.min_enable_speed > 0: if self.min_enable_speed > 0:
acc = f" <strong>while driving above {self.min_enable_speed * CV.MS_TO_MPH:.0f} mph</strong>" acc = f" <strong>while driving above {self.min_enable_speed * CV.MS_TO_MPH:.0f} mph</strong>"
elif CP.carName not in ("nissan", "subaru", "toyota") or (CP.carName == "toyota" and CP.openpilotLongitudinalControl): elif CP.carName not in NO_AUTO_RESUME or (CP.carName in NO_AUTO_RESUME_STOCK_LONG and CP.openpilotLongitudinalControl):
acc = " <strong>that automatically resumes from a stop</strong>" acc = " <strong>that automatically resumes from a stop</strong>"
if self.row[Column.STEERING_TORQUE] != Star.FULL: if self.row[Column.STEERING_TORQUE] != Star.FULL:
@ -186,7 +190,8 @@ class Harness(Enum):
bosch_a = "Honda Bosch A" bosch_a = "Honda Bosch A"
bosch_b = "Honda Bosch B" bosch_b = "Honda Bosch B"
toyota = "Toyota" toyota = "Toyota"
subaru = "Subaru" subaru_a = "Subaru A"
subaru_b = "Subaru B"
fca = "FCA" fca = "FCA"
ram = "Ram" ram = "Ram"
vw = "VW" vw = "VW"
@ -209,6 +214,7 @@ class Harness(Enum):
hyundai_p = "Hyundai P" hyundai_p = "Hyundai P"
custom = "Developer" custom = "Developer"
obd_ii = "OBD-II" obd_ii = "OBD-II"
gm = "GM"
nissan_a = "Nissan A" nissan_a = "Nissan A"
nissan_b = "Nissan B" nissan_b = "Nissan B"
mazda = "Mazda" mazda = "Mazda"

@ -337,16 +337,20 @@ def match_fw_to_car_exact(fw_versions_dict):
return set(candidates.keys()) - set(invalid) return set(candidates.keys()) - set(invalid)
def match_fw_to_car(fw_versions, allow_fuzzy=True): def match_fw_to_car(fw_versions, allow_exact=True, allow_fuzzy=True):
# Try exact matching first # Try exact matching first
exact_matches = []
if allow_exact:
exact_matches = [(True, match_fw_to_car_exact)] exact_matches = [(True, match_fw_to_car_exact)]
if allow_fuzzy: if allow_fuzzy:
exact_matches.append((False, match_fw_to_car_fuzzy)) exact_matches.append((False, match_fw_to_car_fuzzy))
brands = get_interface_attr('FW_VERSIONS', ignore_none=True).keys()
for exact_match, match_func in exact_matches: for exact_match, match_func in exact_matches:
# TODO: For each brand, attempt to fingerprint using only FW returned from its queries # For each brand, attempt to fingerprint using all FW returned from its queries
matches = set() matches = set()
fw_versions_dict = build_fw_dict(fw_versions, filter_brand=None) for brand in brands:
fw_versions_dict = build_fw_dict(fw_versions, filter_brand=brand)
matches |= match_func(fw_versions_dict) matches |= match_func(fw_versions_dict)
if len(matches): if len(matches):
@ -416,9 +420,8 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa
for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True): 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, debug=debug, progress=progress) car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, debug=debug, progress=progress)
all_car_fw.extend(car_fw) all_car_fw.extend(car_fw)
# Try to match using FW returned from this brand only
# TODO: Until erroneous FW versions are removed, try to fingerprint on all possible combinations so far matches = match_fw_to_car_exact(build_fw_dict(car_fw))
_, matches = match_fw_to_car(all_car_fw, allow_fuzzy=False)
if len(matches) == 1: if len(matches) == 1:
break break

@ -5,7 +5,7 @@ from common.realtime import DT_CTRL
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car import apply_std_steer_torque_limits
from selfdrive.car.gm import gmcan from selfdrive.car.gm import gmcan
from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, EV_CAR from selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons, EV_CAR
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@ -19,6 +19,7 @@ class CarController:
self.apply_gas = 0 self.apply_gas = 0
self.apply_brake = 0 self.apply_brake = 0
self.frame = 0 self.frame = 0
self.last_button_frame = 0
self.lka_steering_cmd_counter_last = -1 self.lka_steering_cmd_counter_last = -1
self.lka_icon_status_last = (False, False) self.lka_icon_status_last = (False, False)
@ -46,8 +47,7 @@ class CarController:
if CS.lka_steering_cmd_counter != self.lka_steering_cmd_counter_last: if CS.lka_steering_cmd_counter != self.lka_steering_cmd_counter_last:
self.lka_steering_cmd_counter_last = CS.lka_steering_cmd_counter self.lka_steering_cmd_counter_last = CS.lka_steering_cmd_counter
elif (self.frame % self.params.STEER_STEP) == 0: elif (self.frame % self.params.STEER_STEP) == 0:
lkas_enabled = CC.latActive and CS.out.vEgo > self.params.MIN_STEER_SPEED if CC.latActive:
if lkas_enabled:
new_steer = int(round(actuators.steer * self.params.STEER_MAX)) 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_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
else: else:
@ -58,7 +58,7 @@ class CarController:
# moment of disengaging, increment the counter based on the last message known to pass Panda safety checks. # moment of disengaging, increment the counter based on the last message known to pass Panda safety checks.
idx = (CS.lka_steering_cmd_counter + 1) % 4 idx = (CS.lka_steering_cmd_counter + 1) % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled)) can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive))
if self.CP.openpilotLongitudinalControl: if self.CP.openpilotLongitudinalControl:
# Gas/regen, brakes, and UI commands - all at 25Hz # Gas/regen, brakes, and UI commands - all at 25Hz
@ -107,6 +107,13 @@ class CarController:
if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0: if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0:
can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN) can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN)
else:
# Stock longitudinal, integrated at camera
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
if CC.cruiseControl.cancel:
self.last_button_frame = self.frame
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CruiseButtons.CANCEL))
# Show green icon when LKA torque is applied, and # Show green icon when LKA torque is applied, and
# alarming orange icon when approaching torque limit. # alarming orange icon when approaching torque limit.
# If not sent again, LKA icon disappears in about 5 seconds. # If not sent again, LKA icon disappears in about 5 seconds.
@ -114,6 +121,8 @@ class CarController:
lka_active = CS.lkas_status == 1 lka_active = CS.lkas_status == 1
lka_critical = lka_active and abs(actuators.steer) > 0.9 lka_critical = lka_active and abs(actuators.steer) > 0.9
lka_icon_status = (lka_active, lka_critical) lka_icon_status = (lka_active, lka_critical)
# SW_GMLAN not yet on cam harness, no HUD alerts
if self.CP.networkLocation != NetworkLocation.fwdCamera and (self.frame % self.params.CAMERA_KEEPALIVE_STEP == 0 or lka_icon_status != self.lka_icon_status_last): if self.CP.networkLocation != NetworkLocation.fwdCamera and (self.frame % self.params.CAMERA_KEEPALIVE_STEP == 0 or lka_icon_status != self.lka_icon_status_last):
steer_alert = hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw) steer_alert = hud_alert in (VisualAlert.steerRequired, VisualAlert.ldw)
can_sends.append(gmcan.create_lka_icon_command(CanBus.SW_GMLAN, lka_active, lka_critical, steer_alert)) can_sends.append(gmcan.create_lka_icon_command(CanBus.SW_GMLAN, lka_active, lka_critical, steer_alert))

@ -1,4 +1,5 @@
from cereal import car from cereal import car
from common.conversions import Conversions as CV
from common.numpy_fast import mean from common.numpy_fast import mean
from opendbc.can.can_define import CANDefine from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
@ -6,6 +7,7 @@ from selfdrive.car.interfaces import CarStateBase
from selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD from selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD
TransmissionType = car.CarParams.TransmissionType TransmissionType = car.CarParams.TransmissionType
NetworkLocation = car.CarParams.NetworkLocation
class CarState(CarStateBase): class CarState(CarStateBase):
@ -15,7 +17,7 @@ class CarState(CarStateBase):
self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"] self.shifter_values = can_define.dv["ECMPRDNL2"]["PRNDL2"]
self.lka_steering_cmd_counter = 0 self.lka_steering_cmd_counter = 0
def update(self, pt_cp, loopback_cp): def update(self, pt_cp, cam_cp, loopback_cp):
ret = car.CarState.new_message() ret = car.CarState.new_message()
self.prev_cruise_buttons = self.cruise_buttons self.prev_cruise_buttons = self.cruise_buttons
@ -77,9 +79,21 @@ class CarState(CarStateBase):
ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF ret.cruiseState.enabled = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] != AccState.OFF
ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL ret.cruiseState.standstill = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.STANDSTILL
if self.CP.networkLocation == NetworkLocation.fwdCamera:
ret.cruiseState.speed = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] * CV.KPH_TO_MS
return ret return ret
@staticmethod
def get_cam_can_parser(CP):
signals = []
checks = []
if CP.networkLocation == NetworkLocation.fwdCamera:
signals.append(("ACCSpeedSetpoint", "ASCMActiveCruiseControlStatus"))
checks.append(("ASCMActiveCruiseControlStatus", 25))
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CanBus.CAMERA)
@staticmethod @staticmethod
def get_can_parser(CP): def get_can_parser(CP):
signals = [ signals = [

@ -1,5 +1,9 @@
from selfdrive.car import make_can_msg from selfdrive.car import make_can_msg
def create_buttons(packer, bus, button):
values = {"ACCButtons": button}
return packer.make_can_msg("ASCMSteeringButton", bus, values)
def create_steering_control(packer, bus, apply_steer, idx, lkas_active): def create_steering_control(packer, bus, apply_steer, idx, lkas_active):
values = { values = {
@ -59,8 +63,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, near_stop, at_f
return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values) return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values)
def create_acc_dashboard_command(packer, bus, acc_engaged, target_speed_kph, lead_car_in_sight, fcw): def create_acc_dashboard_command(packer, bus, acc_engaged, target_speed_kph, lead_car_in_sight, fcw):
# Not a bit shift, dash can round up based on low 4 bits. target_speed = min(target_speed_kph, 255)
target_speed = int(target_speed_kph * 16) & 0xfff
values = { values = {
"ACCAlwaysOne" : 1, "ACCAlwaysOne" : 1,

@ -1,10 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from cereal import car from cereal import car
from math import fabs from math import fabs
from panda import Panda
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams from selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR
from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.interfaces import CarInterfaceBase
ButtonType = car.CarState.ButtonEvent.Type ButtonType = car.CarState.ButtonEvent.Type
@ -48,29 +49,36 @@ class CarInterface(CarInterfaceBase):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "gm" ret.carName = "gm"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
ret.pcmCruise = False # For ASCM, stock non-adaptive cruise control is kept off
ret.radarOffCan = False # For ASCM, radar exists if candidate in EV_CAR:
ret.transmissionType = TransmissionType.direct
else:
ret.transmissionType = TransmissionType.automatic ret.transmissionType = TransmissionType.automatic
# NetworkLocation.gateway: OBD-II harness (typically ASCM), NetworkLocation.fwdCamera: non-ASCM
if candidate in CAMERA_ACC_CAR:
ret.openpilotLongitudinalControl = False
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarOffCan = True # no radar
ret.pcmCruise = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM
else: # ASCM, OBD-II harness
ret.openpilotLongitudinalControl = True
ret.networkLocation = NetworkLocation.gateway ret.networkLocation = NetworkLocation.gateway
ret.radarOffCan = False
ret.pcmCruise = False # stock non-adaptive cruise control is kept off
# These cars have been put into dashcam only due to both a lack of users and test coverage. # 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 # 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. # 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} ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL}
# Presence of a camera on the object bus is ok.
# Have to go to read_only if ASCM is online (ACC-enabled cars),
# or camera is on powertrain bus (LKA cars without ACC).
ret.openpilotLongitudinalControl = True
tire_stiffness_factor = 0.444 # not optimized yet
# Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below.
ret.minSteerSpeed = 7 * CV.MPH_TO_MS ret.minSteerSpeed = 7 * CV.MPH_TO_MS
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.00]]
ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594 ret.lateralTuning.pid.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594
ret.steerActuatorDelay = 0.1 # Default delay, not measured yet ret.steerActuatorDelay = 0.1 # Default delay, not measured yet
tire_stiffness_factor = 0.444 # not optimized yet
ret.longitudinalTuning.kpBP = [5., 35.] ret.longitudinalTuning.kpBP = [5., 35.]
ret.longitudinalTuning.kpV = [2.4, 1.5] ret.longitudinalTuning.kpV = [2.4, 1.5]
@ -84,7 +92,6 @@ class CarInterface(CarInterfaceBase):
ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.minEnableSpeed = 18 * CV.MPH_TO_MS
if candidate == CAR.VOLT: if candidate == CAR.VOLT:
ret.transmissionType = TransmissionType.direct
ret.mass = 1607. + STD_CARGO_KG ret.mass = 1607. + STD_CARGO_KG
ret.wheelbase = 2.69 ret.wheelbase = 2.69
ret.steerRatio = 17.7 # Stock 15.7, LiveParameters ret.steerRatio = 17.7 # Stock 15.7, LiveParameters
@ -143,6 +150,16 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kf = 0.000045 ret.lateralTuning.pid.kf = 0.000045
tire_stiffness_factor = 1.0 tire_stiffness_factor = 1.0
elif candidate == CAR.BOLT_EUV:
ret.minEnableSpeed = -1
ret.mass = 1669. + STD_CARGO_KG
ret.wheelbase = 2.675
ret.steerRatio = 16.8
ret.centerToFront = ret.wheelbase * 0.4
tire_stiffness_factor = 1.0
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase # civic and scaling by mass and wheelbase
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)
@ -156,7 +173,7 @@ class CarInterface(CarInterfaceBase):
# returns a car.CarState # returns a car.CarState
def _update(self, c): def _update(self, c):
ret = self.CS.update(self.cp, self.cp_loopback) ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback)
ret.cruiseState.enabled, ret.cruiseState.available = self.dp_atl_mode(ret) ret.cruiseState.enabled, ret.cruiseState.available = self.dp_atl_mode(ret)
if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT:

@ -14,7 +14,6 @@ class CarControllerParams:
STEER_STEP = 2 # Control frames per command (50hz) STEER_STEP = 2 # Control frames per command (50hz)
STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness
STEER_DELTA_DOWN = 17 STEER_DELTA_DOWN = 17
MIN_STEER_SPEED = 3. # m/s
STEER_DRIVER_ALLOWANCE = 50 STEER_DRIVER_ALLOWANCE = 50
STEER_DRIVER_MULTIPLIER = 4 STEER_DRIVER_MULTIPLIER = 4
STEER_DRIVER_FACTOR = 100 STEER_DRIVER_FACTOR = 100
@ -59,10 +58,7 @@ class CAR:
ACADIA = "GMC ACADIA DENALI 2018" ACADIA = "GMC ACADIA DENALI 2018"
BUICK_REGAL = "BUICK REGAL ESSENCE 2018" BUICK_REGAL = "BUICK REGAL ESSENCE 2018"
ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016" ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016"
BOLT_EUV = "CHEVROLET BOLT EUV 2022"
EV_CAR = {CAR.VOLT}
STEER_THRESHOLD = 1.0
class Footnote(Enum): class Footnote(Enum):
@ -87,6 +83,7 @@ CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = {
CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"), CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"),
CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"), CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"),
CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"), CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"),
CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier/Premier Redline Trim", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm),
} }
@ -107,6 +104,7 @@ class AccState:
class CanBus: class CanBus:
POWERTRAIN = 0 POWERTRAIN = 0
OBSTACLE = 1 OBSTACLE = 1
CAMERA = 2
CHASSIS = 2 CHASSIS = 2
SW_GMLAN = 3 SW_GMLAN = 3
LOOPBACK = 128 LOOPBACK = 128
@ -155,6 +153,17 @@ FINGERPRINTS = {
{ {
309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8 309: 1, 848: 8, 849: 8, 850: 8, 851: 8, 852: 8, 853: 8, 854: 3, 1056: 6, 1057: 8, 1058: 8, 1059: 8, 1060: 8, 1061: 8, 1062: 8, 1063: 8, 1064: 8, 1065: 8, 1066: 8, 1067: 8, 1068: 8, 1120: 8, 1121: 8, 1122: 8, 1123: 8, 1124: 8, 1125: 8, 1126: 8, 1127: 8, 1128: 8, 1129: 8, 1130: 8, 1131: 8, 1132: 8, 1133: 8, 1134: 8, 1135: 8, 1136: 8, 1137: 8, 1138: 8, 1139: 8, 1140: 8, 1141: 8, 1142: 8, 1143: 8, 1146: 8, 1147: 8, 1148: 8, 1149: 8, 1150: 8, 1151: 8, 1216: 8, 1217: 8, 1218: 8, 1219: 8, 1220: 8, 1221: 8, 1222: 8, 1223: 8, 1224: 8, 1225: 8, 1226: 8, 1232: 8, 1233: 8, 1234: 8, 1235: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1240: 8, 1241: 8, 1242: 8, 1787: 8, 1788: 8
}], }],
CAR.BOLT_EUV: [
{
189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7
}],
} }
DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')) DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis'))
EV_CAR = {CAR.VOLT, CAR.BOLT_EUV}
# We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness)
CAMERA_ACC_CAR = {CAR.BOLT_EUV}
STEER_THRESHOLD = 1.0

@ -329,6 +329,23 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.1 ret.steerActuatorDelay = 0.1
ret.steerLimitTimer = 0.8 ret.steerLimitTimer = 0.8
if Params().get_bool('dp_honda_eps_mod'):
if candidate == CAR.CIVIC:
# tuned by a-tao
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096, 8000], [0, 4096, 4096]]
elif candidate in (CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2564, 8000], [0, 2564, 3840]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.09]] #2.5 default mod #Tuned by TMG
elif candidate in (CAR.ACCORD, CAR.ACCORDH):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.3], [0.09]]
elif candidate == CAR.CRV_5G:
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2560, 10000], [0, 2560, 3840]] #tuned by Titanminer (8000)
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.21], [0.07]]
elif candidate == CAR.CRV_HYBRID:
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0x0, 0xB5, 0x161, 0x2D6, 0x4C0, 0x70D, 0xC42, 0x1058, 0x2C00], [0x0, 0x160, 0x1F0, 0x2E0, 0x378, 0x4A0, 0x5F0, 0x804, 0xF00]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.21], [0.07]] #still needs to finish tuning for the new car
ret.lateralTuning.pid.kf = 0.00004
CarInterfaceBase.configure_lqr_tune(ret.lateralTuning) CarInterfaceBase.configure_lqr_tune(ret.lateralTuning)
return ret return ret

@ -131,7 +131,7 @@ CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = {
CAR.FIT: HondaCarInfo("Honda Fit 2018-20", harness=Harness.nidec), CAR.FIT: HondaCarInfo("Honda Fit 2018-20", harness=Harness.nidec),
CAR.FREED: HondaCarInfo("Honda Freed 2020", harness=Harness.nidec), CAR.FREED: HondaCarInfo("Honda Freed 2020", harness=Harness.nidec),
CAR.HRV: HondaCarInfo("Honda HR-V 2019-22", harness=Harness.nidec), CAR.HRV: HondaCarInfo("Honda HR-V 2019-22", harness=Harness.nidec),
CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-22", min_steer_speed=0., harness=Harness.nidec), CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-20", min_steer_speed=0., harness=Harness.nidec),
CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey
CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", harness=Harness.nidec), CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", harness=Harness.nidec),
CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a), CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a),

@ -4,8 +4,8 @@ from common.numpy_fast import clip, interp
from common.realtime import DT_CTRL from common.realtime import DT_CTRL
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car import apply_std_steer_torque_limits
from selfdrive.car.hyundai import hda2can, hyundaican from selfdrive.car.hyundai import hyundaicanfd, hyundaican
from selfdrive.car.hyundai.values import Buttons, CarControllerParams, HDA2_CAR, CAR from selfdrive.car.hyundai.values import Buttons, CarControllerParams, CANFD_CAR, CAR
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState LongCtrlState = car.CarControl.Actuators.LongControlState
@ -69,23 +69,23 @@ class CarController:
can_sends = [] can_sends = []
if self.CP.carFingerprint in HDA2_CAR: if self.CP.carFingerprint in CANFD_CAR:
# steering control # steering control
can_sends.append(hda2can.create_lkas(self.packer, CC.enabled, CC.latActive, apply_steer)) can_sends.append(hyundaicanfd.create_lkas(self.packer, CC.enabled, CC.latActive, apply_steer))
if self.frame % 5 == 0: if self.frame % 5 == 0:
can_sends.append(hda2can.create_cam_0x2a4(self.packer, CS.cam_0x2a4)) can_sends.append(hyundaicanfd.create_cam_0x2a4(self.packer, CS.cam_0x2a4))
# cruise cancel # cruise cancel
if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
if CC.cruiseControl.cancel: if CC.cruiseControl.cancel:
for _ in range(20): for _ in range(20):
can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL)) can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.CANCEL))
self.last_button_frame = self.frame self.last_button_frame = self.frame
# cruise standstill resume # cruise standstill resume
elif CC.cruiseControl.resume: elif CC.cruiseControl.resume:
can_sends.append(hda2can.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL)) can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL))
self.last_button_frame = self.frame self.last_button_frame = self.frame
else: else:

@ -5,7 +5,7 @@ from cereal import car
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine from opendbc.can.can_define import CANDefine
from selfdrive.car.hyundai.values import DBC, FEATURES, CAMERA_SCC_CAR, HDA2_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.values import DBC, FEATURES, CAMERA_SCC_CAR, CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams
from selfdrive.car.interfaces import CarStateBase from selfdrive.car.interfaces import CarStateBase
PREV_BUTTON_SAMPLES = 8 PREV_BUTTON_SAMPLES = 8
@ -19,7 +19,7 @@ class CarState(CarStateBase):
self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
if CP.carFingerprint in HDA2_CAR: if CP.carFingerprint in CANFD_CAR:
self.shifter_values = can_define.dv["ACCELERATOR"]["GEAR"] self.shifter_values = can_define.dv["ACCELERATOR"]["GEAR"]
elif self.CP.carFingerprint in FEATURES["use_cluster_gears"]: elif self.CP.carFingerprint in FEATURES["use_cluster_gears"]:
self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"] self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"]
@ -35,8 +35,8 @@ class CarState(CarStateBase):
self.params = CarControllerParams(CP) self.params = CarControllerParams(CP)
def update(self, cp, cp_cam): def update(self, cp, cp_cam):
if self.CP.carFingerprint in HDA2_CAR: if self.CP.carFingerprint in CANFD_CAR:
return self.update_hda2(cp, cp_cam) return self.update_canfd(cp, cp_cam)
ret = car.CarState.new_message() ret = car.CarState.new_message()
@ -133,7 +133,7 @@ class CarState(CarStateBase):
return ret return ret
def update_hda2(self, cp, cp_cam): def update_canfd(self, cp, cp_cam):
ret = car.CarState.new_message() ret = car.CarState.new_message()
ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255. ret.gas = cp.vl["ACCELERATOR"]["ACCELERATOR_PEDAL"] / 255.
@ -184,8 +184,8 @@ class CarState(CarStateBase):
@staticmethod @staticmethod
def get_can_parser(CP): def get_can_parser(CP):
if CP.carFingerprint in HDA2_CAR: if CP.carFingerprint in CANFD_CAR:
return CarState.get_can_parser_hda2(CP) return CarState.get_can_parser_canfd(CP)
signals = [ signals = [
# signal_name, signal_address # signal_name, signal_address
@ -319,7 +319,7 @@ class CarState(CarStateBase):
@staticmethod @staticmethod
def get_cam_can_parser(CP): def get_cam_can_parser(CP):
if CP.carFingerprint in HDA2_CAR: if CP.carFingerprint in CANFD_CAR:
signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)] signals = [(f"BYTE{i}", "CAM_0x2a4") for i in range(3, 24)]
checks = [("CAM_0x2a4", 20)] checks = [("CAM_0x2a4", 20)]
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 6)
@ -374,7 +374,7 @@ class CarState(CarStateBase):
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2)
@staticmethod @staticmethod
def get_can_parser_hda2(CP): def get_can_parser_canfd(CP):
signals = [ signals = [
("WHEEL_SPEED_1", "WHEEL_SPEEDS"), ("WHEEL_SPEED_1", "WHEEL_SPEEDS"),
("WHEEL_SPEED_2", "WHEEL_SPEEDS"), ("WHEEL_SPEED_2", "WHEEL_SPEEDS"),

@ -2,7 +2,7 @@
from cereal import car from cereal import car
from panda import Panda from panda import Panda
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from selfdrive.car.hyundai.values import CAR, DBC, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams from selfdrive.car.hyundai.values import CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, Buttons, CarControllerParams
from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR from selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car import STD_CARGO_KG, create_button_enable_events, create_button_event, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.interfaces import CarInterfaceBase
@ -26,7 +26,6 @@ class CarInterface(CarInterfaceBase):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint) ret = CarInterfaceBase.get_std_params(candidate, fingerprint)
ret.carName = "hyundai" ret.carName = "hyundai"
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundai, 0)]
ret.radarOffCan = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None ret.radarOffCan = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
# WARNING: disabling radar also disables AEB (and we show the same warning on the instrument cluster as if you manually disabled AEB) # WARNING: disabling radar also disables AEB (and we show the same warning on the instrument cluster as if you manually disabled AEB)
@ -239,8 +238,12 @@ class CarInterface(CarInterfaceBase):
ret.mass = 2055 + STD_CARGO_KG ret.mass = 2055 + STD_CARGO_KG
ret.wheelbase = 2.9 ret.wheelbase = 2.9
ret.steerRatio = 16. ret.steerRatio = 16.
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), tire_stiffness_factor = 0.65
get_safety_config(car.CarParams.SafetyModel.hyundaiHDA2)] CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.IONIQ_5:
ret.mass = 2012 + STD_CARGO_KG
ret.wheelbase = 3.0
ret.steerRatio = 16.
tire_stiffness_factor = 0.65 tire_stiffness_factor = 0.65
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
@ -280,9 +283,16 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.16], [0.01]]
# these cars require a special panda safety mode due to missing counters and checksums in the messages # panda safety config
if candidate in CANFD_CAR:
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput),
get_safety_config(car.CarParams.SafetyModel.hyundaiCanfd)]
else:
if candidate in LEGACY_SAFETY_MODE_CAR: if candidate in LEGACY_SAFETY_MODE_CAR:
# these cars require a special panda safety mode due to missing counters and checksums in the messages
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundaiLegacy)] ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundaiLegacy)]
else:
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hyundai, 0)]
# set appropriate safety param for gas signal # set appropriate safety param for gas signal
if candidate in HYBRID_CAR: if candidate in HYBRID_CAR:
@ -290,6 +300,12 @@ class CarInterface(CarInterfaceBase):
elif candidate in EV_CAR: elif candidate in EV_CAR:
ret.safetyConfigs[0].safetyParam = 1 ret.safetyConfigs[0].safetyParam = 1
if ret.openpilotLongitudinalControl:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LONG
if candidate in CAMERA_SCC_CAR:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
ret.centerToFront = ret.wheelbase * 0.4 ret.centerToFront = ret.wheelbase * 0.4
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
@ -306,12 +322,6 @@ class CarInterface(CarInterfaceBase):
if int(Params().get("dp_atl").decode('utf-8')) == 1: if int(Params().get("dp_atl").decode('utf-8')) == 1:
ret.openpilotLongitudinalControl = False ret.openpilotLongitudinalControl = False
if ret.openpilotLongitudinalControl:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_LONG
if candidate in CAMERA_SCC_CAR:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
CarInterfaceBase.configure_lqr_tune(ret.lateralTuning) CarInterfaceBase.configure_lqr_tune(ret.lateralTuning)
return ret return ret

@ -20,7 +20,7 @@ class CarControllerParams:
self.STEER_DRIVER_FACTOR = 1 self.STEER_DRIVER_FACTOR = 1
self.STEER_THRESHOLD = 150 self.STEER_THRESHOLD = 150
if CP.carFingerprint in HDA2_CAR: if CP.carFingerprint in CANFD_CAR:
self.STEER_MAX = 270 self.STEER_MAX = 270
self.STEER_DRIVER_ALLOWANCE = 250 self.STEER_DRIVER_ALLOWANCE = 250
self.STEER_DRIVER_MULTIPLIER = 2 self.STEER_DRIVER_MULTIPLIER = 2
@ -65,6 +65,7 @@ class CAR:
PALISADE = "HYUNDAI PALISADE 2020" PALISADE = "HYUNDAI PALISADE 2020"
VELOSTER = "HYUNDAI VELOSTER 2019" VELOSTER = "HYUNDAI VELOSTER 2019"
SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021" SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021"
IONIQ_5 = "HYUNDAI IONIQ 5 2022"
# Kia # Kia
KIA_FORTE = "KIA FORTE E 2018 & GT 2021" KIA_FORTE = "KIA FORTE E 2018 & GT 2021"
@ -126,6 +127,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
], ],
CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", "Smart Cruise Control (SCC)", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e), CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", "Smart Cruise Control (SCC)", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e),
CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a), CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-22", "All", harness=Harness.hyundai_a),
CAR.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.none),
# Kia # Kia
CAR.KIA_FORTE: [ CAR.KIA_FORTE: [
@ -156,7 +158,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
], ],
CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c), CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c),
CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", harness=Harness.hyundai_e), CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", harness=Harness.hyundai_e),
CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "All", harness=Harness.hyundai_p), CAR.KIA_EV6: HyundaiCarInfo("Kia EV6 2022", "Highway Driving Assist II", harness=Harness.hyundai_p),
# Genesis # Genesis
CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018-19", "All", harness=Harness.hyundai_f), CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018-19", "All", harness=Harness.hyundai_f),
@ -1263,6 +1265,23 @@ FW_VERSIONS = {
b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.05 99210-CV000 211027', b'\xf1\x00CV1 MFC AT USA LHD 1.00 1.05 99210-CV000 211027',
], ],
}, },
CAR.IONIQ_5: {
(Ecu.esp, 0x7d1, None): [
b'\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010',
b'\xf1\x8758520GI010\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010',
],
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106',
b'\xf1\x8757700GI000 \xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ',
b'\xf1\x8799110GI000\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.02 99211-GI010 211206',
],
},
} }
CHECKSUM = { CHECKSUM = {
@ -1280,7 +1299,7 @@ FEATURES = {
"use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022}, "use_fca": {CAR.SONATA, CAR.SONATA_HYBRID, CAR.ELANTRA, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021, CAR.ELANTRA_GT_I30, CAR.KIA_STINGER, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KONA_EV, CAR.KIA_FORTE, CAR.KIA_NIRO_EV, CAR.PALISADE, CAR.GENESIS_G70, CAR.GENESIS_G70_2020, CAR.KONA, CAR.SANTA_FE, CAR.KIA_SELTOS, CAR.KONA_HEV, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.TUCSON, CAR.KONA_EV_2022},
} }
HDA2_CAR = {CAR.KIA_EV6, } CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5}
# The camera does SCC on these cars, rather than the radar # The camera does SCC on these cars, rather than the radar
CAMERA_SCC_CAR = {CAR.KONA_EV_2022, } CAMERA_SCC_CAR = {CAR.KONA_EV_2022, }
@ -1335,4 +1354,5 @@ DBC = {
CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None), CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_EV6: dbc_dict('kia_ev6', None), CAR.KIA_EV6: dbc_dict('kia_ev6', None),
CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'), CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.IONIQ_5: dbc_dict('kia_ev6', None),
} }

@ -135,6 +135,7 @@ class IsoTpParallelQuery:
if self.debug: if self.debug:
cloudlog.warning(f"iso-tp query response pending: {tx_addr}") cloudlog.warning(f"iso-tp query response pending: {tx_addr}")
else: else:
response_timeouts[tx_addr] = 0
request_done[tx_addr] = True request_done[tx_addr] = True
cloudlog.warning(f"iso-tp query bad response: {tx_addr} - 0x{dat.hex()}") cloudlog.warning(f"iso-tp query bad response: {tx_addr} - 0x{dat.hex()}")

@ -67,6 +67,7 @@ FW_VERSIONS = {
b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2G-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PX2H-188K2-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'SH54-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'SH54-188K2-D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PXFG-188K2-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.fwdRadar, 0x764, None): [ (Ecu.fwdRadar, 0x764, None): [
b'K131-67XK2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'K131-67XK2-F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
@ -80,6 +81,7 @@ FW_VERSIONS = {
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'PYB2-21PS1-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'PYB2-21PS1-H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'SH51-21PS1-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'SH51-21PS1-C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
b'PXFG-21PS1-A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
], ],
}, },
CAR.CX5: { CAR.CX5: {

@ -46,12 +46,12 @@ class CAR:
@dataclass @dataclass
class SubaruCarInfo(CarInfo): class SubaruCarInfo(CarInfo):
package: str = "EyeSight Driver Assistance" package: str = "EyeSight Driver Assistance"
harness: Enum = Harness.subaru harness: Enum = Harness.subaru_a
CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = { CAR_INFO: Dict[str, Union[SubaruCarInfo, List[SubaruCarInfo]]] = {
CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"), CAR.ASCENT: SubaruCarInfo("Subaru Ascent 2019-21", "All"),
CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", harness=Harness.none), CAR.OUTBACK: SubaruCarInfo("Subaru Outback 2020-22", "All", harness=Harness.subaru_b),
CAR.IMPREZA: [ CAR.IMPREZA: [
SubaruCarInfo("Subaru Impreza 2017-19"), SubaruCarInfo("Subaru Impreza 2017-19"),
SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"), SubaruCarInfo("Subaru Crosstrek 2018-19", video_link="https://youtu.be/Agww7oE1k-s?t=26"),
@ -99,7 +99,6 @@ FW_VERSIONS = {
b'\x00\xfe\xf7\x00\x00', b'\x00\xfe\xf7\x00\x00',
b'\001\xfe\xf9\000\000', b'\001\xfe\xf9\000\000',
b'\x01\xfe\xf7\x00\x00', b'\x01\xfe\xf7\x00\x00',
b'\xf1\x00\xa4\x10@',
], ],
}, },
CAR.IMPREZA: { CAR.IMPREZA: {
@ -116,6 +115,7 @@ FW_VERSIONS = {
b'z\x94\x08\x90\x00', b'z\x94\x08\x90\x00',
b'z\x84\x19\x90\x00', b'z\x84\x19\x90\x00',
b'\xf1\x00\xb2\x06\x04', b'\xf1\x00\xb2\x06\x04',
b'z\x94\x0c\x90\x00',
], ],
(Ecu.eps, 0x746, None): [ (Ecu.eps, 0x746, None): [
b'\x7a\xc0\x0c\x00', b'\x7a\xc0\x0c\x00',
@ -139,6 +139,7 @@ FW_VERSIONS = {
b'\x00\x00c\xf4\x00\x00\x00\x00', b'\x00\x00c\xf4\x00\x00\x00\x00',
b'\x00\x00d\xdc\x00\x00\x00\x00', b'\x00\x00d\xdc\x00\x00\x00\x00',
b'\x00\x00dd\x00\x00\x00\x00', b'\x00\x00dd\x00\x00\x00\x00',
b'\x00\x00c\xf4\x1f@ \x07',
], ],
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xaa\x61\x66\x73\x07', b'\xaa\x61\x66\x73\x07',
@ -148,7 +149,6 @@ FW_VERSIONS = {
b'\xaa!`u\a', b'\xaa!`u\a',
b'\xaa!dq\a', b'\xaa!dq\a',
b'\xaa!dt\a', b'\xaa!dt\a',
b'\xf1\x00\xa2\x10\t',
b'\xc5!ar\a', b'\xc5!ar\a',
b'\xbe!as\a', b'\xbe!as\a',
b'\xc5!ds\a', b'\xc5!ds\a',
@ -158,6 +158,7 @@ FW_VERSIONS = {
b'\xaa\x00Bu\x07', b'\xaa\x00Bu\x07',
b'\xc5!dr\x07', b'\xc5!dr\x07',
b'\xaa!aw\x07', b'\xaa!aw\x07',
b'\xaa!av\x07',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\xe3\xe5\x46\x31\x00', b'\xe3\xe5\x46\x31\x00',
@ -173,7 +174,6 @@ FW_VERSIONS = {
b'\xe4\xf5\002\000\000', b'\xe4\xf5\002\000\000',
b'\xe3\xd0\x081\x00', b'\xe3\xd0\x081\x00',
b'\xe3\xf5\x06\x00\x00', b'\xe3\xf5\x06\x00\x00',
b'\xf1\x00\xa4\x10@',
], ],
}, },
CAR.IMPREZA_2020: { CAR.IMPREZA_2020: {
@ -202,7 +202,6 @@ FW_VERSIONS = {
b'\xca!`0\a', b'\xca!`0\a',
b'\xcc\"f0\a', b'\xcc\"f0\a',
b'\xcc!fp\a', b'\xcc!fp\a',
b'\xf1\x00\xa2\x10\t',
b'\xca!f@\x07', b'\xca!f@\x07',
b'\xca!fp\x07', b'\xca!fp\x07',
], ],
@ -247,7 +246,6 @@ FW_VERSIONS = {
b'\x1a\xf6F`\x00', b'\x1a\xf6F`\x00',
b'\032\xf6b`\000', b'\032\xf6b`\000',
b'\x1a\xf6B`\x00', b'\x1a\xf6B`\x00',
b'\xf1\x00\xa4\x10@',
b'\x1a\xf6b0\x00', b'\x1a\xf6b0\x00',
], ],
}, },

@ -22,7 +22,9 @@ COMMA BODY: [.nan, 1000, .nan]
# Totally new cars # Totally new cars
KIA EV6 2022: [3.5, 2.5, 0.0] KIA EV6 2022: [3.5, 2.5, 0.0]
RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.0]
RAM HD 5TH GEN: [1.4, 1.4, 0.0]
SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11]
CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05]
# Dashcam or fallback configured as ideal car # Dashcam or fallback configured as ideal car
mock: [10.0, 10, 0.0] mock: [10.0, 10, 0.0]

@ -29,6 +29,7 @@ HYUNDAI I30 N LINE 2019 & GT 2018 DCT: HYUNDAI SONATA 2019
HYUNDAI KONA 2020: HYUNDAI KONA ELECTRIC 2019 HYUNDAI KONA 2020: HYUNDAI KONA ELECTRIC 2019
HYUNDAI KONA HYBRID 2020: HYUNDAI KONA ELECTRIC 2019 HYUNDAI KONA HYBRID 2020: HYUNDAI KONA ELECTRIC 2019
HYUNDAI KONA ELECTRIC 2022: HYUNDAI KONA ELECTRIC 2019 HYUNDAI KONA ELECTRIC 2022: HYUNDAI KONA ELECTRIC 2019
HYUNDAI IONIQ 5 2022: KIA EV6 2022
HYUNDAI IONIQ HYBRID 2017-2019: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ HYBRID 2017-2019: HYUNDAI IONIQ PLUG-IN HYBRID 2019
HYUNDAI IONIQ HYBRID 2020-2022: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ HYBRID 2020-2022: HYUNDAI IONIQ PLUG-IN HYBRID 2019
HYUNDAI IONIQ ELECTRIC 2020: HYUNDAI IONIQ PLUG-IN HYBRID 2019 HYUNDAI IONIQ ELECTRIC 2020: HYUNDAI IONIQ PLUG-IN HYBRID 2019

@ -32,10 +32,12 @@ class CarController:
# dp # dp
self.dp_toyota_sng = False self.dp_toyota_sng = False
self.dp_atl = 0
def update(self, CC, CS, dragonconf): def update(self, CC, CS, dragonconf):
if dragonconf is not None: if dragonconf is not None:
self.dp_toyota_sng = dragonconf.dpToyotaSng self.dp_toyota_sng = dragonconf.dpToyotaSng
self.dp_atl = dragonconf.dpAtl
actuators = CC.actuators actuators = CC.actuators
hud_control = CC.hudControl hud_control = CC.hudControl
pcm_cancel_cmd = CC.cruiseControl.cancel pcm_cancel_cmd = CC.cruiseControl.cancel
@ -79,6 +81,11 @@ class CarController:
apply_steer_req = 0 apply_steer_req = 0
self.steer_rate_counter = 0 self.steer_rate_counter = 0
# dp - try to avoid steering fault
if self.dp_atl > 0 and abs(CS.out.steeringAngleDeg) > 500:
apply_steer = 0
apply_steer_req = 0
# TODO: probably can delete this. CS.pcm_acc_status uses a different signal # TODO: probably can delete this. CS.pcm_acc_status uses a different signal
# than CS.cruiseState.enabled. confirm they're not meaningfully different # than CS.cruiseState.enabled. confirm they're not meaningfully different
if not CC.enabled and CS.pcm_acc_status: if not CC.enabled and CS.pcm_acc_status:

@ -158,7 +158,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
CAR.RAV4H_TSS2: ToyotaCarInfo("Toyota RAV4 Hybrid 2019-21"), 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_2022: ToyotaCarInfo("Toyota RAV4 Hybrid 2022", video_link="https://youtu.be/U0nH9cnrFB0"),
CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"), CAR.MIRAI: ToyotaCarInfo("Toyota Mirai 2021"),
CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", footnotes=[Footnote.DSU]), CAR.SIENNA: ToyotaCarInfo("Toyota Sienna 2018-20", video_link="https://www.youtube.com/watch?v=q1UPOo4Sh68", footnotes=[Footnote.DSU], min_enable_speed=MIN_ACC_SPEED),
# Lexus # Lexus
CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+", footnotes=[Footnote.DSU]), CAR.LEXUS_CTH: ToyotaCarInfo("Lexus CT Hybrid 2017-18", "Lexus Safety System+", footnotes=[Footnote.DSU]),
@ -171,7 +171,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"), CAR.LEXUS_NX_TSS2: ToyotaCarInfo("Lexus NX 2020-21"),
CAR.LEXUS_NXH_TSS2: ToyotaCarInfo("Lexus NX Hybrid 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 2017-20"),
CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-18", footnotes=[Footnote.DSU]), CAR.LEXUS_RX: ToyotaCarInfo("Lexus RX 2016-19", footnotes=[Footnote.DSU]),
CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]), CAR.LEXUS_RXH: ToyotaCarInfo("Lexus RX Hybrid 2016-19", footnotes=[Footnote.DSU]),
CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-22"), CAR.LEXUS_RX_TSS2: ToyotaCarInfo("Lexus RX 2020-22"),
CAR.LEXUS_RXH_TSS2: ToyotaCarInfo("Lexus RX Hybrid 2020-21"), CAR.LEXUS_RXH_TSS2: ToyotaCarInfo("Lexus RX Hybrid 2020-21"),
@ -1825,15 +1825,18 @@ FW_VERSIONS = {
b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x02348Y3000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D14000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00', b'\x0234D16000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x02348X4000\x00\x00\x00\x00\x00\x00\x00\x00A4802000\x00\x00\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.esp, 0x7b0, None): [ (Ecu.esp, 0x7b0, None): [
b'F152648831\x00\x00\x00\x00\x00\x00', b'F152648831\x00\x00\x00\x00\x00\x00',
b'F152648891\x00\x00\x00\x00\x00\x00', b'F152648891\x00\x00\x00\x00\x00\x00',
b'F152648D00\x00\x00\x00\x00\x00\x00', b'F152648D00\x00\x00\x00\x00\x00\x00',
b'F152648D60\x00\x00\x00\x00\x00\x00', b'F152648D60\x00\x00\x00\x00\x00\x00',
b'F152648811\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.eps, 0x7a1, None): [ (Ecu.eps, 0x7a1, None): [
b'8965B48271\x00\x00\x00\x00\x00\x00', b'8965B48271\x00\x00\x00\x00\x00\x00',
b'8965B48261\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.fwdRadar, 0x750, 0xf): [ (Ecu.fwdRadar, 0x750, 0xf): [
b'\x018821F3301400\x00\x00\x00\x00', b'\x018821F3301400\x00\x00\x00\x00',

@ -1,8 +1,8 @@
from cereal import car from cereal import car
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car import apply_std_steer_torque_limits
from selfdrive.car.volkswagen import volkswagencan from selfdrive.car.volkswagen import mqbcan
from selfdrive.car.volkswagen.values import DBC_FILES, CANBUS, MQB_LDW_MESSAGES, CarControllerParams as P from selfdrive.car.volkswagen.values import CANBUS, CarControllerParams
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
@ -10,11 +10,12 @@ VisualAlert = car.CarControl.HUDControl.VisualAlert
class CarController: class CarController:
def __init__(self, dbc_name, CP, VM): def __init__(self, dbc_name, CP, VM):
self.CP = CP self.CP = CP
self.CCP = CarControllerParams(CP)
self.CCS = mqbcan
self.packer_pt = CANPacker(dbc_name)
self.apply_steer_last = 0 self.apply_steer_last = 0
self.frame = 0 self.frame = 0
self.packer_pt = CANPacker(DBC_FILES.mqb)
self.hcaSameTorqueCount = 0 self.hcaSameTorqueCount = 0
self.hcaEnabledFrameCount = 0 self.hcaEnabledFrameCount = 0
@ -26,7 +27,7 @@ class CarController:
# **** Steering Controls ************************************************ # # **** Steering Controls ************************************************ #
if self.frame % P.HCA_STEP == 0: if self.frame % self.CCP.HCA_STEP == 0:
# Logic to avoid HCA state 4 "refused": # Logic to avoid HCA state 4 "refused":
# * Don't steer unless HCA is in state 3 "ready" or 5 "active" # * Don't steer unless HCA is in state 3 "ready" or 5 "active"
# * Don't steer at standstill # * Don't steer at standstill
@ -38,21 +39,21 @@ class CarController:
# when exceeding ~1/3 the 360 second timer. # when exceeding ~1/3 the 360 second timer.
if CC.latActive: if CC.latActive:
new_steer = int(round(actuators.steer * P.STEER_MAX)) 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, P) apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.CCP)
if apply_steer == 0: if apply_steer == 0:
hcaEnabled = False hcaEnabled = False
self.hcaEnabledFrameCount = 0 self.hcaEnabledFrameCount = 0
else: else:
self.hcaEnabledFrameCount += 1 self.hcaEnabledFrameCount += 1
if self.hcaEnabledFrameCount >= 118 * (100 / P.HCA_STEP): # 118s if self.hcaEnabledFrameCount >= 118 * (100 / self.CCP.HCA_STEP): # 118s
hcaEnabled = False hcaEnabled = False
self.hcaEnabledFrameCount = 0 self.hcaEnabledFrameCount = 0
else: else:
hcaEnabled = True hcaEnabled = True
if self.apply_steer_last == apply_steer: if self.apply_steer_last == apply_steer:
self.hcaSameTorqueCount += 1 self.hcaSameTorqueCount += 1
if self.hcaSameTorqueCount > 1.9 * (100 / P.HCA_STEP): # 1.9s if self.hcaSameTorqueCount > 1.9 * (100 / self.CCP.HCA_STEP): # 1.9s
apply_steer -= (1, -1)[apply_steer < 0] apply_steer -= (1, -1)[apply_steer < 0]
self.hcaSameTorqueCount = 0 self.hcaSameTorqueCount = 0
else: else:
@ -62,32 +63,28 @@ class CarController:
apply_steer = 0 apply_steer = 0
self.apply_steer_last = apply_steer self.apply_steer_last = apply_steer
can_sends.append(volkswagencan.create_mqb_steering_control(self.packer_pt, CANBUS.pt, apply_steer, hcaEnabled)) can_sends.append(self.CCS.create_steering_control(self.packer_pt, CANBUS.pt, apply_steer, hcaEnabled))
# **** HUD Controls ***************************************************** # # **** HUD Controls ***************************************************** #
if self.frame % P.LDW_STEP == 0: if self.frame % self.CCP.LDW_STEP == 0:
hud_alert = 0
if hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw): if hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw):
hud_alert = MQB_LDW_MESSAGES["laneAssistTakeOverSilent"] hud_alert = self.CCP.LDW_MESSAGES["laneAssistTakeOver"]
else: can_sends.append(self.CCS.create_lka_hud_control(self.packer_pt, CANBUS.pt, CS.ldw_stock_values, CC.enabled,
hud_alert = MQB_LDW_MESSAGES["none"] CS.out.steeringPressed, hud_alert, hud_control))
can_sends.append(volkswagencan.create_mqb_hud_control(self.packer_pt, CANBUS.pt, CC.enabled,
CS.out.steeringPressed, hud_alert, hud_control.leftLaneVisible,
hud_control.rightLaneVisible, CS.ldw_stock_values,
hud_control.leftLaneDepart, hud_control.rightLaneDepart))
# **** ACC Button Controls ********************************************** # # **** Stock ACC Button Controls **************************************** #
if self.CP.pcmCruise and self.frame % P.GRA_ACC_STEP == 0: if self.CP.pcmCruise and self.frame % self.CCP.GRA_ACC_STEP == 0:
idx = (CS.gra_stock_values["COUNTER"] + 1) % 16 idx = (CS.gra_stock_values["COUNTER"] + 1) % 16
if CC.cruiseControl.cancel: if CC.cruiseControl.cancel:
can_sends.append(volkswagencan.create_mqb_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, cancel=True)) can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, cancel=True))
elif CC.cruiseControl.resume: elif CC.cruiseControl.resume:
can_sends.append(volkswagencan.create_mqb_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, resume=True)) can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, ext_bus, CS.gra_stock_values, idx, resume=True))
new_actuators = actuators.copy() new_actuators = actuators.copy()
new_actuators.steer = self.apply_steer_last / P.STEER_MAX new_actuators.steer = self.apply_steer_last / self.CCP.STEER_MAX
self.frame += 1 self.frame += 1
return new_actuators, can_sends return new_actuators, can_sends

@ -3,20 +3,29 @@ from cereal import car
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from selfdrive.car.interfaces import CarStateBase from selfdrive.car.interfaces import CarStateBase
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine from selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \
from selfdrive.car.volkswagen.values import DBC_FILES, CANBUS, NetworkLocation, TransmissionType, GearShifter, \ CarControllerParams
CarControllerParams, MQB_BUTTONS
class CarState(CarStateBase): class CarState(CarStateBase):
def __init__(self, CP): def __init__(self, CP):
super().__init__(CP) super().__init__(CP)
self.button_states = {button.event_type: False for button in MQB_BUTTONS} self.CCP = CarControllerParams(CP)
can_define = CANDefine(DBC_FILES.mqb) self.button_states = {button.event_type: False for button in self.CCP.BUTTONS}
if CP.transmissionType == TransmissionType.automatic:
self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"] def create_button_events(self, pt_cp, buttons):
elif CP.transmissionType == TransmissionType.direct: button_events = []
self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"]
self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"] for button in buttons:
state = pt_cp.vl[button.can_addr][button.can_msg] in button.values
if self.button_states[button.event_type] != state:
event = car.CarState.ButtonEvent.new_message()
event.type = button.event_type
event.pressed = state
button_events.append(event)
self.button_states[button.event_type] = state
return button_events
def update(self, pt_cp, cam_cp, ext_cp, trans_type): def update(self, pt_cp, cam_cp, ext_cp, trans_type):
ret = car.CarState.new_message() ret = car.CarState.new_message()
@ -37,11 +46,11 @@ class CarState(CarStateBase):
ret.steeringAngleDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradwinkel"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradwinkel"])] ret.steeringAngleDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradwinkel"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradwinkel"])]
ret.steeringRateDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradw_Geschw"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradw_Geschw"])] ret.steeringRateDeg = pt_cp.vl["LWI_01"]["LWI_Lenkradw_Geschw"] * (1, -1)[int(pt_cp.vl["LWI_01"]["LWI_VZ_Lenkradw_Geschw"])]
ret.steeringTorque = pt_cp.vl["LH_EPS_03"]["EPS_Lenkmoment"] * (1, -1)[int(pt_cp.vl["LH_EPS_03"]["EPS_VZ_Lenkmoment"])] ret.steeringTorque = pt_cp.vl["LH_EPS_03"]["EPS_Lenkmoment"] * (1, -1)[int(pt_cp.vl["LH_EPS_03"]["EPS_VZ_Lenkmoment"])]
ret.steeringPressed = abs(ret.steeringTorque) > CarControllerParams.STEER_DRIVER_ALLOWANCE ret.steeringPressed = abs(ret.steeringTorque) > self.CCP.STEER_DRIVER_ALLOWANCE
ret.yawRate = pt_cp.vl["ESP_02"]["ESP_Gierrate"] * (1, -1)[int(pt_cp.vl["ESP_02"]["ESP_VZ_Gierrate"])] * CV.DEG_TO_RAD ret.yawRate = pt_cp.vl["ESP_02"]["ESP_Gierrate"] * (1, -1)[int(pt_cp.vl["ESP_02"]["ESP_VZ_Gierrate"])] * CV.DEG_TO_RAD
# Verify EPS readiness to accept steering commands # Verify EPS readiness to accept steering commands
hca_status = self.hca_status_values.get(pt_cp.vl["LH_EPS_03"]["EPS_HCA_Status"]) hca_status = self.CCP.hca_status_values.get(pt_cp.vl["LH_EPS_03"]["EPS_HCA_Status"])
ret.steerFaultPermanent = hca_status in ("DISABLED", "FAULT") ret.steerFaultPermanent = hca_status in ("DISABLED", "FAULT")
ret.steerFaultTemporary = hca_status in ("INITIALIZING", "REJECTED") ret.steerFaultTemporary = hca_status in ("INITIALIZING", "REJECTED")
@ -54,9 +63,9 @@ class CarState(CarStateBase):
# Update gear and/or clutch position data. # Update gear and/or clutch position data.
if trans_type == TransmissionType.automatic: if trans_type == TransmissionType.automatic:
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["Getriebe_11"]["GE_Fahrstufe"], None)) ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["Getriebe_11"]["GE_Fahrstufe"], None))
elif trans_type == TransmissionType.direct: elif trans_type == TransmissionType.direct:
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["EV_Gearshift"]["GearPosition"], None)) ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["EV_Gearshift"]["GearPosition"], None))
elif trans_type == TransmissionType.manual: elif trans_type == TransmissionType.manual:
ret.clutchPressed = not pt_cp.vl["Motor_14"]["MO_Kuppl_schalter"] ret.clutchPressed = not pt_cp.vl["Motor_14"]["MO_Kuppl_schalter"]
if bool(pt_cp.vl["Gateway_72"]["BCM1_Rueckfahrlicht_Schalter"]): if bool(pt_cp.vl["Gateway_72"]["BCM1_Rueckfahrlicht_Schalter"]):
@ -118,17 +127,8 @@ class CarState(CarStateBase):
# Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough # Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough
ret.leftBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Left"]) ret.leftBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Left"])
ret.rightBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Right"]) ret.rightBlinker = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Right"])
ret.buttonEvents = self.create_button_events(pt_cp, self.CCP.BUTTONS)
self.gra_stock_values = pt_cp.vl["GRA_ACC_01"] self.gra_stock_values = pt_cp.vl["GRA_ACC_01"]
buttonEvents = []
for button in MQB_BUTTONS:
state = pt_cp.vl[button.can_addr][button.can_msg] in button.values
if self.button_states[button.event_type] != state:
event = car.CarState.ButtonEvent.new_message()
event.type = button.event_type
event.pressed = state
buttonEvents.append(event)
self.button_states[button.event_type] = state
ret.buttonEvents = buttonEvents
# Additional safety checks performed in CarInterface. # Additional safety checks performed in CarInterface.
ret.espDisabled = pt_cp.vl["ESP_21"]["ESP_Tastung_passiv"] != 0 ret.espDisabled = pt_cp.vl["ESP_21"]["ESP_Tastung_passiv"] != 0
@ -219,7 +219,7 @@ class CarState(CarStateBase):
signals += MqbExtraSignals.bsm_radar_signals signals += MqbExtraSignals.bsm_radar_signals
checks += MqbExtraSignals.bsm_radar_checks checks += MqbExtraSignals.bsm_radar_checks
return CANParser(DBC_FILES.mqb, signals, checks, CANBUS.pt) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.pt)
@staticmethod @staticmethod
def get_cam_can_parser(CP): def get_cam_can_parser(CP):
@ -247,7 +247,7 @@ class CarState(CarStateBase):
signals += MqbExtraSignals.bsm_radar_signals signals += MqbExtraSignals.bsm_radar_signals
checks += MqbExtraSignals.bsm_radar_checks checks += MqbExtraSignals.bsm_radar_checks
return CANParser(DBC_FILES.mqb, signals, checks, CANBUS.cam) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, CANBUS.cam)
class MqbExtraSignals: class MqbExtraSignals:
# Additional signal and message lists for optional or bus-portable controllers # Additional signal and message lists for optional or bus-portable controllers

@ -1,7 +1,9 @@
from cereal import car from cereal import car
from selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter from selfdrive.car import STD_CARGO_KG, create_button_enable_events, scale_rot_inertia, scale_tire_stiffness, \
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config gen_empty_fingerprint, get_safety_config
from selfdrive.car.interfaces import CarInterfaceBase from selfdrive.car.interfaces import CarInterfaceBase
from selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter
EventName = car.CarEvent.EventName EventName = car.CarEvent.EventName
@ -52,6 +54,13 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV = [0.6] ret.lateralTuning.pid.kpV = [0.6]
ret.lateralTuning.pid.kiV = [0.2] ret.lateralTuning.pid.kiV = [0.2]
# Global longitudinal tuning defaults, can be overridden per-vehicle
ret.pcmCruise = not ret.openpilotLongitudinalControl
ret.longitudinalActuatorDelayUpperBound = 0.5 # s
ret.longitudinalTuning.kpV = [0.1]
ret.longitudinalTuning.kiV = [0.0]
# Per-chassis tuning values, override tuning defaults here if desired # Per-chassis tuning values, override tuning defaults here if desired
if candidate == CAR.ARTEON_MK1: if candidate == CAR.ARTEON_MK1:
@ -162,7 +171,8 @@ class CarInterface(CarInterfaceBase):
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType) ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType)
ret.cruiseState.enabled, ret.cruiseState.available = self.dp_atl_mode(ret) ret.cruiseState.enabled, ret.cruiseState.available = self.dp_atl_mode(ret)
events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic]) events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=not self.CS.CP.openpilotLongitudinalControl)
events = self.dp_atl_warning(ret, events) events = self.dp_atl_warning(ret, events)
# Low speed steer alert hysteresis logic # Low speed steer alert hysteresis logic
@ -173,6 +183,13 @@ class CarInterface(CarInterfaceBase):
if self.low_speed_alert: if self.low_speed_alert:
events.add(EventName.belowSteerSpeed) events.add(EventName.belowSteerSpeed)
if self.CS.CP.openpilotLongitudinalControl:
if ret.vEgo < self.CP.minEnableSpeed + 2.:
events.add(EventName.belowEngageSpeed)
if c.enabled and ret.vEgo < self.CP.minEnableSpeed:
events.add(EventName.speedTooLow)
events.events.extend(create_button_enable_events(ret.buttonEvents, pcm_cruise=self.CP.pcmCruise))
ret.events = events.to_msg() ret.events = events.to_msg()
return ret return ret

@ -0,0 +1,38 @@
def create_steering_control(packer, bus, apply_steer, lkas_enabled):
values = {
"SET_ME_0X3": 0x3,
"Assist_Torque": abs(apply_steer),
"Assist_Requested": lkas_enabled,
"Assist_VZ": 1 if apply_steer < 0 else 0,
"HCA_Available": 1,
"HCA_Standby": not lkas_enabled,
"HCA_Active": lkas_enabled,
"SET_ME_0XFE": 0xFE,
"SET_ME_0X07": 0x07,
}
return packer.make_can_msg("HCA_01", bus, values)
def create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control):
values = ldw_stock_values.copy()
values.update({
"LDW_Status_LED_gelb": 1 if enabled and steering_pressed else 0,
"LDW_Status_LED_gruen": 1 if enabled and not steering_pressed else 0,
"LDW_Lernmodus_links": 3 if hud_control.leftLaneDepart else 1 + hud_control.leftLaneVisible,
"LDW_Lernmodus_rechts": 3 if hud_control.rightLaneDepart else 1 + hud_control.rightLaneVisible,
"LDW_Texte": hud_alert,
})
return packer.make_can_msg("LDW_02", bus, values)
def create_acc_buttons_control(packer, bus, gra_stock_values, idx, cancel=False, resume=False):
values = gra_stock_values.copy()
values.update({
"COUNTER": idx,
"GRA_Abbrechen": cancel,
"GRA_Tip_Wiederaufnahme": resume,
})
return packer.make_can_msg("GRA_ACC_01", bus, values)

@ -4,6 +4,7 @@ from enum import Enum
from typing import Dict, List, Union from typing import Dict, List, Union
from cereal import car from cereal import car
from opendbc.can.can_define import CANDefine
from selfdrive.car import dbc_dict from selfdrive.car import dbc_dict
from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness from selfdrive.car.docs_definitions import CarFootnote, CarInfo, Column, Harness
@ -15,34 +16,32 @@ Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
class CarControllerParams: class CarControllerParams:
HCA_STEP = 2 # HCA_01 message frequency 50Hz HCA_STEP = 2 # HCA_01/HCA_1 message frequency 50Hz
LDW_STEP = 10 # LDW_02 message frequency 10Hz GRA_ACC_STEP = 3 # GRA_ACC_01/GRA_Neu message frequency 33Hz
GRA_ACC_STEP = 3 # GRA_ACC_01 message frequency 33Hz
# Observed documented MQB limits: 3.00 Nm max, rate of change 5.00 Nm/sec. def __init__(self, CP):
# Limiting rate-of-change based on real-world testing and Comma's safety # Documented lateral limits: 3.00 Nm max, rate of change 5.00 Nm/sec.
# requirements for minimum time to lane departure. # MQB vs PQ maximums are shared, but rate-of-change limited differently
STEER_MAX = 300 # Max heading control assist torque 3.00 Nm # based on safety requirements driven by lateral accel testing.
STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50)) self.STEER_MAX = 300 # Max heading control assist torque 3.00 Nm
STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) self.STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily
STEER_DRIVER_ALLOWANCE = 80 self.STEER_DRIVER_FACTOR = 1 # from dbc
STEER_DRIVER_MULTIPLIER = 3 # weight driver torque heavily
STEER_DRIVER_FACTOR = 1 # from dbc
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
class CANBUS: if True: # pylint: disable=using-constant-test
pt = 0 self.LDW_STEP = 10 # LDW_02 message frequency 10Hz
cam = 2 self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm
self.STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50))
self.STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60))
class DBC_FILES: if CP.transmissionType == TransmissionType.automatic:
mqb = "vw_mqb_2010" # Used for all cars with MQB-style CAN messaging self.shifter_values = can_define.dv["Getriebe_11"]["GE_Fahrstufe"]
elif CP.transmissionType == TransmissionType.direct:
self.shifter_values = can_define.dv["EV_Gearshift"]["GearPosition"]
self.hca_status_values = can_define.dv["LH_EPS_03"]["EPS_HCA_Status"]
self.BUTTONS = [
DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict(DBC_FILES.mqb, None))
MQB_BUTTONS = [
Button(car.CarState.ButtonEvent.Type.setCruise, "GRA_ACC_01", "GRA_Tip_Setzen", [1]), Button(car.CarState.ButtonEvent.Type.setCruise, "GRA_ACC_01", "GRA_Tip_Setzen", [1]),
Button(car.CarState.ButtonEvent.Type.resumeCruise, "GRA_ACC_01", "GRA_Tip_Wiederaufnahme", [1]), Button(car.CarState.ButtonEvent.Type.resumeCruise, "GRA_ACC_01", "GRA_Tip_Wiederaufnahme", [1]),
Button(car.CarState.ButtonEvent.Type.accelCruise, "GRA_ACC_01", "GRA_Tip_Hoch", [1]), Button(car.CarState.ButtonEvent.Type.accelCruise, "GRA_ACC_01", "GRA_Tip_Hoch", [1]),
@ -51,20 +50,24 @@ MQB_BUTTONS = [
Button(car.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_ACC_01", "GRA_Verstellung_Zeitluecke", [1]), Button(car.CarState.ButtonEvent.Type.gapAdjustCruise, "GRA_ACC_01", "GRA_Verstellung_Zeitluecke", [1]),
] ]
self.LDW_MESSAGES = {
MQB_LDW_MESSAGES = {
"none": 0, # Nothing to display "none": 0, # Nothing to display
"laneAssistUnavailChime": 1, # "Lane Assist currently not available." with chime "laneAssistUnavailChime": 1, # "Lane Assist currently not available." with chime
"laneAssistUnavailNoSensorChime": 3, # "Lane Assist not available. No sensor view." with chime "laneAssistUnavailNoSensorChime": 3, # "Lane Assist not available. No sensor view." with chime
"laneAssistTakeOverUrgent": 4, # "Lane Assist: Please Take Over Steering" with urgent beep "laneAssistTakeOverUrgent": 4, # "Lane Assist: Please Take Over Steering" with urgent beep
"emergencyAssistUrgent": 6, # "Emergency Assist: Please Take Over Steering" with urgent beep "emergencyAssistUrgent": 6, # "Emergency Assist: Please Take Over Steering" with urgent beep
"laneAssistTakeOverChime": 7, # "Lane Assist: Please Take Over Steering" with chime "laneAssistTakeOverChime": 7, # "Lane Assist: Please Take Over Steering" with chime
"laneAssistTakeOverSilent": 8, # "Lane Assist: Please Take Over Steering" silent "laneAssistTakeOver": 8, # "Lane Assist: Please Take Over Steering" silent
"emergencyAssistChangingLanes": 9, # "Emergency Assist: Changing lanes..." with urgent beep "emergencyAssistChangingLanes": 9, # "Emergency Assist: Changing lanes..." with urgent beep
"laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward "laneAssistDeactivated": 10, # "Lane Assist deactivated." silent with persistent icon afterward
} }
class CANBUS:
pt = 0
cam = 2
# Check the 7th and 8th characters of the VIN before adding a new CAR. If the # Check the 7th and 8th characters of the VIN before adding a new CAR. If the
# chassis code is already listed below, don't add a new CAR, just add to the # chassis code is already listed below, don't add a new CAR, just add to the
# FW_VERSIONS for that existing CAR. # FW_VERSIONS for that existing CAR.
@ -96,18 +99,22 @@ class CAR:
SKODA_OCTAVIA_MK3 = "SKODA OCTAVIA 3RD GEN" # Chassis NE, Mk3 Skoda Octavia and variants SKODA_OCTAVIA_MK3 = "SKODA OCTAVIA 3RD GEN" # Chassis NE, Mk3 Skoda Octavia and variants
DBC: Dict[str, Dict[str, str]] = defaultdict(lambda: dbc_dict("vw_mqb_2010", None))
class Footnote(Enum): class Footnote(Enum):
KAMIQ = CarFootnote( KAMIQ = CarFootnote(
"Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.", "Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.",
Column.MODEL) Column.MODEL)
PASSAT = CarFootnote( PASSAT = CarFootnote(
"Not including the USA/China market Passat, which is based on the (currently) unsupported PQ35/NMS platform.", "Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets.",
Column.MODEL) Column.MODEL)
VW_HARNESS = CarFootnote( VW_HARNESS = CarFootnote(
"Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma " + "Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma " +
"store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black " + "store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black " +
"(older design) or light brown (newer design). For the newer design, in the interim, choose \"VW J533 Development\" " + "(older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway " +
"from the vehicle drop-down for a harness that integrates at the CAN gateway inside the dashboard.", "inside the dashboard, choose \"VW J533 Development\" from the vehicle drop-down for a suitable harness. " +
"(Some newer models are also observed to not have a J533 connector.)",
Column.MODEL) Column.MODEL)
VW_VARIANT = CarFootnote( VW_VARIANT = CarFootnote(
"Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)", "Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)",
@ -177,7 +184,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"), CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"),
CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"), CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"),
CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.KAMIQ]), CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.KAMIQ]),
CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21"), CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21", footnotes=[Footnote.VW_HARNESS]),
CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"), CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"),
CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020"), CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020"),
CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-18"), CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-18"),

@ -1,42 +0,0 @@
# CAN controls for MQB platform Volkswagen, Audi, Skoda, and SEAT.
# PQ35/PQ46/NMS, and any future MLB, to come later.
def create_mqb_steering_control(packer, bus, apply_steer, lkas_enabled):
values = {
"SET_ME_0X3": 0x3,
"Assist_Torque": abs(apply_steer),
"Assist_Requested": lkas_enabled,
"Assist_VZ": 1 if apply_steer < 0 else 0,
"HCA_Available": 1,
"HCA_Standby": not lkas_enabled,
"HCA_Active": lkas_enabled,
"SET_ME_0XFE": 0xFE,
"SET_ME_0X07": 0x07,
}
return packer.make_can_msg("HCA_01", bus, values)
def create_mqb_hud_control(packer, bus, enabled, steering_pressed, hud_alert, left_lane_visible, right_lane_visible,
ldw_stock_values, left_lane_depart, right_lane_depart):
# Lane color reference:
# 0 (LKAS disabled) - off
# 1 (LKAS enabled, no lane detected) - dark gray
# 2 (LKAS enabled, lane detected) - light gray on VW, green or white on Audi depending on year or virtual cockpit. On a color MFD on a 2015 A3 TDI it is white, virtual cockpit on a 2018 A3 e-Tron its green.
# 3 (LKAS enabled, lane departure detected) - white on VW, red on Audi
values = ldw_stock_values.copy()
values.update({
"LDW_Status_LED_gelb": 1 if enabled and steering_pressed else 0,
"LDW_Status_LED_gruen": 1 if enabled and not steering_pressed else 0,
"LDW_Lernmodus_links": 3 if left_lane_depart else 1 + left_lane_visible,
"LDW_Lernmodus_rechts": 3 if right_lane_depart else 1 + right_lane_visible,
"LDW_Texte": hud_alert,
})
return packer.make_can_msg("LDW_02", bus, values)
def create_mqb_acc_buttons_control(packer, bus, gra_stock_values, idx, cancel=False, resume=False):
values = gra_stock_values.copy()
values["COUNTER"] = idx
values["GRA_Abbrechen"] = cancel
values["GRA_Tip_Wiederaufnahme"] = resume
return packer.make_can_msg("GRA_ACC_01", bus, values)

@ -645,8 +645,13 @@ class Controls:
if len(dpath_points): if len(dpath_points):
# Check if we deviated from the path # Check if we deviated from the path
# TODO use desired vs actual curvature # TODO use desired vs actual curvature
left_deviation = actuators.steer > 0 and dpath_points[0] < -0.20 if self.CP.steerControlType == car.CarParams.SteerControlType.angle:
right_deviation = actuators.steer < 0 and dpath_points[0] > 0.20 steering_value = actuators.steeringAngleDeg
else:
steering_value = actuators.steer
left_deviation = steering_value > 0 and dpath_points[0] < -0.20
right_deviation = steering_value < 0 and dpath_points[0] > 0.20
if left_deviation or right_deviation: if left_deviation or right_deviation:
self.events.add(EventName.steerSaturated) self.events.add(EventName.steerSaturated)

@ -48,7 +48,7 @@ class DesireHelper:
self.dp_lc_auto_min_mph = LANE_CHANGE_SPEED_MIN + 10 self.dp_lc_auto_min_mph = LANE_CHANGE_SPEED_MIN + 10
self.dp_lc_auto_delay = 3 # secs self.dp_lc_auto_delay = 3 # secs
def update(self, carstate, active, lane_change_prob, dragonconf): def update(self, carstate, lateral_active, lane_change_prob, dragonconf):
# dp - sync with dragonConf # dp - sync with dragonConf
self.dp_lateral_mode = dragonconf.dpLateralMode self.dp_lateral_mode = dragonconf.dpLateralMode
self.dp_lc_min_mph = dragonconf.dpLcMinMph * CV.MPH_TO_MS self.dp_lc_min_mph = dragonconf.dpLcMinMph * CV.MPH_TO_MS
@ -61,7 +61,7 @@ class DesireHelper:
below_lane_change_speed = v_ego < self.dp_lc_min_mph below_lane_change_speed = v_ego < self.dp_lc_min_mph
below_alc_speed = v_ego < self.dp_lc_auto_min_mph below_alc_speed = v_ego < self.dp_lc_auto_min_mph
if not active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
self.lane_change_state = LaneChangeState.off self.lane_change_state = LaneChangeState.off
self.lane_change_direction = LaneChangeDirection.none self.lane_change_direction = LaneChangeDirection.none
else: else:

@ -89,7 +89,7 @@ def gen_lat_ocp():
# TODO hacky weights to keep behavior the same # TODO hacky weights to keep behavior the same
ocp.model.cost_y_expr = vertcat(y_ego, ocp.model.cost_y_expr = vertcat(y_ego,
((v_ego +5.0) * psi_ego), ((v_ego +5.0) * psi_ego),
((v_ego +5.0) * 4 * curv_rate)) ((v_ego + 5.0) * 4.0 * curv_rate))
ocp.model.cost_y_expr_e = vertcat(y_ego, ocp.model.cost_y_expr_e = vertcat(y_ego,
((v_ego +5.0) * psi_ego)) ((v_ego +5.0) * psi_ego))
@ -147,7 +147,7 @@ class LateralMpc():
#TODO hacky weights to keep behavior the same #TODO hacky weights to keep behavior the same
self.solver.cost_set(N, 'W', (3/20.)*W[:2,:2]) self.solver.cost_set(N, 'W', (3/20.)*W[:2,:2])
def run(self, x0, p, y_pts, heading_pts): def run(self, x0, p, y_pts, heading_pts, curv_rate_pts):
x0_cp = np.copy(x0) x0_cp = np.copy(x0)
p_cp = np.copy(p) p_cp = np.copy(p)
self.solver.constraints_set(0, "lbx", x0_cp) self.solver.constraints_set(0, "lbx", x0_cp)
@ -156,6 +156,7 @@ class LateralMpc():
v_ego = p_cp[0] v_ego = p_cp[0]
# rotation_radius = p_cp[1] # rotation_radius = p_cp[1]
self.yref[:,1] = heading_pts*(v_ego+5.0) self.yref[:,1] = heading_pts*(v_ego+5.0)
self.yref[:,2] = curv_rate_pts * (v_ego+5.0) * 4.0
for i in range(N): for i in range(N):
self.solver.cost_set(i, "yref", self.yref[i]) self.solver.cost_set(i, "yref", self.yref[i])
self.solver.set(i, "p", p_cp) self.solver.set(i, "p", p_cp)

@ -3,7 +3,7 @@ from common.realtime import sec_since_boot, DT_MDL
from common.numpy_fast import interp from common.numpy_fast import interp
from system.swaglog import cloudlog from system.swaglog import cloudlog
from selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc from selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc
from selfdrive.controls.lib.drive_helpers import CONTROL_N, MPC_COST_LAT, LAT_MPC_N, CAR_ROTATION_RADIUS from selfdrive.controls.lib.drive_helpers import CONTROL_N, MPC_COST_LAT, LAT_MPC_N
from selfdrive.controls.lib.lane_planner import LanePlanner, TRAJECTORY_SIZE from selfdrive.controls.lib.lane_planner import LanePlanner, TRAJECTORY_SIZE
from selfdrive.controls.lib.desire_helper import DesireHelper from selfdrive.controls.lib.desire_helper import DesireHelper
import cereal.messaging as messaging import cereal.messaging as messaging
@ -11,17 +11,21 @@ from cereal import log
class LateralPlanner: class LateralPlanner:
def __init__(self, use_lanelines=True, wide_camera=False): def __init__(self, CP, use_lanelines=True, wide_camera=False):
self.use_lanelines = use_lanelines self.use_lanelines = use_lanelines
self.LP = LanePlanner(wide_camera) self.LP = LanePlanner(wide_camera)
self.DH = DesireHelper() self.DH = DesireHelper()
# Vehicle model parameters used to calculate lateral movement of car
self.factor1 = CP.wheelbase - CP.centerToFront
self.factor2 = (CP.centerToFront * CP.mass) / (CP.wheelbase * CP.tireStiffnessRear)
self.last_cloudlog_t = 0 self.last_cloudlog_t = 0
self.solution_invalid_cnt = 0 self.solution_invalid_cnt = 0
self.path_xyz = np.zeros((TRAJECTORY_SIZE, 3)) self.path_xyz = np.zeros((TRAJECTORY_SIZE, 3))
self.path_xyz_stds = np.ones((TRAJECTORY_SIZE, 3)) self.path_xyz_stds = np.ones((TRAJECTORY_SIZE, 3))
self.plan_yaw = np.zeros((TRAJECTORY_SIZE,)) self.plan_yaw = np.zeros((TRAJECTORY_SIZE,))
self.plan_curv_rate = np.zeros((TRAJECTORY_SIZE,))
self.t_idxs = np.arange(TRAJECTORY_SIZE) self.t_idxs = np.arange(TRAJECTORY_SIZE)
self.y_pts = np.zeros(TRAJECTORY_SIZE) self.y_pts = np.zeros(TRAJECTORY_SIZE)
self.d_path_w_lines_xyz = np.zeros((TRAJECTORY_SIZE, 3)) self.d_path_w_lines_xyz = np.zeros((TRAJECTORY_SIZE, 3))
@ -45,13 +49,13 @@ class LateralPlanner:
if len(md.position.x) == TRAJECTORY_SIZE and len(md.orientation.x) == TRAJECTORY_SIZE: if len(md.position.x) == TRAJECTORY_SIZE and len(md.orientation.x) == TRAJECTORY_SIZE:
self.path_xyz = np.column_stack([md.position.x, md.position.y, md.position.z]) self.path_xyz = np.column_stack([md.position.x, md.position.y, md.position.z])
self.t_idxs = np.array(md.position.t) self.t_idxs = np.array(md.position.t)
self.plan_yaw = list(md.orientation.z) self.plan_yaw = np.array(md.orientation.z)
if len(md.position.xStd) == TRAJECTORY_SIZE: if len(md.position.xStd) == TRAJECTORY_SIZE:
self.path_xyz_stds = np.column_stack([md.position.xStd, md.position.yStd, md.position.zStd]) self.path_xyz_stds = np.column_stack([md.position.xStd, md.position.yStd, md.position.zStd])
# Lane change logic # Lane change logic
lane_change_prob = self.LP.l_lane_change_prob + self.LP.r_lane_change_prob lane_change_prob = self.LP.l_lane_change_prob + self.LP.r_lane_change_prob
self.DH.update(sm['carState'], sm['controlsState'].active, lane_change_prob, sm['dragonConf']) self.DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob, sm['dragonConf'])
# Turn off lanes during lane change # Turn off lanes during lane change
if self.DH.desire == log.LateralPlan.Desire.laneChangeRight or self.DH.desire == log.LateralPlan.Desire.laneChangeLeft: if self.DH.desire == log.LateralPlan.Desire.laneChangeRight or self.DH.desire == log.LateralPlan.Desire.laneChangeLeft:
@ -78,16 +82,19 @@ class LateralPlanner:
y_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(d_path_xyz, axis=1), d_path_xyz[:, 1]) y_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(d_path_xyz, axis=1), d_path_xyz[:, 1])
heading_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_yaw) heading_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_yaw)
curv_rate_pts = np.interp(v_ego * self.t_idxs[:LAT_MPC_N + 1], np.linalg.norm(self.path_xyz, axis=1), self.plan_curv_rate)
self.y_pts = y_pts self.y_pts = y_pts
assert len(y_pts) == LAT_MPC_N + 1 assert len(y_pts) == LAT_MPC_N + 1
assert len(heading_pts) == LAT_MPC_N + 1 assert len(heading_pts) == LAT_MPC_N + 1
# self.x0[4] = v_ego assert len(curv_rate_pts) == LAT_MPC_N + 1
p = np.array([v_ego, CAR_ROTATION_RADIUS]) lateral_factor = max(0, self.factor1 - (self.factor2 * v_ego**2))
p = np.array([v_ego, lateral_factor])
self.lat_mpc.run(self.x0, self.lat_mpc.run(self.x0,
p, p,
y_pts, y_pts,
heading_pts) heading_pts,
curv_rate_pts)
# init state for next # init state for next
# mpc.u_sol is the desired curvature rate given x0 curv state. # mpc.u_sol is the desired curvature rate given x0 curv state.
# with x0[3] = measured_curvature, this would be the actual desired rate. # with x0[3] = measured_curvature, this would be the actual desired rate.

@ -23,10 +23,10 @@ def plannerd_thread(sm=None, pm=None):
cloudlog.event("e2e mode", on=use_lanelines) cloudlog.event("e2e mode", on=use_lanelines)
longitudinal_planner = Planner(CP) longitudinal_planner = Planner(CP)
lateral_planner = LateralPlanner(use_lanelines=use_lanelines, wide_camera=wide_camera) lateral_planner = LateralPlanner(CP, use_lanelines=use_lanelines, wide_camera=wide_camera)
if sm is None: if sm is None:
sm = messaging.SubMaster(['carState', 'controlsState', 'radarState', 'modelV2', 'dragonConf', 'lateralPlan', 'navInstruction', 'liveMapData'], sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2', 'dragonConf', 'lateralPlan', 'navInstruction', 'liveMapData'],
poll=['radarState', 'modelV2'], ignore_avg_freq=['radarState']) poll=['radarState', 'modelV2'], ignore_avg_freq=['radarState'])
if pm is None: if pm is None:

Binary file not shown.

Binary file not shown.

@ -86,9 +86,17 @@ class Route():
b = np.arctan2(v[:, 0], v[:, 1]) b = np.arctan2(v[:, 0], v[:, 1])
# - Find index of las_wr section and calculate deltas of bearings to the other sections. # - Find index of las_wr section and calculate deltas of bearings to the other sections.
# dp - force re init if last_wr_idx return ValueError?
try:
last_wr_idx = way_relations.index(last_wr) last_wr_idx = way_relations.index(last_wr)
b_ref = b[last_wr_idx] b_ref = b[last_wr_idx]
delta = b - b_ref delta = b - b_ref
except ValueError:
self.way_collection_id = way_collection_id
self._ordered_way_relations = []
self._nodes_data = None
self._reset()
return
# - Update the direction of the possible route continuation ways as starting from last_node_id. # - Update the direction of the possible route continuation ways as starting from last_node_id.
# Make sure to exclude any ways already included in the ordered list as to not modify direction when there # Make sure to exclude any ways already included in the ordered list as to not modify direction when there

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,5 +1,6 @@
{ {
"English": "main_en", "English": "main_en",
"Português": "main_pt",
"中文(繁體)": "main_zh-CHT", "中文(繁體)": "main_zh-CHT",
"中文(简体)": "main_zh-CHS", "中文(简体)": "main_zh-CHS",
"한국어": "main_ko", "한국어": "main_ko",

@ -164,6 +164,22 @@ Reboot required.</source>
<location filename="../qt/offroad/settings_dp.cc" line="415"/> <location filename="../qt/offroad/settings_dp.cc" line="415"/>
<source>Enable this to link Accel Mode (AM) control to the physical button (TSS2). <source>Enable this to link Accel Mode (AM) control to the physical button (TSS2).
ONLY WORK ON SOME OF TSS1 VEHICLES. ONLY WORK ON SOME OF TSS1 VEHICLES.
Reboot required.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="428"/>
<source>Honda</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable EPS Mod Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable this will increase steering, USE IT ONLY if you have a modded EPS firmware.
Reboot required.</source> Reboot required.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1631,23 +1647,23 @@ location set</source>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="305"/> <location filename="../qt/offroad/settings.cc" line="305"/>
<source>Switch Branch</source> <source>Switch Branch</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="305"/> <location filename="../qt/offroad/settings.cc" line="305"/>
<source>ENTER</source> <source>ENTER</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="305"/> <location filename="../qt/offroad/settings.cc" line="305"/>
<location filename="../qt/offroad/settings.cc" line="307"/> <location filename="../qt/offroad/settings.cc" line="307"/>
<source>The new branch will be pulled the next time the updater runs.</source> <source>The new branch will be pulled the next time the updater runs.</source>
<translation type="unfinished"></translation> <translation>updater </translation>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="307"/> <location filename="../qt/offroad/settings.cc" line="307"/>
<source>Enter branch name</source> <source>Enter branch name</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="318"/> <location filename="../qt/offroad/settings.cc" line="318"/>
@ -1820,7 +1836,7 @@ location set</source>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="116"/> <location filename="../qt/offroad/settings.cc" line="116"/>
<source>Show ETA in 24h format</source> <source>Show ETA in 24h Format</source>
<translation>24</translation> <translation>24</translation>
</message> </message>
<message> <message>

@ -164,6 +164,22 @@ Reboot required.</source>
<location filename="../qt/offroad/settings_dp.cc" line="415"/> <location filename="../qt/offroad/settings_dp.cc" line="415"/>
<source>Enable this to link Accel Mode (AM) control to the physical button (TSS2). <source>Enable this to link Accel Mode (AM) control to the physical button (TSS2).
ONLY WORK ON SOME OF TSS1 VEHICLES. ONLY WORK ON SOME OF TSS1 VEHICLES.
Reboot required.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="428"/>
<source>Honda</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable EPS Mod Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable this will increase steering, USE IT ONLY if you have a modded EPS firmware.
Reboot required.</source> Reboot required.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1820,7 +1836,7 @@ location set</source>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="116"/> <location filename="../qt/offroad/settings.cc" line="116"/>
<source>Show ETA in 24h format</source> <source>Show ETA in 24h Format</source>
<translation>24 </translation> <translation>24 </translation>
</message> </message>
<message> <message>

File diff suppressed because it is too large Load Diff

@ -164,6 +164,22 @@ Reboot required.</source>
<location filename="../qt/offroad/settings_dp.cc" line="415"/> <location filename="../qt/offroad/settings_dp.cc" line="415"/>
<source>Enable this to link Accel Mode (AM) control to the physical button (TSS2). <source>Enable this to link Accel Mode (AM) control to the physical button (TSS2).
ONLY WORK ON SOME OF TSS1 VEHICLES. ONLY WORK ON SOME OF TSS1 VEHICLES.
Reboot required.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="428"/>
<source>Honda</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable EPS Mod Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable this will increase steering, USE IT ONLY if you have a modded EPS firmware.
Reboot required.</source> Reboot required.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1818,7 +1834,7 @@ location set</source>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="116"/> <location filename="../qt/offroad/settings.cc" line="116"/>
<source>Show ETA in 24h format</source> <source>Show ETA in 24h Format</source>
<translation>24</translation> <translation>24</translation>
</message> </message>
<message> <message>

@ -171,6 +171,22 @@ Reboot required.</source>
TSS1車型上也可以使用 TSS1車型上也可以使用
</translation> </translation>
</message> </message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="428"/>
<source>Honda</source>
<translation></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable EPS Mod Mode</source>
<translation></translation>
</message>
<message>
<location filename="../qt/offroad/settings_dp.cc" line="430"/>
<source>Enable this will increase steering, USE IT ONLY if you have a modded EPS firmware.
Reboot required.</source>
<translation></translation>
</message>
<message> <message>
<location filename="../qt/offroad/settings_dp.cc" line="448"/> <location filename="../qt/offroad/settings_dp.cc" line="448"/>
<source>Mazda</source> <source>Mazda</source>
@ -1852,7 +1868,7 @@ location set</source>
</message> </message>
<message> <message>
<location filename="../qt/offroad/settings.cc" line="116"/> <location filename="../qt/offroad/settings.cc" line="116"/>
<source>Show ETA in 24h format</source> <source>Show ETA in 24h Format</source>
<translation> 24 </translation> <translation> 24 </translation>
</message> </message>
<message> <message>

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save