Merge branch 'master' into mqb-long

mqb-long
Jason Young 3 years ago
commit 99221fbbbd
  1. 9
      RELEASES.md
  2. 2
      cereal
  3. 8
      common/params.cc
  4. 55
      docs/CARS.md
  5. 2
      launch_env.sh
  6. 2
      opendbc
  7. 2
      panda
  8. 3
      release/files_common
  9. BIN
      selfdrive/assets/images/button_flag.png
  10. 55
      selfdrive/boardd/boardd.cc
  11. 9
      selfdrive/boardd/panda.cc
  12. 2
      selfdrive/boardd/panda.h
  13. 23
      selfdrive/car/gm/interface.py
  14. 12
      selfdrive/car/gm/values.py
  15. 1
      selfdrive/car/hyundai/carcontroller.py
  16. 26
      selfdrive/car/hyundai/carstate.py
  17. 2
      selfdrive/car/hyundai/hyundaican.py
  18. 4
      selfdrive/car/hyundai/interface.py
  19. 114
      selfdrive/car/hyundai/values.py
  20. 29
      selfdrive/car/interfaces.py
  21. 2
      selfdrive/car/isotp_parallel_query.py
  22. 4
      selfdrive/car/mazda/interface.py
  23. 4
      selfdrive/car/mock/interface.py
  24. 46
      selfdrive/car/tesla/values.py
  25. 3
      selfdrive/car/tests/routes.py
  26. 3
      selfdrive/car/tests/test_docs.py
  27. 2
      selfdrive/car/torque_data/override.yaml
  28. 3
      selfdrive/car/torque_data/substitute.yaml
  29. 2
      selfdrive/car/toyota/carcontroller.py
  30. 1
      selfdrive/car/toyota/values.py
  31. 1
      selfdrive/car/volkswagen/values.py
  32. 12
      selfdrive/controls/controlsd.py
  33. 35
      selfdrive/controls/lib/latcontrol_torque.py
  34. 290
      selfdrive/locationd/torqued.py
  35. 6
      selfdrive/locationd/ublox_msg.cc
  36. 6
      selfdrive/loggerd/SConscript
  37. 8
      selfdrive/loggerd/bootlog.cc
  38. 1
      selfdrive/loggerd/encoder/v4l_encoder.h
  39. 12
      selfdrive/loggerd/tests/test_loggerd.py
  40. 1
      selfdrive/manager/process_config.py
  41. 4
      selfdrive/sensord/pigeond.py
  42. 18
      selfdrive/sensord/sensors/bmx055_accel.cc
  43. 5
      selfdrive/sensord/sensors/bmx055_accel.h
  44. 18
      selfdrive/sensord/sensors/bmx055_gyro.cc
  45. 5
      selfdrive/sensord/sensors/bmx055_gyro.h
  46. 10
      selfdrive/sensord/sensors/bmx055_magn.cc
  47. 2
      selfdrive/sensord/sensors/bmx055_magn.h
  48. 17
      selfdrive/sensord/sensors/lsm6ds3_accel.cc
  49. 17
      selfdrive/sensord/sensors/lsm6ds3_gyro.cc
  50. 28
      selfdrive/sensord/sensors/mmc5603nj_magn.cc
  51. 2
      selfdrive/sensord/sensors/mmc5603nj_magn.h
  52. 25
      selfdrive/sensord/sensors_qcom2.cc
  53. 103
      selfdrive/sensord/tests/test_sensord.py
  54. 27
      selfdrive/test/process_replay/process_replay.py
  55. 2
      selfdrive/test/process_replay/ref_commit
  56. 8
      selfdrive/test/process_replay/regen.py
  57. 11
      selfdrive/test/process_replay/regen_all.py
  58. 40
      selfdrive/test/process_replay/test_processes.py
  59. 1
      selfdrive/test/test_onroad.py
  60. 2
      selfdrive/test/update_ci_routes.py
  61. 1
      selfdrive/ui/qt/home.cc
  62. 3
      selfdrive/ui/qt/maps/map.cc
  63. 2
      selfdrive/ui/qt/maps/map.h
  64. 4
      selfdrive/ui/qt/offroad/settings.cc
  65. 2
      selfdrive/ui/qt/offroad/software_settings.cc
  66. 5
      selfdrive/ui/qt/onroad.cc
  67. 32
      selfdrive/ui/qt/sidebar.cc
  68. 5
      selfdrive/ui/qt/sidebar.h
  69. 2
      selfdrive/ui/qt/widgets/controls.cc
  70. 4
      selfdrive/ui/qt/widgets/prime.cc
  71. 12
      selfdrive/ui/tests/test_translations.py
  72. 4
      selfdrive/ui/translations/main_en.ts
  73. 270
      selfdrive/ui/translations/main_ja.ts
  74. 270
      selfdrive/ui/translations/main_ko.ts
  75. 282
      selfdrive/ui/translations/main_pt-BR.ts
  76. 256
      selfdrive/ui/translations/main_zh-CHS.ts
  77. 278
      selfdrive/ui/translations/main_zh-CHT.ts
  78. 2
      selfdrive/ui/update_translations.py
  79. 23
      selfdrive/updated.py
  80. 23
      system/camerad/cameras/camera_common.cc
  81. 9
      system/camerad/cameras/camera_common.h
  82. 28
      system/camerad/cameras/camera_qcom2.cc
  83. 6
      system/camerad/cameras/real_debayer.cl
  84. 16
      system/camerad/cameras/sensor2_i2c.h
  85. 12
      system/hardware/tici/agnos.json
  86. 11
      system/hardware/tici/hardware.py
  87. 19
      tools/camerastream/compressed_vipc.py
  88. 1
      tools/replay/replay.cc

@ -2,6 +2,15 @@ Version 0.8.17 (2022-XX-XX)
========================
* New driving model
* Internal feature space accuracy increased tenfold during training, this makes the model dramatically more accurate.
* Self-tuning torque lateral controller parameters
* Parameters are learned live for each car
* Enabled only on Toyota Corolla for now
* UI updates
* Matched speeds shown on car's dash
* Improved update experience
* Border turns grey while overriding steering
* Added button to flag events that are shown in comma connect
* AGNOS 6
Version 0.8.16 (2022-08-26)
========================

@ -1 +1 @@
Subproject commit 513dfc7ee001243cd68a57a9d92fe3170fc49c7d
Subproject commit a0c6f28d6bce2fd7d7ef2fd29e80d2eab118a6c6

@ -144,6 +144,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"LastUpdateException", CLEAR_ON_MANAGER_START},
{"LastUpdateTime", PERSISTENT},
{"LiveParameters", PERSISTENT},
{"LiveTorqueCarParams", PERSISTENT},
{"LiveTorqueParameters", PERSISTENT | DONT_LOG},
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
{"NavSettingTime24h", PERSISTENT},
{"NavSettingLeftSide", PERSISTENT},
@ -198,10 +200,8 @@ std::unordered_map<std::string, uint32_t> keys = {
Params::Params(const std::string &path) {
const char* env = std::getenv("OPENPILOT_PREFIX");
prefix = env ? "/" + std::string(env) : "/d";
std::string default_param_path = ensure_params_path(prefix);
params_path = path.empty() ? default_param_path : ensure_params_path(prefix, path);
prefix = "/" + util::getenv("OPENPILOT_PREFIX", "d");
params_path = ensure_params_path(prefix, path);
}
std::vector<std::string> Params::allKeys() const {

@ -4,7 +4,7 @@
A supported vehicle is one that just works when you install a comma three. All supported cars provide a better experience than any stock system.
# 205 Supported Cars
# 204 Supported Cars
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Harness|
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|
@ -53,27 +53,27 @@ A supported vehicle is one that just works when you install a comma three. All s
|Honda|Passport 2019-21|All|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Honda|Ridgeline 2017-22|Honda Sensing|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec|
|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC) & LKAS|Stock|19 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Elantra 2017-19|Smart Cruise Control (SCC)|Stock|19 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Hyundai|Elantra 2021-22|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Elantra Hybrid 2021-22|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai K|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC) & LKAS|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai J|
|Hyundai|Genesis 2015-16|Smart Cruise Control (SCC)|Stock|19 mph|37 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai J|
|Hyundai|Ioniq 5 2022|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai Q|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Electric 2020|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC) & LFA|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Plug-in Hybrid 2020-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Electric 2019|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Electric 2020|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Hybrid 2017-19|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Hybrid 2020-22|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Ioniq Plug-in Hybrid 2019|Smart Cruise Control (SCC)|openpilot|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Hyundai|Ioniq Plug-in Hybrid 2020-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Kona 2020|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Hyundai|Kona Electric 2018-21|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Hyundai|Kona Electric 2022|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai O|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai I|
|Hyundai|Kona Hybrid 2020|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai I|
|Hyundai|Palisade 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Hyundai|Santa Fe 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai D|
|Hyundai|Santa Fe 2021-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Santa Fe Hybrid 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Santa Fe Plug-in Hybrid 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Hyundai|Sonata 2018-19|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Hyundai|Sonata 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Hyundai|Sonata Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Hyundai|Tucson 2021|Smart Cruise Control (SCC)|openpilot|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L|
@ -82,24 +82,23 @@ A supported vehicle is one that just works when you install a comma three. All s
|Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA|
|Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|Ceed 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|EV6 2022|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai P|
|Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Kia|Forte 2019-21|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|Forte 2019-21|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|K5 2021-22|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Kia|Niro Electric 2019|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Electric 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro Electric 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Niro Electric 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Plug-in Hybrid 2018-19|Smart Cruise Control (SCC) & LKAS|openpilot|10 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Optima 2017|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Kia|Optima 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|Niro EV 2019|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro EV 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro EV 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Niro EV 2022|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Hybrid 2021|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F|
|Kia|Niro Hybrid 2022|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Kia|Niro Plug-in Hybrid 2018-19|All|openpilot|10 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B|
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai G|
|Kia|Seltos 2021|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai A|
|Kia|Sorento 2018|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Sorento 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|Stinger 2018-20|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Sorento 2018|Advanced Smart Cruise Control|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E|
|Kia|Stinger 2018-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C|
|Kia|Telluride 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H|
|Lexus|CT Hybrid 2017-18|Lexus Safety System+|Stock[<sup>3</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota|
|Lexus|ES 2019-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota|

@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1
if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="5.2"
export AGNOS_VERSION="6"
fi
if [ -z "$PASSIVE" ]; then

@ -1 +1 @@
Subproject commit e95ed311c10547026143b539a33341425cbec9ea
Subproject commit eaac172af9cb342204e69ec52339cdf3c6a8ac4e

@ -1 +1 @@
Subproject commit b16d97b05ef5ab74c62479f1f74a6adc34869c9d
Subproject commit 37bad6776c8d91f7a1926cd731cc9a5f5a67c956

@ -240,6 +240,7 @@ selfdrive/locationd/models/live_kf.cc
selfdrive/locationd/models/constants.py
selfdrive/locationd/models/gnss_helpers.py
selfdrive/locationd/torqued.py
selfdrive/locationd/calibrationd.py
system/logcatd/.gitignore
@ -534,7 +535,7 @@ opendbc/honda_civic_ex_2022_can_generated.dbc
opendbc/hyundai_canfd.dbc
opendbc/hyundai_kia_generic.dbc
opendbc/hyundai_kia_mando_front_radar.dbc
opendbc/hyundai_kia_mando_front_radar_generated.dbc
opendbc/mazda_2017.dbc

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -114,9 +114,8 @@ bool safety_setter_thread(std::vector<Panda *> pandas) {
}
// set to ELM327 for fingerprinting
pandas[0]->set_safety_model(cereal::CarParams::SafetyModel::ELM327);
for (int i = 1; i < pandas.size(); i++) {
pandas[i]->set_safety_model(cereal::CarParams::SafetyModel::SILENT);
for (Panda *panda : pandas) {
panda->set_safety_model(cereal::CarParams::SafetyModel::ELM327);
}
Params p = Params();
@ -138,7 +137,9 @@ bool safety_setter_thread(std::vector<Panda *> pandas) {
}
// set to ELM327 for ECU knockouts
pandas[0]->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1U);
for (Panda *panda : pandas) {
panda->set_safety_model(cereal::CarParams::SafetyModel::ELM327, 1U);
}
std::string params;
LOGW("waiting for params to set safety model");
@ -295,13 +296,19 @@ void send_empty_panda_state(PubMaster *pm) {
std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *> &pandas, bool spoofing_started) {
bool ignition_local = false;
const uint32_t pandas_cnt = pandas.size();
// build msg
MessageBuilder msg;
auto evt = msg.initEvent();
auto pss = evt.initPandaStates(pandas.size());
auto pss = evt.initPandaStates(pandas_cnt);
std::vector<health_t> pandaStates;
pandaStates.reserve(pandas_cnt);
std::vector<std::array<can_health_t, PANDA_CAN_CNT>> pandaCanStates;
pandaCanStates.reserve(pandas_cnt);
for (const auto& panda : pandas){
auto health_opt = panda->get_state();
if (!health_opt) {
@ -310,6 +317,16 @@ std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *>
health_t health = *health_opt;
std::array<can_health_t, PANDA_CAN_CNT> can_health{};
for (uint32_t i = 0; i < PANDA_CAN_CNT; i++) {
auto can_health_opt = panda->get_can_state(i);
if (!can_health_opt) {
return std::nullopt;
}
can_health[i] = *can_health_opt;
}
pandaCanStates.push_back(can_health);
if (spoofing_started) {
health.ignition_line_pkt = 1;
}
@ -319,7 +336,7 @@ std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *>
pandaStates.push_back(health);
}
for (uint32_t i = 0; i < pandas.size(); i++) {
for (uint32_t i = 0; i < pandas_cnt; i++) {
auto panda = pandas[i];
const auto &health = pandaStates[i];
@ -366,6 +383,32 @@ std::optional<bool> send_panda_states(PubMaster *pm, const std::vector<Panda *>
ps.setInterruptLoad(health.interrupt_load);
ps.setFanPower(health.fan_power);
std::array<cereal::PandaState::PandaCanState::Builder, PANDA_CAN_CNT> cs = {ps.initCanState0(), ps.initCanState1(), ps.initCanState2()};
for (uint32_t j = 0; j < PANDA_CAN_CNT; j++) {
const auto &can_health = pandaCanStates[i][j];
cs[j].setBusOff((bool)can_health.bus_off);
cs[j].setBusOffCnt(can_health.bus_off_cnt);
cs[j].setErrorWarning((bool)can_health.error_warning);
cs[j].setErrorPassive((bool)can_health.error_passive);
cs[j].setLastError(cereal::PandaState::PandaCanState::LecErrorCode(can_health.last_error));
cs[j].setLastStoredError(cereal::PandaState::PandaCanState::LecErrorCode(can_health.last_stored_error));
cs[j].setLastDataError(cereal::PandaState::PandaCanState::LecErrorCode(can_health.last_data_error));
cs[j].setLastDataStoredError(cereal::PandaState::PandaCanState::LecErrorCode(can_health.last_data_stored_error));
cs[j].setReceiveErrorCnt(can_health.receive_error_cnt);
cs[j].setTransmitErrorCnt(can_health.transmit_error_cnt);
cs[j].setTotalErrorCnt(can_health.total_error_cnt);
cs[j].setTotalTxLostCnt(can_health.total_tx_lost_cnt);
cs[j].setTotalRxLostCnt(can_health.total_rx_lost_cnt);
cs[j].setTotalTxCnt(can_health.total_tx_cnt);
cs[j].setTotalRxCnt(can_health.total_rx_cnt);
cs[j].setTotalFwdCnt(can_health.total_fwd_cnt);
cs[j].setCanSpeed(can_health.can_speed);
cs[j].setCanDataSpeed(can_health.can_data_speed);
cs[j].setCanfdEnabled(can_health.canfd_enabled);
cs[j].setBrsEnabled(can_health.brs_enabled);
}
// Convert faults bitset to capnp list
std::bitset<sizeof(health.faults_pkt) * 8> fault_bits(health.faults_pkt);
auto faults = ps.initFaults(fault_bits.count());

@ -317,6 +317,12 @@ std::optional<health_t> Panda::get_state() {
return err >= 0 ? std::make_optional(health) : std::nullopt;
}
std::optional<can_health_t> Panda::get_can_state(uint16_t can_number) {
can_health_t can_health {0};
int err = usb_read(0xc2, can_number, 0, (unsigned char*)&can_health, sizeof(can_health));
return err >= 0 ? std::make_optional(can_health) : std::nullopt;
}
void Panda::set_loopback(bool loopback) {
usb_write(0xe5, loopback, 0);
}
@ -389,7 +395,8 @@ void Panda::pack_can_buffer(const capnp::List<cereal::CanData>::Reader &can_data
}
auto can_data = cmsg.getDat();
uint8_t data_len_code = len_to_dlc(can_data.size());
assert(can_data.size() <= ((hw_type == cereal::PandaState::PandaType::RED_PANDA) ? 64 : 8));
assert(can_data.size() <= ((hw_type == cereal::PandaState::PandaType::RED_PANDA ||
hw_type == cereal::PandaState::PandaType::RED_PANDA_V2) ? 64 : 8));
assert(can_data.size() == dlc_to_len[data_len_code]);
can_header header;

@ -16,6 +16,7 @@
#include "panda/board/health.h"
#define TIMEOUT 0
#define PANDA_CAN_CNT 3
#define PANDA_BUS_CNT 4
#define RECV_SIZE (0x4000U)
#define USB_TX_SOFT_LIMIT (0x100U)
@ -81,6 +82,7 @@ class Panda {
uint16_t get_fan_speed();
void set_ir_pwr(uint16_t ir_pwr);
std::optional<health_t> get_state();
std::optional<can_health_t> get_can_state(uint16_t can_number);
void set_loopback(bool loopback);
std::optional<std::vector<uint8_t>> get_firmware_version();
std::optional<std::string> get_serial();

@ -71,10 +71,11 @@ class CarInterface(CarInterfaceBase):
# These cars have been put into dashcam only due to both a lack of users and test coverage.
# These cars likely still work fine. Once a user confirms each car works and a test route is
# added to selfdrive/car/tests/routes.py, we can remove it from this list.
ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL}
ret.dashcamOnly = candidate in {CAR.CADILLAC_ATS, CAR.HOLDEN_ASTRA, CAR.MALIBU, CAR.BUICK_REGAL, CAR.EQUINOX, CAR.BOLT_EV}
# Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below.
ret.minSteerSpeed = 10 * CV.KPH_TO_MS
# Some GMs need some tolerance above 10 kph to avoid a fault
ret.minSteerSpeed = 10.1 * CV.KPH_TO_MS
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.kf = 0.00004 # full torque for 20 deg at 80mph means 0.00007818594
@ -138,25 +139,25 @@ class CarInterface(CarInterfaceBase):
ret.mass = 1601. + STD_CARGO_KG
ret.wheelbase = 2.78
ret.steerRatio = 15.3
ret.centerToFront = ret.wheelbase * 0.49
ret.centerToFront = ret.wheelbase * 0.5
elif candidate == CAR.ESCALADE_ESV:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.mass = 2739. + STD_CARGO_KG
ret.wheelbase = 3.302
ret.steerRatio = 17.3
ret.centerToFront = ret.wheelbase * 0.49
ret.centerToFront = ret.wheelbase * 0.5
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[10., 41.0], [10., 41.0]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.13, 0.24], [0.01, 0.02]]
ret.lateralTuning.pid.kf = 0.000045
tire_stiffness_factor = 1.0
elif candidate == CAR.BOLT_EUV:
elif candidate in (CAR.BOLT_EV, CAR.BOLT_EUV):
ret.minEnableSpeed = -1
ret.mass = 1669. + STD_CARGO_KG
ret.wheelbase = 2.675
ret.wheelbase = 2.63779
ret.steerRatio = 16.8
ret.centerToFront = ret.wheelbase * 0.4
ret.centerToFront = 2.15 # measured
tire_stiffness_factor = 1.0
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
@ -170,6 +171,14 @@ class CarInterface(CarInterfaceBase):
tire_stiffness_factor = 1.0
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.EQUINOX:
ret.minEnableSpeed = -1
ret.mass = 3500. * CV.LB_TO_KG + STD_CARGO_KG
ret.wheelbase = 2.72
ret.steerRatio = 14.4
ret.centerToFront = ret.wheelbase * 0.4
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase
ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase)

@ -58,8 +58,10 @@ class CAR:
ACADIA = "GMC ACADIA DENALI 2018"
BUICK_REGAL = "BUICK REGAL ESSENCE 2018"
ESCALADE_ESV = "CADILLAC ESCALADE ESV 2016"
BOLT_EV = "CHEVROLET BOLT EV 2022"
BOLT_EUV = "CHEVROLET BOLT EUV 2022"
SILVERADO = "CHEVROLET SILVERADO 1500 2020"
EQUINOX = "CHEVROLET EQUINOX 2019"
class Footnote(Enum):
@ -84,11 +86,13 @@ CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = {
CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"),
CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"),
CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"),
CAR.BOLT_EV: GMCarInfo("Chevrolet Bolt EV 2022-23", "Adaptive Cruise Control (ACC)", footnotes=[], harness=Harness.gm),
CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm),
CAR.SILVERADO: [
GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II", footnotes=[], harness=Harness.gm),
GMCarInfo("GMC Sierra 1500 2020-21", "Driver Alert Package II", footnotes=[], harness=Harness.gm),
],
CAR.EQUINOX: GMCarInfo("Chevrolet Equinox 2019-22", "Adaptive Cruise Control (ACC)", footnotes=[], harness=Harness.gm),
}
@ -166,13 +170,17 @@ FINGERPRINTS = {
{
190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 460: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 534: 2, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 801: 8, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7
}],
CAR.EQUINOX: [
{
190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 510: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 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'))
EV_CAR = {CAR.VOLT, CAR.BOLT_EUV}
EV_CAR = {CAR.VOLT, CAR.BOLT_EV, 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, CAR.SILVERADO}
CAMERA_ACC_CAR = {CAR.BOLT_EV, CAR.BOLT_EUV, CAR.SILVERADO, CAR.EQUINOX}
STEER_THRESHOLD = 1.0

@ -97,6 +97,7 @@ class CarController:
# cruise standstill resume
elif CC.cruiseControl.resume:
if not (self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS):
for _ in range(20):
can_sends.append(hyundaicanfd.create_buttons(self.packer, CS.buttons_counter+1, Buttons.RES_ACCEL))
self.last_button_frame = self.frame
else:

@ -1,5 +1,6 @@
from collections import deque
import copy
import math
from cereal import car
from common.conversions import Conversions as CV
@ -9,6 +10,7 @@ from selfdrive.car.hyundai.values import HyundaiFlags, DBC, FEATURES, CAMERA_SCC
from selfdrive.car.interfaces import CarStateBase
PREV_BUTTON_SAMPLES = 8
CLUSTER_SAMPLE_RATE = 20 # frames
class CarState(CarStateBase):
@ -32,6 +34,10 @@ class CarState(CarStateBase):
self.park_brake = False
self.buttons_counter = 0
# On some cars, CLU15->CF_Clu_VehicleSpeed can oscillate faster than the dash updates. Sample at 5 Hz
self.cluster_speed = 0
self.cluster_speed_counter = CLUSTER_SAMPLE_RATE
self.params = CarControllerParams(CP)
def update(self, cp, cp_cam):
@ -39,8 +45,9 @@ class CarState(CarStateBase):
return self.update_canfd(cp, cp_cam)
ret = car.CarState.new_message()
cp_cruise = cp_cam if self.CP.carFingerprint in CAMERA_SCC_CAR else cp
is_metric = cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"] == 0
speed_conv = CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS
ret.doorOpen = any([cp.vl["CGW1"]["CF_Gway_DrvDrSw"], cp.vl["CGW1"]["CF_Gway_AstDrSw"],
cp.vl["CGW2"]["CF_Gway_RLDrSw"], cp.vl["CGW2"]["CF_Gway_RRDrSw"]])
@ -55,9 +62,19 @@ class CarState(CarStateBase):
)
ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4.
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
ret.standstill = ret.vEgoRaw < 0.1
self.cluster_speed_counter += 1
if self.cluster_speed_counter > CLUSTER_SAMPLE_RATE:
self.cluster_speed = cp.vl["CLU15"]["CF_Clu_VehicleSpeed"]
self.cluster_speed_counter = 0
# mimic how dash converts to imperial
if not is_metric:
self.cluster_speed = math.floor(self.cluster_speed * CV.KPH_TO_MPH + CV.KPH_TO_MPH)
ret.vEgoCluster = self.cluster_speed * speed_conv
ret.steeringAngleDeg = cp.vl["SAS11"]["SAS_Angle"]
ret.steeringRateDeg = cp.vl["SAS11"]["SAS_Speed"]
ret.yawRate = cp.vl["ESP12"]["YAW_RATE"]
@ -78,7 +95,6 @@ class CarState(CarStateBase):
ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1
ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0
ret.cruiseState.standstill = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 4.
speed_conv = CV.MPH_TO_MS if cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"] else CV.KPH_TO_MS
ret.cruiseState.speed = cp_cruise.vl["SCC11"]["VSetDis"] * speed_conv
# TODO: Find brake pressure
@ -227,6 +243,8 @@ class CarState(CarStateBase):
("CF_Clu_AmpInfo", "CLU11"),
("CF_Clu_AliveCnt1", "CLU11"),
("CF_Clu_VehicleSpeed", "CLU15"),
("ACCEnable", "TCS13"),
("ACC_REQ", "TCS13"),
("DriverBraking", "TCS13"),
@ -251,6 +269,7 @@ class CarState(CarStateBase):
("TCS13", 50),
("TCS15", 10),
("CLU11", 50),
("CLU15", 5),
("ESP12", 100),
("CGW1", 10),
("CGW2", 5),
@ -309,7 +328,6 @@ class CarState(CarStateBase):
if CP.carFingerprint in FEATURES["use_cluster_gears"]:
signals.append(("CF_Clu_Gear", "CLU15"))
checks.append(("CLU15", 5))
elif CP.carFingerprint in FEATURES["use_tcu_gears"]:
signals.append(("CUR_GR", "TCU12"))
checks.append(("TCU12", 100))

@ -38,7 +38,7 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0
# Likely cars lacking the ability to show individual lane lines in the dash
elif car_fingerprint in (CAR.KIA_OPTIMA,):
elif car_fingerprint in (CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_2019):
# SysWarning 4 = keep hands on wheel + beep
values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0

@ -202,11 +202,13 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.indi.timeConstantV = [1.4]
ret.lateralTuning.indi.actuatorEffectivenessBP = [0.]
ret.lateralTuning.indi.actuatorEffectivenessV = [1.8]
elif candidate in (CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_H):
elif candidate in (CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_2019, CAR.KIA_OPTIMA_H):
ret.mass = 3558. * CV.LB_TO_KG
ret.wheelbase = 2.80
ret.steerRatio = 13.75
tire_stiffness_factor = 0.5
if candidate == CAR.KIA_OPTIMA:
ret.minSteerSpeed = 32 * CV.MPH_TO_MS
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.KIA_STINGER:
ret.lateralTuning.pid.kf = 0.00005

@ -85,7 +85,8 @@ class CAR:
KIA_NIRO_EV = "KIA NIRO EV 2020"
KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019"
KIA_NIRO_HEV_2021 = "KIA NIRO HYBRID 2021"
KIA_OPTIMA = "KIA OPTIMA SX 2019 & 2016"
KIA_OPTIMA = "KIA OPTIMA 2016"
KIA_OPTIMA_2019 = "KIA OPTIMA 2019"
KIA_OPTIMA_H = "KIA OPTIMA HYBRID 2017 & SPORTS 2019"
KIA_SELTOS = "KIA SELTOS 2021"
KIA_SORENTO = "KIA SORENTO GT LINE 2018"
@ -102,27 +103,25 @@ class CAR:
@dataclass
class HyundaiCarInfo(CarInfo):
# TODO: we can probably remove LKAS. LKAS is standard on many
# HKG and for others, it's likely packaged together with SCC
package: str = "Smart Cruise Control (SCC) & LKAS"
package: str = "Smart Cruise Control (SCC)"
CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
CAR.ELANTRA: HyundaiCarInfo("Hyundai Elantra 2017-19", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_b),
CAR.ELANTRA_2021: HyundaiCarInfo("Hyundai Elantra 2021-22", video_link="https://youtu.be/_EdYQtV52-c", harness=Harness.hyundai_k),
CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021-22", "Smart Cruise Control (SCC)", video_link="https://youtu.be/_EdYQtV52-c", harness=Harness.hyundai_k),
CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021-22", video_link="https://youtu.be/_EdYQtV52-c", harness=Harness.hyundai_k),
CAR.ELANTRA_GT_I30: None, # dashcamOnly and same platform as CAR.ELANTRA
CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_j),
CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_j), # TODO: check 2015 packages
CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", harness=Harness.hyundai_c),
CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "Smart Cruise Control (SCC) & LFA", harness=Harness.hyundai_h),
CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "Smart Cruise Control (SCC)", harness=Harness.hyundai_h), # TODO: confirm 2020-21 harness
CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019", harness=Harness.hyundai_c),
CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020", harness=Harness.hyundai_h),
CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020", "All", harness=Harness.hyundai_h),
CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", harness=Harness.hyundai_c),
CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21", "Smart Cruise Control (SCC)", harness=Harness.hyundai_h),
CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", "Smart Cruise Control (SCC)", harness=Harness.hyundai_b),
CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21", "All", harness=Harness.hyundai_h),
CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", harness=Harness.hyundai_b),
CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21", harness=Harness.hyundai_g),
CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022", "Smart Cruise Control (SCC)", harness=Harness.hyundai_o),
CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", harness=Harness.hyundai_i),
CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022", harness=Harness.hyundai_o),
CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", harness=Harness.hyundai_i), # TODO: check packages
CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", harness=Harness.hyundai_d),
CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", video_link="https://youtu.be/VnHzSTygTS4", harness=Harness.hyundai_l),
CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All", harness=Harness.hyundai_l),
@ -130,43 +129,41 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", harness=Harness.hyundai_a),
CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19", harness=Harness.hyundai_e),
CAR.TUCSON: [
HyundaiCarInfo("Hyundai Tucson 2021", "Smart Cruise Control (SCC)", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_l),
HyundaiCarInfo("Hyundai Tucson Diesel 2019", "Smart Cruise Control (SCC)", harness=Harness.hyundai_l),
HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_l),
HyundaiCarInfo("Hyundai Tucson Diesel 2019", harness=Harness.hyundai_l),
],
CAR.PALISADE: [
HyundaiCarInfo("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Telluride 2020", "All", harness=Harness.hyundai_h),
],
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", 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.IONIQ_5: HyundaiCarInfo("Hyundai Ioniq 5 2022", "Highway Driving Assist II", harness=Harness.hyundai_q),
CAR.TUCSON_HYBRID_4TH_GEN: HyundaiCarInfo("Hyundai Tucson Hybrid 2022", "All", harness=Harness.hyundai_n),
# Kia
CAR.KIA_FORTE: [
HyundaiCarInfo("Kia Forte 2018", harness=Harness.hyundai_b),
HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g),
],
CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", "Smart Cruise Control (SCC)", harness=Harness.hyundai_a),
CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g),
CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", harness=Harness.hyundai_a),
CAR.KIA_NIRO_EV: [
HyundaiCarInfo("Kia Niro Electric 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro Electric 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_f),
HyundaiCarInfo("Kia Niro Electric 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Niro Electric 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_f),
HyundaiCarInfo("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
],
CAR.KIA_NIRO_PHEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c),
CAR.KIA_NIRO_PHEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c),
CAR.KIA_NIRO_HEV_2021: [
HyundaiCarInfo("Kia Niro Hybrid 2021", harness=Harness.hyundai_f), # TODO: could be hyundai_d, verify
HyundaiCarInfo("Kia Niro Hybrid 2022", harness=Harness.hyundai_h),
],
CAR.KIA_OPTIMA: [
HyundaiCarInfo("Kia Optima 2017", min_steer_speed=32. * CV.MPH_TO_MS, harness=Harness.hyundai_b),
HyundaiCarInfo("Kia Optima 2019", harness=Harness.hyundai_g),
CAR.KIA_OPTIMA: HyundaiCarInfo("Kia Optima 2017", "Advanced Smart Cruise Control", harness=Harness.hyundai_b), # TODO: may support 2016, 2018
CAR.KIA_OPTIMA_2019: HyundaiCarInfo("Kia Optima 2019-20", harness=Harness.hyundai_g),
CAR.KIA_OPTIMA_H: [
HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control"), # TODO: may support adjacent years
HyundaiCarInfo("Kia Optima Hybrid 2019"),
],
CAR.KIA_OPTIMA_H: HyundaiCarInfo("Kia Optima Hybrid 2017, 2019"), # TODO: info may be incorrect
CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", "Smart Cruise Control (SCC)", harness=Harness.hyundai_a),
CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", harness=Harness.hyundai_a),
CAR.KIA_SORENTO: [
HyundaiCarInfo("Kia Sorento 2018", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_e),
],
CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c),
@ -230,9 +227,6 @@ FINGERPRINTS = {
CAR.SONATA_LF: [
{66: 8, 67: 8, 68: 8, 127: 8, 273: 8, 274: 8, 275: 8, 339: 8, 356: 4, 399: 8, 447: 8, 512: 6, 544: 8, 593: 8, 608: 8, 688: 5, 790: 8, 809: 8, 832: 8, 884: 8, 897: 8, 899: 8, 902: 8, 903: 6, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1253: 8, 1254: 8, 1255: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1314: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1363: 8, 1365: 8, 1366: 8, 1367: 8, 1369: 8, 1397: 8, 1407: 8, 1415: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1472: 8, 1486: 8, 1487: 8, 1491: 8, 1530: 8, 1532: 5, 2000: 8, 2001: 8, 2004: 8, 2005: 8, 2008: 8, 2009: 8, 2012: 8, 2013: 8, 2014: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8},
],
CAR.KIA_OPTIMA: [{
64: 8, 66: 8, 67: 8, 68: 8, 127: 8, 128: 8, 129: 8, 273: 8, 274: 8, 275: 8, 339: 8, 354: 3, 356: 4, 399: 8, 447: 8, 512: 6, 544: 8, 558: 8, 593: 8, 608: 8, 640: 8, 688: 5, 790: 8, 809: 8, 832: 8, 884: 8, 897: 8, 899: 8, 902: 8, 903: 6, 909: 8, 912: 7, 916: 8, 1040: 8, 1056: 8, 1057: 8, 1078: 4, 1151: 6, 1168: 7, 1170: 8, 1186: 2, 1191: 2, 1253: 8, 1254: 8, 1255: 8, 1265: 4, 1268: 8, 1280: 1, 1282: 4, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1349: 8, 1351: 8, 1353: 8, 1356: 8, 1363: 8, 1365: 8, 1366: 8, 1367: 8, 1369: 8, 1407: 8, 1414: 3, 1415: 8, 1419: 8, 1425: 2, 1427: 6, 1440: 8, 1456: 4, 1470: 8, 1472: 8, 1486: 8, 1487: 8, 1491: 8, 1492: 8, 1530: 8, 1532: 5, 1792: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 1988: 8, 1996: 8, 2000: 8, 2001: 8, 2004: 8, 2008: 8, 2009: 8, 2012: 8, 2015: 8, 2016: 8, 2017: 8, 2024: 8, 2025: 8, 1371: 8, 1397: 8, 1961: 8
}],
CAR.KIA_SORENTO: [{
67: 8, 68: 8, 127: 8, 304: 8, 320: 8, 339: 8, 356: 4, 544: 8, 593: 8, 608: 8, 688: 5, 809: 8, 832: 8, 854: 7, 870: 7, 871: 8, 872: 8, 897: 8, 902: 8, 903: 8, 916: 8, 1040: 8, 1042: 8, 1056: 8, 1057: 8, 1064: 8, 1078: 4, 1107: 5, 1136: 8, 1151: 6, 1168: 7, 1170: 8, 1173: 8, 1265: 4, 1280: 1, 1287: 4, 1290: 8, 1292: 8, 1294: 8, 1312: 8, 1322: 8, 1331: 8, 1332: 8, 1333: 8, 1342: 6, 1345: 8, 1348: 8, 1363: 8, 1369: 8, 1370: 8, 1371: 8, 1384: 8, 1407: 8, 1411: 8, 1419: 8, 1425: 2, 1427: 6, 1444: 8, 1456: 4, 1470: 8, 1489: 1
}],
@ -1144,25 +1138,40 @@ FW_VERSIONS = {
},
CAR.KIA_OPTIMA: {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00JF__ SCC F-CUP 1.00 1.00 96400-D4110 ',
b'\xf1\x00JF__ SCC F-CUP 1.00 1.00 96400-D4100 ',
],
(Ecu.abs, 0x7d1, None): [
b'\xf1\x00JF ESC \x0b 11 \x18\x030 58920-D5180',
b'\xf1\x00JF ESC \x0f 16 \x16\x06\x17 58920-D5080',
],
(Ecu.engine, 0x7e0, None): [
b'\xf1\x89F1JF600AISEIU702\xf1\x82F1JF600AISEIU702',
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00JFWGN LDWS AT USA LHD 1.00 1.02 95895-D4100 G21',
],
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00TM MDPS C 1.00 1.00 56340-S2000 8409',
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x816T6J0051\x00\x00\xf1\x006T6J0_C2\x00\x006T6J0051\x00\x00TJF0T20NSB\x00\x00\x00\x00',
],
},
CAR.KIA_OPTIMA_2019: {
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00JF__ SCC F-CUP 1.00 1.00 96400-D4110 ',
],
(Ecu.abs, 0x7d1, None): [
b'\xf1\x00JF ESC \x0b 11 \x18\x030 58920-D5180',
b"\xf1\x00JF ESC \t 11 \x18\x03' 58920-D5260",
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00JFA LKAS AT USA LHD 1.00 1.00 95895-D5001 h32',
b'\xf1\x00JFA LKAS AT USA LHD 1.00 1.02 95895-D5000 h31',
b'\xf1\x00JFA LKAS AT USA LHD 1.00 1.00 95895-D5100 h32',
],
(Ecu.transmission, 0x7e1, None): [
b'\xf1\x006U2V0_C2\x00\x006U2V8051\x00\x00DJF0T16NL0\t\xd2GW',
b'\xf1\x006U2V0_C2\x00\x006U2VA051\x00\x00DJF0T16NL1\xca3\xeb.',
b'\xf1\x006U2V0_C2\x00\x006U2VC051\x00\x00DJF0T16NL2\x9eA\x80\x01',
b'\xf1\x006U2V0_C2\x00\x006U2VA051\x00\x00DJF0T16NL1\x00\x00\x00\x00',
b'\xf1\x816U2V8051\x00\x00\xf1\x006U2V0_C2\x00\x006U2V8051\x00\x00DJF0T16NL0\t\xd2GW',
b'\xf1\x816U2VA051\x00\x00\xf1\x006U2V0_C2\x00\x006U2VA051\x00\x00DJF0T16NL1\xca3\xeb.',
b'\xf1\x816U2VC051\x00\x00\xf1\x006U2V0_C2\x00\x006U2VC051\x00\x00DJF0T16NL2\x9eA\x80\x01',
b'\xf1\x816U2VA051\x00\x00\xf1\x006U2V0_C2\x00\x006U2VA051\x00\x00DJF0T16NL1\x00\x00\x00\x00',
b'\xf1\x87\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf1\x816T6B8051\x00\x00\xf1\x006T6H0_C2\x00\x006T6B8051\x00\x00TJFSG24NH27\xa7\xc2\xb4',
],
},
CAR.ELANTRA_2021: {
@ -1200,7 +1209,7 @@ FW_VERSIONS = {
],
(Ecu.engine, 0x7e0, None): [
b'\xf1\x82CNCWD0AMFCXCSFFA',
b'\xf1\x82CNCWD0AMFCXCSFFB',
b'\xf1\x81HM6M2_0a0_FF0',
b'\xf1\x82CNCVD0AMFCXCSFFB',
b'\xf1\x870\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x81HM6M2_0a0_G80',
],
@ -1358,7 +1367,7 @@ CHECKSUM = {
FEATURES = {
# which message has the gear
"use_cluster_gears": {CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.KONA},
"use_tcu_gears": {CAR.KIA_OPTIMA, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON},
"use_tcu_gears": {CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_2019, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON},
"use_elect_gears": {CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.KIA_OPTIMA_H, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.IONIQ, CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.KONA_EV_2022},
# these cars use the FCA11 message for the AEB and FCW signals, all others use SCC12
@ -1374,7 +1383,7 @@ HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_N
EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KONA_EV_2022}
# these cars require a special panda safety mode due to missing counters and checksums in the messages
LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022}
LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.IONIQ_PHEV, CAR.IONIQ, CAR.KONA_EV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA, CAR.KIA_OPTIMA_2019, CAR.VELOSTER, CAR.KIA_STINGER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022}
# If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points.
# If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py
@ -1384,22 +1393,23 @@ DBC = {
CAR.ELANTRA_HEV_2021: dbc_dict('hyundai_kia_generic', None),
CAR.ELANTRA_GT_I30: dbc_dict('hyundai_kia_generic', None),
CAR.GENESIS_G70: dbc_dict('hyundai_kia_generic', None),
CAR.GENESIS_G70_2020: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.GENESIS_G70_2020: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.GENESIS_G80: dbc_dict('hyundai_kia_generic', None),
CAR.GENESIS_G90: dbc_dict('hyundai_kia_generic', None),
CAR.HYUNDAI_GENESIS: dbc_dict('hyundai_kia_generic', None),
CAR.IONIQ_PHEV_2019: dbc_dict('hyundai_kia_generic', None),
CAR.IONIQ_PHEV: dbc_dict('hyundai_kia_generic', None),
CAR.IONIQ_EV_2020: dbc_dict('hyundai_kia_generic', None),
CAR.IONIQ_EV_LTD: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.IONIQ_EV_LTD: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.IONIQ: dbc_dict('hyundai_kia_generic', None),
CAR.IONIQ_HEV_2022: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_FORTE: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_K5_2021: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_NIRO_EV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.KIA_NIRO_PHEV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.KIA_NIRO_EV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.KIA_NIRO_PHEV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.KIA_NIRO_HEV_2021: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_OPTIMA: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_OPTIMA_2019: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_OPTIMA_H: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_SELTOS: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_SORENTO: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format
@ -1408,18 +1418,18 @@ DBC = {
CAR.KONA_EV: dbc_dict('hyundai_kia_generic', None),
CAR.KONA_EV_2022: dbc_dict('hyundai_kia_generic', None),
CAR.KONA_HEV: dbc_dict('hyundai_kia_generic', None),
CAR.SANTA_FE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.SANTA_FE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.SANTA_FE_2022: dbc_dict('hyundai_kia_generic', None),
CAR.SANTA_FE_HEV_2022: dbc_dict('hyundai_kia_generic', None),
CAR.SANTA_FE_PHEV_2022: dbc_dict('hyundai_kia_generic', None),
CAR.SONATA: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.SONATA: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.SONATA_LF: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format
CAR.TUCSON: dbc_dict('hyundai_kia_generic', None),
CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar'),
CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
CAR.VELOSTER: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None),
CAR.KIA_EV6: dbc_dict('hyundai_canfd', 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_generated'),
CAR.TUCSON_HYBRID_4TH_GEN: dbc_dict('hyundai_canfd', None),
CAR.IONIQ_5: dbc_dict('hyundai_canfd', None),
}

@ -2,25 +2,28 @@ import yaml
import os
import time
from abc import abstractmethod, ABC
from typing import Any, Dict, Optional, Tuple, List
from typing import Any, Dict, Optional, Tuple, List, Callable
from cereal import car
from common.basedir import BASEDIR
from common.conversions import Conversions as CV
from common.kalman.simple_kalman import KF1D
from common.numpy_fast import interp
from common.realtime import DT_CTRL
from selfdrive.car import apply_hysteresis, create_button_enable_events, gen_empty_fingerprint
from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX
from selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, apply_deadzone
from selfdrive.controls.lib.events import Events
from selfdrive.controls.lib.vehicle_model import VehicleModel
ButtonType = car.CarState.ButtonEvent.Type
GearShifter = car.CarState.GearShifter
EventName = car.CarEvent.EventName
TorqueFromLateralAccelCallbackType = Callable[[float, car.CarParams.LateralTorqueTuning, float, float, bool], float]
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
ACCEL_MAX = 2.0
ACCEL_MIN = -3.5
FRICTION_THRESHOLD = 0.2
TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.yaml')
TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.yaml')
@ -102,6 +105,20 @@ class CarInterfaceBase(ABC):
def get_steer_feedforward_function(self):
return self.get_steer_feedforward_default
@staticmethod
def torque_from_lateral_accel_linear(lateral_accel_value, torque_params, lateral_accel_error, lateral_accel_deadzone, friction_compensation):
# The default is a linear relationship between torque and lateral acceleration (accounting for road roll and steering friction)
friction_interp = interp(
apply_deadzone(lateral_accel_error, lateral_accel_deadzone),
[-FRICTION_THRESHOLD, FRICTION_THRESHOLD],
[-torque_params.friction, torque_params.friction]
)
friction = friction_interp if friction_compensation else 0.0
return (lateral_accel_value / torque_params.latAccelFactor) + friction
def torque_from_lateral_accel(self) -> TorqueFromLateralAccelCallbackType:
return self.torque_from_lateral_accel_linear
# returns a set of default params to avoid repetition in car specific params
@staticmethod
def get_std_params(candidate, fingerprint):
@ -145,10 +162,12 @@ class CarInterfaceBase(ABC):
tune.init('torque')
tune.torque.useSteeringAngle = use_steering_angle
tune.torque.kp = 1.0 / params['LAT_ACCEL_FACTOR']
tune.torque.kf = 1.0 / params['LAT_ACCEL_FACTOR']
tune.torque.ki = 0.1 / params['LAT_ACCEL_FACTOR']
tune.torque.kp = 1.0
tune.torque.kf = 1.0
tune.torque.ki = 0.1
tune.torque.friction = params['FRICTION']
tune.torque.latAccelFactor = params['LAT_ACCEL_FACTOR']
tune.torque.latAccelOffset = 0.0
tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg
@abstractmethod

@ -109,7 +109,7 @@ class IsoTpParallelQuery:
try:
dat: Optional[bytes] = msg.recv()
except Exception:
cloudlog.exception("Error processing UDS response")
cloudlog.exception(f"Error processing UDS response: {tx_addr}")
request_done[tx_addr] = True
continue

@ -10,10 +10,6 @@ EventName = car.CarEvent.EventName
class CarInterface(CarInterfaceBase):
@staticmethod
def compute_gb(accel, speed):
return float(accel) / 4.0
@staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, experimental_long=False):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)

@ -28,10 +28,6 @@ class CarInterface(CarInterfaceBase):
self.yaw_rate = 0.
self.yaw_rate_meas = 0.
@staticmethod
def compute_gb(accel, speed):
return accel
@staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), car_fw=None, experimental_long=False):
ret = CarInterfaceBase.get_std_params(candidate, fingerprint)

@ -1,9 +1,12 @@
from collections import namedtuple
from typing import Dict, List, Union
from cereal import car
from selfdrive.car import dbc_dict
from selfdrive.car.docs_definitions import CarInfo
from cereal import car
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
Ecu = car.CarParams.Ecu
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_points', 'max_angle_diff_points'])
@ -20,11 +23,6 @@ CAR_INFO: Dict[str, Union[CarInfo, List[CarInfo]]] = {
}
FINGERPRINTS = {
CAR.AP2_MODELS: [
{
1: 8, 3: 8, 14: 8, 21: 4, 69: 8, 109: 4, 257: 3, 264: 8, 277: 6, 280: 6, 293: 4, 296: 4, 309: 5, 325: 8, 328: 5, 336: 8, 341: 8, 360: 7, 373: 8, 389: 8, 415: 8, 513: 5, 516: 8, 518: 8, 520: 4, 522: 8, 524: 8, 526: 8, 532: 3, 536: 8, 537: 3, 538: 8, 542: 8, 551: 5, 552: 2, 556: 8, 558: 8, 568: 8, 569: 8, 574: 8, 576: 3, 577: 8, 582: 5, 583: 8, 584: 4, 585: 8, 590: 8, 601: 8, 606: 8, 608: 1, 622: 8, 627: 6, 638: 8, 641: 8, 643: 8, 692: 8, 693: 8, 695: 8, 696: 8, 697: 8, 699: 8, 700: 8, 701: 8, 702: 8, 703: 8, 704: 8, 708: 8, 709: 8, 710: 8, 711: 8, 712: 8, 728: 8, 744: 8, 760: 8, 772: 8, 775: 8, 776: 8, 777: 8, 778: 8, 782: 8, 788: 8, 791: 8, 792: 8, 796: 2, 797: 8, 798: 6, 799: 8, 804: 8, 805: 8, 807: 8, 808: 1, 811: 8, 812: 8, 813: 8, 814: 5, 815: 8, 820: 8, 823: 8, 824: 8, 829: 8, 830: 5, 836: 8, 840: 8, 845: 8, 846: 5, 848: 8, 852: 8, 853: 8, 856: 4, 857: 6, 861: 8, 862: 5, 872: 8, 876: 8, 877: 8, 879: 8, 880: 8, 882: 8, 884: 8, 888: 8, 893: 8, 894: 8, 901: 6, 904: 3, 905: 8, 906: 8, 908: 2, 909: 8, 910: 8, 912: 8, 920: 8, 921: 8, 925: 4, 926: 6, 936: 8, 941: 8, 949: 8, 952: 8, 953: 6, 968: 8, 969: 7, 970: 8, 971: 8, 977: 8, 984: 8, 986: 8, 987: 8, 990: 8, 1000: 8, 1001: 8, 1006: 8, 1007: 8, 1008: 8, 1010: 6, 1014: 1, 1015: 8, 1016: 8, 1017: 8, 1018: 8, 1020: 8, 1026: 8, 1028: 8, 1029: 8, 1030: 8, 1032: 1, 1033: 1, 1034: 8, 1048: 1, 1049: 8, 1061: 8, 1064: 8, 1065: 8, 1070: 8, 1080: 8, 1081: 8, 1097: 8, 1113: 8, 1129: 8, 1145: 8, 1160: 4, 1177: 8, 1281: 8, 1328: 8, 1329: 8, 1332: 8, 1335: 8, 1337: 8, 1353: 8, 1368: 8, 1412: 8, 1436: 8, 1476: 8, 1481: 8, 1497: 8, 1513: 8, 1519: 8, 1601: 8, 1605: 8, 1617: 8, 1621: 8, 1625: 8, 1665: 8, 1792: 8, 1798: 8, 1800: 4, 1804: 8, 1812: 8, 1815: 8, 1816: 8, 1824: 8, 1825: 8, 1828: 8, 1831: 8, 1832: 8, 1840: 8, 1842: 8, 1848: 8, 1864: 8, 1872: 8, 1880: 8, 1888: 8, 1892: 8, 1896: 8, 1912: 8, 1937: 8, 1953: 8, 1960: 8, 1968: 8, 1992: 8, 2001: 8, 2008: 3, 2015: 8, 2016: 8, 2043: 5, 2045: 4
},
],
CAR.AP1_MODELS: [
{
1: 8, 3: 8, 14: 8, 21: 4, 69: 8, 109: 4, 257: 3, 264: 8, 267: 5, 277: 6, 280: 6, 283: 5, 293: 4, 296: 4, 309: 5, 325: 8, 328: 5, 336: 8, 341: 8, 360: 7, 373: 8, 389: 8, 415: 8, 513: 5, 516: 8, 520: 4, 522: 8, 524: 8, 526: 8, 532: 3, 536: 8, 537: 3, 542: 8, 551: 5, 552: 2, 556: 8, 558: 8, 568: 8, 569: 8, 574: 8, 577: 8, 582: 5, 584: 4, 585: 8, 590: 8, 606: 8, 622: 8, 627: 6, 638: 8, 641: 8, 643: 8, 660: 5, 693: 8, 696: 8, 697: 8, 712: 8, 728: 8, 744: 8, 760: 8, 772: 8, 775: 8, 776: 8, 777: 8, 778: 8, 782: 8, 788: 8, 791: 8, 792: 8, 796: 2, 797: 8, 798: 6, 799: 8, 804: 8, 805: 8, 807: 8, 808: 1, 809: 8, 812: 8, 813: 8, 814: 5, 815: 8, 820: 8, 823: 8, 824: 8, 829: 8, 830: 5, 836: 8, 840: 8, 841: 8, 845: 8, 846: 5, 852: 8, 856: 4, 857: 6, 861: 8, 862: 5, 872: 8, 873: 8, 877: 8, 878: 8, 879: 8, 880: 8, 884: 8, 888: 8, 889: 8, 893: 8, 896: 8, 901: 6, 904: 3, 905: 8, 908: 2, 909: 8, 920: 8, 921: 8, 925: 4, 936: 8, 937: 8, 941: 8, 949: 8, 952: 8, 953: 6, 957: 8, 968: 8, 973: 8, 984: 8, 987: 8, 989: 8, 990: 8, 1000: 8, 1001: 8, 1006: 8, 1016: 8, 1026: 8, 1028: 8, 1029: 8, 1030: 8, 1032: 1, 1033: 1, 1034: 8, 1048: 1, 1064: 8, 1070: 8, 1080: 8, 1160: 4, 1281: 8, 1329: 8, 1332: 8, 1335: 8, 1337: 8, 1368: 8, 1412: 8, 1436: 8, 1465: 8, 1476: 8, 1497: 8, 1524: 8, 1527: 8, 1601: 8, 1605: 8, 1611: 8, 1614: 8, 1617: 8, 1621: 8, 1627: 8, 1630: 8, 1800: 4, 1804: 8, 1812: 8, 1815: 8, 1816: 8, 1828: 8, 1831: 8, 1832: 8, 1840: 8, 1848: 8, 1864: 8, 1880: 8, 1892: 8, 1896: 8, 1912: 8, 1960: 8, 1992: 8, 2008: 3, 2043: 5, 2045: 4
@ -37,6 +35,42 @@ DBC = {
CAR.AP1_MODELS: dbc_dict('tesla_powertrain', 'tesla_radar', chassis_dbc='tesla_can'),
}
FW_QUERY_CONFIG = FwQueryConfig(
requests=[
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.UDS_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.UDS_VERSION_RESPONSE],
whitelist_ecus=[Ecu.eps],
rx_offset=0x08,
bus=0,
),
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.UDS_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.UDS_VERSION_RESPONSE],
whitelist_ecus=[Ecu.adas, Ecu.electricBrakeBooster, Ecu.fwdRadar],
rx_offset=0x10,
bus=0,
),
]
)
FW_VERSIONS = {
CAR.AP2_MODELS: {
(Ecu.adas, 0x649, None): [
b'\x01\x00\x8b\x07\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11',
],
(Ecu.electricBrakeBooster, 0x64d, None): [
b'1037123-00-A',
],
(Ecu.fwdRadar, 0x671, None): [
b'\x01\x00W\x00\x00\x00\x07\x00\x00\x00\x00\x08\x01\x00\x00\x00\x07\xff\xfe',
],
(Ecu.eps, 0x730, None): [
b'\x10#\x01',
],
},
}
class CANBUS:
# Lateral harness
chassis = 0

@ -21,6 +21,8 @@ non_tested_cars = [
GM.CADILLAC_ATS,
GM.HOLDEN_ASTRA,
GM.MALIBU,
GM.EQUINOX,
GM.BOLT_EV,
HYUNDAI.ELANTRA_GT_I30,
HYUNDAI.GENESIS_G90,
HYUNDAI.KIA_OPTIMA_H,
@ -87,6 +89,7 @@ routes = [
CarTestRoute("656ac0d830792fcc|2021-12-28--14-45-56", HYUNDAI.SANTA_FE_PHEV_2022, segment=1),
CarTestRoute("e0e98335f3ebc58f|2021-03-07--16-38-29", HYUNDAI.KIA_CEED),
CarTestRoute("7653b2bce7bcfdaa|2020-03-04--15-34-32", HYUNDAI.KIA_OPTIMA),
CarTestRoute("018654717bc93d7d|2022-09-19--23-11-10", HYUNDAI.KIA_OPTIMA_2019, segment=0),
CarTestRoute("c75a59efa0ecd502|2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS),
CarTestRoute("5b7c365c50084530|2020-04-15--16-13-24", HYUNDAI.SONATA),
CarTestRoute("b2a38c712dcf90bd|2020-05-18--18-12-48", HYUNDAI.SONATA_LF),

@ -34,9 +34,10 @@ class TestCarDocs(unittest.TestCase):
if car.car_name == "hyundai":
self.assertNotIn("phev", tokens, "Use `Plug-in Hybrid`")
self.assertNotIn("hev", tokens, "Use `Hybrid`")
self.assertNotIn("ev", tokens, "Use `Electric`")
if "plug-in hybrid" in car.model.lower():
self.assertIn("Plug-in Hybrid", car.model, "Use correct capitalization")
if car.make != "Kia":
self.assertNotIn("ev", tokens, "Use `Electric`")
elif car.car_name == "toyota":
if "rav4" in tokens:
self.assertIn("RAV4", car.model, "Use correct capitalization")

@ -25,8 +25,10 @@ KIA EV6 2022: [3.5, 3.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]
CHEVROLET BOLT EV 2022: [2.0, 2.0, 0.05]
CHEVROLET BOLT EUV 2022: [2.0, 2.0, 0.05]
CHEVROLET SILVERADO 1500 2020: [1.9, 1.9, 0.112]
CHEVROLET EQUINOX 2019: [2.0, 2.0, 0.05]
VOLKSWAGEN PASSAT NMS: [2.5, 2.5, 0.1]
HYUNDAI TUCSON HYBRID 4TH GEN: [2.5, 2.5, 0.0]

@ -17,7 +17,8 @@ LEXUS RC 2020: LEXUS NX 2020
TOYOTA AVALON HYBRID 2019: TOYOTA AVALON 2019
TOYOTA AVALON HYBRID 2022: TOYOTA AVALON 2022
KIA OPTIMA SX 2019 & 2016: HYUNDAI SONATA 2020
KIA OPTIMA 2016: HYUNDAI SONATA 2020
KIA OPTIMA 2019: HYUNDAI SONATA 2020
KIA OPTIMA HYBRID 2017 & SPORTS 2019: HYUNDAI SONATA 2020
KIA FORTE E 2018 & GT 2021: HYUNDAI SONATA 2020
KIA CEED INTRO ED 2019: HYUNDAI SONATA 2020

@ -81,7 +81,7 @@ class CarController:
pcm_cancel_cmd = 1
# on entering standstill, send standstill request
if CS.out.standstill and not self.last_standstill and self.CP.carFingerprint not in NO_STOP_TIMER_CAR:
if CS.out.standstill and not self.last_standstill and (self.CP.carFingerprint not in NO_STOP_TIMER_CAR or self.CP.enableGasInterceptor):
self.standstill_req = True
if CS.pcm_acc_status != 8:
# pcm entered standstill or it's disabled

@ -817,6 +817,7 @@ FW_VERSIONS = {
b'\x01896637626000\x00\x00\x00\x00',
b'\x01896637648000\x00\x00\x00\x00',
b'\x01896637643000\x00\x00\x00\x00',
b'\x02896630A07000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00',
b'\x02896630A21000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00',
b'\x02896630ZJ5000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00',
b'\x02896630ZN8000\x00\x00\x00\x008966A4703000\x00\x00\x00\x00',

@ -301,6 +301,7 @@ FW_VERSIONS = {
(Ecu.engine, 0x7e0, None): [
b'\xf1\x8703H906026AA\xf1\x899970',
b'\xf1\x8703H906026AJ\xf1\x890638',
b'\xf1\x8703H906026AJ\xf1\x891017',
b'\xf1\x8703H906026AT\xf1\x891922',
b'\xf1\x8703H906026BC\xf1\x892664',
b'\xf1\x8703H906026F \xf1\x896696',

@ -104,7 +104,7 @@ class Controls:
ignore += ['roadCameraState']
self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration',
'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman',
'managerState', 'liveParameters', 'radarState'] + self.camera_packets + joystick_packet,
'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters'] + self.camera_packets + joystick_packet,
ignore_alive=ignore, ignore_avg_freq=['radarState', 'longitudinalPlan'])
# set alternative experiences from parameters
@ -233,6 +233,10 @@ class Controls:
self.events.add(EventName.controlsInitializing)
return
# no more events while in dashcam mode
if self.read_only:
return
# Block resume if cruise never previously enabled
resume_pressed = any(be.type in (ButtonType.accelCruise, ButtonType.resumeCruise) for be in CS.buttonEvents)
if not self.CP.pcmCruise and self.v_cruise_kph == V_CRUISE_INITIAL and resume_pressed:
@ -578,6 +582,12 @@ class Controls:
sr = max(params.steerRatio, 0.1)
self.VM.update_params(x, sr)
# Update Torque Params
if self.CP.lateralTuning.which() == 'torque':
torque_params = self.sm['liveTorqueParameters']
if self.sm.all_checks(['liveTorqueParameters']) and torque_params.useParams:
self.LaC.update_live_torque_params(torque_params.latAccelFactorFiltered, torque_params.latAccelOffsetFiltered, torque_params.frictionCoefficientFiltered)
lat_plan = self.sm['lateralPlan']
long_plan = self.sm['longitudinalPlan']

@ -4,7 +4,6 @@ from cereal import log
from common.numpy_fast import interp
from selfdrive.controls.lib.latcontrol import LatControl, MIN_STEER_SPEED
from selfdrive.controls.lib.pid import PIDController
from selfdrive.controls.lib.drive_helpers import apply_deadzone
from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
# At higher speeds (25+mph) we can assume:
@ -19,19 +18,20 @@ from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
# move it at all, this is compensated for too.
FRICTION_THRESHOLD = 0.2
class LatControlTorque(LatControl):
def __init__(self, CP, CI):
super().__init__(CP, CI)
self.pid = PIDController(CP.lateralTuning.torque.kp, CP.lateralTuning.torque.ki,
k_f=CP.lateralTuning.torque.kf, pos_limit=self.steer_max, neg_limit=-self.steer_max)
self.get_steer_feedforward = CI.get_steer_feedforward_function()
self.use_steering_angle = CP.lateralTuning.torque.useSteeringAngle
self.friction = CP.lateralTuning.torque.friction
self.kf = CP.lateralTuning.torque.kf
self.steering_angle_deadzone_deg = CP.lateralTuning.torque.steeringAngleDeadzoneDeg
self.torque_params = CP.lateralTuning.torque
self.pid = PIDController(self.torque_params.kp, self.torque_params.ki,
k_f=self.torque_params.kf, pos_limit=self.steer_max, neg_limit=-self.steer_max)
self.torque_from_lateral_accel = CI.torque_from_lateral_accel()
self.use_steering_angle = self.torque_params.useSteeringAngle
self.steering_angle_deadzone_deg = self.torque_params.steeringAngleDeadzoneDeg
def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction):
self.torque_params.latAccelFactor = latAccelFactor
self.torque_params.latAccelOffset = latAccelOffset
self.torque_params.friction = friction
def update(self, active, CS, VM, params, last_actuators, steer_limited, desired_curvature, desired_curvature_rate, llk):
pid_log = log.ControlsState.LateralTorqueState.new_message()
@ -55,19 +55,16 @@ class LatControlTorque(LatControl):
actual_lateral_accel = actual_curvature * CS.vEgo ** 2
lateral_accel_deadzone = curvature_deadzone * CS.vEgo ** 2
low_speed_factor = interp(CS.vEgo, [0, 10, 20], [500, 500, 200])
setpoint = desired_lateral_accel + low_speed_factor * desired_curvature
measurement = actual_lateral_accel + low_speed_factor * actual_curvature
error = setpoint - measurement
pid_log.error = error
gravity_adjusted_lateral_accel = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY
pid_log.error = self.torque_from_lateral_accel(error, self.torque_params, error, lateral_accel_deadzone, friction_compensation=False)
ff = self.torque_from_lateral_accel(gravity_adjusted_lateral_accel, self.torque_params, error, lateral_accel_deadzone, friction_compensation=True)
ff = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY
# convert friction into lateral accel units for feedforward
friction_compensation = interp(apply_deadzone(error, lateral_accel_deadzone), [-FRICTION_THRESHOLD, FRICTION_THRESHOLD], [-self.friction, self.friction])
ff += friction_compensation / self.kf
freeze_integrator = steer_limited or CS.steeringPressed or CS.vEgo < 5
output_torque = self.pid.update(error,
output_torque = self.pid.update(pid_log.error,
feedforward=ff,
speed=CS.vEgo,
freeze_integrator=freeze_integrator)
@ -78,9 +75,9 @@ class LatControlTorque(LatControl):
pid_log.d = self.pid.d
pid_log.f = self.pid.f
pid_log.output = -output_torque
pid_log.saturated = self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited)
pid_log.actualLateralAccel = actual_lateral_accel
pid_log.desiredLateralAccel = desired_lateral_accel
pid_log.saturated = self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited)
# TODO left is positive in this convention
return -output_torque, 0.0, pid_log

@ -0,0 +1,290 @@
#!/usr/bin/env python3
import os
import sys
import signal
import numpy as np
from collections import deque, defaultdict
import cereal.messaging as messaging
from cereal import car, log
from common.params import Params
from common.realtime import config_realtime_process, DT_MDL
from common.filter_simple import FirstOrderFilter
from system.swaglog import cloudlog
from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from selfdrive.car.toyota.values import CAR as TOYOTA
HISTORY = 5 # secs
POINTS_PER_BUCKET = 1500
MIN_POINTS_TOTAL = 4000
FIT_POINTS_TOTAL = 2000
MIN_VEL = 15 # m/s
FRICTION_FACTOR = 1.5 # ~85% of data coverage
FACTOR_SANITY = 0.3
FRICTION_SANITY = 0.5
STEER_MIN_THRESHOLD = 0.02
MIN_FILTER_DECAY = 50
MAX_FILTER_DECAY = 250
LAT_ACC_THRESHOLD = 1
STEER_BUCKET_BOUNDS = [(-0.5, -0.3), (-0.3, -0.2), (-0.2, -0.1), (-0.1, 0), (0, 0.1), (0.1, 0.2), (0.2, 0.3), (0.3, 0.5)]
MIN_BUCKET_POINTS = [100, 300, 500, 500, 500, 500, 300, 100]
MAX_RESETS = 5.0
MAX_INVALID_THRESHOLD = 10
MIN_ENGAGE_BUFFER = 2 # secs
VERSION = 1 # bump this to invalidate old parameter caches
ALLOWED_FINGERPRINTS = [TOYOTA.COROLLA_TSS2, TOYOTA.COROLLA, TOYOTA.COROLLAH_TSS2]
def slope2rot(slope):
sin = np.sqrt(slope**2 / (slope**2 + 1))
cos = np.sqrt(1 / (slope**2 + 1))
return np.array([[cos, -sin], [sin, cos]])
class npqueue:
def __init__(self, maxlen, rowsize):
self.maxlen = maxlen
self.arr = np.empty((0, rowsize))
def __len__(self):
return len(self.arr)
def append(self, pt):
if len(self.arr) < self.maxlen:
self.arr = np.append(self.arr, [pt], axis=0)
else:
self.arr[:-1] = self.arr[1:]
self.arr[-1] = pt
class PointBuckets:
def __init__(self, x_bounds, min_points):
self.x_bounds = x_bounds
self.buckets = {bounds: npqueue(maxlen=POINTS_PER_BUCKET, rowsize=3) for bounds in x_bounds}
self.buckets_min_points = {bounds: min_point for bounds, min_point in zip(x_bounds, min_points)}
def bucket_lengths(self):
return [len(v) for v in self.buckets.values()]
def __len__(self):
return sum(self.bucket_lengths())
def is_valid(self):
return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values())) and (self.__len__() >= MIN_POINTS_TOTAL)
def add_point(self, x, y):
for bound_min, bound_max in self.x_bounds:
if (x >= bound_min) and (x < bound_max):
self.buckets[(bound_min, bound_max)].append([x, 1.0, y])
break
def get_points(self, num_points=None):
points = np.concatenate([x.arr for x in self.buckets.values() if len(x) > 0])
if num_points is None:
return points
return points[np.random.choice(np.arange(len(points)), min(len(points), num_points), replace=False)]
def load_points(self, points):
for x, y in points:
self.add_point(x, y)
class TorqueEstimator:
def __init__(self, CP):
self.hist_len = int(HISTORY / DT_MDL)
self.lag = CP.steerActuatorDelay + .2 # from controlsd
self.offline_friction = 0.0
self.offline_latAccelFactor = 0.0
self.resets = 0.0
self.use_params = CP.carFingerprint in ALLOWED_FINGERPRINTS
if CP.lateralTuning.which() == 'torque':
self.offline_friction = CP.lateralTuning.torque.friction
self.offline_latAccelFactor = CP.lateralTuning.torque.latAccelFactor
self.reset()
initial_params = {
'latAccelFactor': self.offline_latAccelFactor,
'latAccelOffset': 0.0,
'frictionCoefficient': self.offline_friction,
'points': []
}
self.decay = MIN_FILTER_DECAY
self.min_lataccel_factor = (1.0 - FACTOR_SANITY) * self.offline_latAccelFactor
self.max_lataccel_factor = (1.0 + FACTOR_SANITY) * self.offline_latAccelFactor
self.min_friction = (1.0 - FRICTION_SANITY) * self.offline_friction
self.max_friction = (1.0 + FRICTION_SANITY) * self.offline_friction
# try to restore cached params
params = Params()
params_cache = params.get("LiveTorqueCarParams")
torque_cache = params.get("LiveTorqueParameters")
if params_cache is not None and torque_cache is not None:
try:
cache_ltp = log.Event.from_bytes(torque_cache).liveTorqueParameters
cache_CP = car.CarParams.from_bytes(params_cache)
if self.get_restore_key(cache_CP, cache_ltp.version) == self.get_restore_key(CP, VERSION):
initial_params = {
'latAccelFactor': cache_ltp.latAccelFactorFiltered,
'latAccelOffset': cache_ltp.latAccelOffsetFiltered,
'frictionCoefficient': cache_ltp.frictionCoefficientFiltered,
'points': cache_ltp.points
}
self.decay = cache_ltp.decay
self.filtered_points.load_points(initial_params['points'])
cloudlog.info("restored torque params from cache")
except Exception:
cloudlog.exception("failed to restore cached torque params")
params.remove("LiveTorqueCarParams")
params.remove("LiveTorqueParameters")
self.filtered_params = {}
for param in initial_params:
self.filtered_params[param] = FirstOrderFilter(initial_params[param], self.decay, DT_MDL)
def get_restore_key(self, CP, version):
a, b = None, None
if CP.lateralTuning.which() == 'torque':
a = CP.lateralTuning.torque.friction
b = CP.lateralTuning.torque.latAccelFactor
return (CP.carFingerprint, CP.lateralTuning.which(), a, b, version)
def reset(self):
self.resets += 1.0
self.invalid_values_tracker = 0.0
self.decay = MIN_FILTER_DECAY
self.raw_points = defaultdict(lambda: deque(maxlen=self.hist_len))
self.filtered_points = PointBuckets(x_bounds=STEER_BUCKET_BOUNDS, min_points=MIN_BUCKET_POINTS)
def estimate_params(self):
points = self.filtered_points.get_points(FIT_POINTS_TOTAL)
# total least square solution as both x and y are noisy observations
# this is empirically the slope of the hysteresis parallelogram as opposed to the line through the diagonals
try:
_, _, v = np.linalg.svd(points, full_matrices=False)
slope, offset = -v.T[0:2, 2] / v.T[2, 2]
_, spread = np.matmul(points[:, [0, 2]], slope2rot(slope)).T
friction_coeff = np.std(spread) * FRICTION_FACTOR
except np.linalg.LinAlgError as e:
cloudlog.exception(f"Error computing live torque params: {e}")
slope = offset = friction_coeff = np.nan
return slope, offset, friction_coeff
def update_params(self, params):
self.decay = min(self.decay + DT_MDL, MAX_FILTER_DECAY)
for param, value in params.items():
self.filtered_params[param].update(value)
self.filtered_params[param].update_alpha(self.decay)
def is_sane(self, latAccelFactor, latAccelOffset, friction):
if any([val is None or np.isnan(val) for val in [latAccelFactor, latAccelOffset, friction]]):
return False
return (self.max_friction >= friction >= self.min_friction) and\
(self.max_lataccel_factor >= latAccelFactor >= self.min_lataccel_factor)
def handle_log(self, t, which, msg):
if which == "carControl":
self.raw_points["carControl_t"].append(t + self.lag)
self.raw_points["steer_torque"].append(-msg.actuatorsOutput.steer)
self.raw_points["active"].append(msg.latActive)
elif which == "carState":
self.raw_points["carState_t"].append(t + self.lag)
self.raw_points["vego"].append(msg.vEgo)
self.raw_points["steer_override"].append(msg.steeringPressed)
elif which == "liveLocationKalman":
if len(self.raw_points['steer_torque']) == self.hist_len:
yaw_rate = msg.angularVelocityCalibrated.value[2]
roll = msg.orientationNED.value[0]
active = np.interp(np.arange(t - MIN_ENGAGE_BUFFER, t, DT_MDL), self.raw_points['carControl_t'], self.raw_points['active']).astype(bool)
steer_override = np.interp(np.arange(t - MIN_ENGAGE_BUFFER, t, DT_MDL), self.raw_points['carState_t'], self.raw_points['steer_override']).astype(bool)
vego = np.interp(t, self.raw_points['carState_t'], self.raw_points['vego'])
steer = np.interp(t, self.raw_points['carControl_t'], self.raw_points['steer_torque'])
lateral_acc = (vego * yaw_rate) - (np.sin(roll) * ACCELERATION_DUE_TO_GRAVITY)
if all(active) and (not any(steer_override)) and (vego > MIN_VEL) and (abs(steer) > STEER_MIN_THRESHOLD) and (abs(lateral_acc) <= LAT_ACC_THRESHOLD):
self.filtered_points.add_point(float(steer), float(lateral_acc))
def get_msg(self, valid=True, with_points=False):
msg = messaging.new_message('liveTorqueParameters')
msg.valid = valid
liveTorqueParameters = msg.liveTorqueParameters
liveTorqueParameters.version = VERSION
liveTorqueParameters.useParams = self.use_params
if self.filtered_points.is_valid():
latAccelFactor, latAccelOffset, friction_coeff = self.estimate_params()
liveTorqueParameters.latAccelFactorRaw = float(latAccelFactor)
liveTorqueParameters.latAccelOffsetRaw = float(latAccelOffset)
liveTorqueParameters.frictionCoefficientRaw = float(friction_coeff)
if self.is_sane(latAccelFactor, latAccelOffset, friction_coeff):
liveTorqueParameters.liveValid = True
self.update_params({'latAccelFactor': latAccelFactor, 'latAccelOffset': latAccelOffset, 'frictionCoefficient': friction_coeff})
self.invalid_values_tracker = max(0.0, self.invalid_values_tracker - 0.5)
else:
cloudlog.exception("live torque params are numerically unstable")
liveTorqueParameters.liveValid = False
self.invalid_values_tracker += 1.0
# Reset when ~10 invalid over 5 secs
if self.invalid_values_tracker > MAX_INVALID_THRESHOLD:
# Do not reset the filter as it may cause a drastic jump, just reset points
self.reset()
else:
liveTorqueParameters.liveValid = False
if with_points:
liveTorqueParameters.points = self.filtered_points.get_points()[:, [0, 2]].tolist()
liveTorqueParameters.latAccelFactorFiltered = float(self.filtered_params['latAccelFactor'].x)
liveTorqueParameters.latAccelOffsetFiltered = float(self.filtered_params['latAccelOffset'].x)
liveTorqueParameters.frictionCoefficientFiltered = float(self.filtered_params['frictionCoefficient'].x)
liveTorqueParameters.totalBucketPoints = len(self.filtered_points)
liveTorqueParameters.decay = self.decay
liveTorqueParameters.maxResets = self.resets
return msg
def main(sm=None, pm=None):
config_realtime_process([0, 1, 2, 3], 5)
if sm is None:
sm = messaging.SubMaster(['carControl', 'carState', 'liveLocationKalman'], poll=['liveLocationKalman'])
if pm is None:
pm = messaging.PubMaster(['liveTorqueParameters'])
params = Params()
CP = car.CarParams.from_bytes(params.get("CarParams", block=True))
estimator = TorqueEstimator(CP)
def cache_params(sig, frame):
signal.signal(sig, signal.SIG_DFL)
cloudlog.warning("caching torque params")
params = Params()
params.put("LiveTorqueCarParams", CP.as_builder().to_bytes())
msg = estimator.get_msg(with_points=True)
params.put("LiveTorqueParameters", msg.to_bytes())
sys.exit(0)
if "REPLAY" not in os.environ:
signal.signal(signal.SIGINT, cache_params)
while True:
sm.update()
if sm.all_checks():
for which in sm.updated.keys():
if sm.updated[which]:
t = sm.logMonoTime[which] * 1e-9
estimator.handle_log(t, which, sm[which])
# 4Hz driven by liveLocationKalman
if sm.frame % 5 == 0:
pm.send('liveTorqueParameters', estimator.get_msg(valid=sm.all_checks()))
if __name__ == "__main__":
main()

@ -103,23 +103,17 @@ std::pair<std::string, kj::Array<capnp::word>> UbloxMsgParser::gen_msg() {
switch (ubx_message.msg_type()) {
case 0x0107:
return {"gpsLocationExternal", gen_nav_pvt(static_cast<ubx_t::nav_pvt_t*>(body))};
break;
case 0x0213:
return {"ubloxGnss", gen_rxm_sfrbx(static_cast<ubx_t::rxm_sfrbx_t*>(body))};
break;
case 0x0215:
return {"ubloxGnss", gen_rxm_rawx(static_cast<ubx_t::rxm_rawx_t*>(body))};
break;
case 0x0a09:
return {"ubloxGnss", gen_mon_hw(static_cast<ubx_t::mon_hw_t*>(body))};
break;
case 0x0a0b:
return {"ubloxGnss", gen_mon_hw2(static_cast<ubx_t::mon_hw2_t*>(body))};
break;
default:
LOGE("Unknown message type %x", ubx_message.msg_type());
return {"ubloxGnss", kj::Array<capnp::word>()};
break;
}
}

@ -5,10 +5,8 @@ libs = [common, cereal, messaging, visionipc,
'avformat', 'avcodec', 'swscale', 'avutil',
'yuv', 'OpenCL', 'pthread']
src = ['logger.cc', 'video_writer.cc', 'encoder/encoder.cc']
if arch == "larch64":
src += ['encoder/v4l_encoder.cc']
else:
src = ['logger.cc', 'video_writer.cc', 'encoder/encoder.cc', 'encoder/v4l_encoder.cc']
if arch != "larch64":
src += ['encoder/ffmpeg_encoder.cc']
if arch == "Darwin":

@ -55,13 +55,11 @@ int main(int argc, char** argv) {
bool r = util::create_directories(LOG_ROOT + "/boot/", 0775);
assert(r);
RawFile bz_file(path.c_str());
RawFile file(path.c_str());
// Write initdata
bz_file.write(logger_build_init_data().asBytes());
file.write(logger_build_init_data().asBytes());
// Write bootlog
bz_file.write(build_boot_log().asBytes());
file.write(build_boot_log().asBytes());
return 0;
}

@ -28,7 +28,6 @@ private:
static void dequeue_handler(V4LEncoder *e);
std::thread dequeue_handler_thread;
VisionBuf buf_in[BUF_IN_COUNT];
VisionBuf buf_out[BUF_OUT_COUNT];
SafeQueue<unsigned int> free_buf_in;
};

@ -83,8 +83,10 @@ class TestLoggerd(unittest.TestCase):
("GitRemote", "gitRemote", "remote"),
]
params = Params()
params.clear_all()
for k, _, v in fake_params:
params.put(k, v)
params.put("LaikadEphemeris", "abc")
lr = list(LogReader(str(self._gen_bootlog())))
initData = lr[0].initData
@ -99,8 +101,14 @@ class TestLoggerd(unittest.TestCase):
with open("/proc/version") as f:
self.assertEqual(initData.kernelVersion, f.read())
for _, k, v in fake_params:
self.assertEqual(getattr(initData, k), v)
# check params
logged_params = {entry.key: entry.value for entry in initData.params.entries}
expected_params = set(k for k, _, __ in fake_params) | {'LaikadEphemeris'}
assert set(logged_params.keys()) == expected_params, set(logged_params.keys()) ^ expected_params
assert logged_params['LaikadEphemeris'] == b'', f"DONT_LOG param value was logged: {repr(logged_params['LaikadEphemeris'])}"
for param_key, initData_key, v in fake_params:
self.assertEqual(getattr(initData, initData_key), v)
self.assertEqual(logged_params[param_key].decode(), v)
def test_rotation(self):
os.environ["LOGGERD_TEST"] = "1"

@ -38,6 +38,7 @@ procs = [
NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]),
NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False),
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"),
PythonProcess("torqued", "selfdrive.locationd.torqued"),
PythonProcess("controlsd", "selfdrive.controls.controlsd"),
PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True),
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview),

@ -12,9 +12,9 @@ from typing import List, Optional
from cereal import messaging
from common.params import Params
from system.swaglog import cloudlog
from selfdrive.hardware import TICI
from system.hardware import TICI
from common.gpio import gpio_init, gpio_set
from selfdrive.hardware.tici.pins import GPIO
from system.hardware.tici.pins import GPIO
UBLOX_TTY = "/dev/ttyHS0"

@ -4,6 +4,7 @@
#include "common/swaglog.h"
#include "common/timing.h"
#include "common/util.h"
BMX055_Accel::BMX055_Accel(I2CBus *bus) : I2CSensor(bus) {}
@ -23,6 +24,13 @@ int BMX055_Accel::init() {
goto fail;
}
ret = set_register(BMX055_ACCEL_I2C_REG_PMU, BMX055_ACCEL_NORMAL_MODE);
if (ret < 0) {
goto fail;
}
// bmx055 accel has a 1.3ms wakeup time from deep suspend mode
util::sleep_for(10);
// High bandwidth
// ret = set_register(BMX055_ACCEL_I2C_REG_HBW, BMX055_ACCEL_HBW_ENABLE);
// if (ret < 0) {
@ -43,6 +51,16 @@ fail:
return ret;
}
int BMX055_Accel::shutdown() {
// enter deep suspend mode (lowest power mode)
int ret = set_register(BMX055_ACCEL_I2C_REG_PMU, BMX055_ACCEL_DEEP_SUSPEND);
if (ret < 0) {
LOGE("Could not move BMX055 ACCEL in deep suspend mode!")
}
return ret;
}
bool BMX055_Accel::get_event(cereal::SensorEventData::Builder &event) {
uint64_t start_time = nanos_since_boot();
uint8_t buffer[6];

@ -10,6 +10,7 @@
#define BMX055_ACCEL_I2C_REG_X_LSB 0x02
#define BMX055_ACCEL_I2C_REG_TEMP 0x08
#define BMX055_ACCEL_I2C_REG_BW 0x10
#define BMX055_ACCEL_I2C_REG_PMU 0x11
#define BMX055_ACCEL_I2C_REG_HBW 0x13
#define BMX055_ACCEL_I2C_REG_FIFO 0x3F
@ -18,6 +19,8 @@
#define BMX055_ACCEL_HBW_ENABLE 0b10000000
#define BMX055_ACCEL_HBW_DISABLE 0b00000000
#define BMX055_ACCEL_DEEP_SUSPEND 0b00100000
#define BMX055_ACCEL_NORMAL_MODE 0b00000000
#define BMX055_ACCEL_BW_7_81HZ 0b01000
#define BMX055_ACCEL_BW_15_63HZ 0b01001
@ -34,5 +37,5 @@ public:
BMX055_Accel(I2CBus *bus);
int init();
bool get_event(cereal::SensorEventData::Builder &event);
int shutdown() { return 0; }
int shutdown();
};

@ -4,6 +4,7 @@
#include <cmath>
#include "common/swaglog.h"
#include "common/util.h"
#define DEG2RAD(x) ((x) * M_PI / 180.0)
@ -26,6 +27,13 @@ int BMX055_Gyro::init() {
goto fail;
}
ret = set_register(BMX055_GYRO_I2C_REG_LPM1, BMX055_GYRO_NORMAL_MODE);
if (ret < 0) {
goto fail;
}
// bmx055 gyro has a 30ms wakeup time from deep suspend mode
util::sleep_for(50);
// High bandwidth
// ret = set_register(BMX055_GYRO_I2C_REG_HBW, BMX055_GYRO_HBW_ENABLE);
// if (ret < 0) {
@ -54,6 +62,16 @@ fail:
return ret;
}
int BMX055_Gyro::shutdown() {
// enter deep suspend mode (lowest power mode)
int ret = set_register(BMX055_GYRO_I2C_REG_LPM1, BMX055_GYRO_DEEP_SUSPEND);
if (ret < 0) {
LOGE("Could not move BMX055 GYRO in deep suspend mode!")
}
return ret;
}
bool BMX055_Gyro::get_event(cereal::SensorEventData::Builder &event) {
uint64_t start_time = nanos_since_boot();
uint8_t buffer[6];

@ -10,6 +10,7 @@
#define BMX055_GYRO_I2C_REG_RATE_X_LSB 0x02
#define BMX055_GYRO_I2C_REG_RANGE 0x0F
#define BMX055_GYRO_I2C_REG_BW 0x10
#define BMX055_GYRO_I2C_REG_LPM1 0x11
#define BMX055_GYRO_I2C_REG_HBW 0x13
#define BMX055_GYRO_I2C_REG_FIFO 0x3F
@ -18,6 +19,8 @@
#define BMX055_GYRO_HBW_ENABLE 0b10000000
#define BMX055_GYRO_HBW_DISABLE 0b00000000
#define BMX055_GYRO_DEEP_SUSPEND 0b00100000
#define BMX055_GYRO_NORMAL_MODE 0b00000000
#define BMX055_GYRO_RANGE_2000 0b000
#define BMX055_GYRO_RANGE_1000 0b001
@ -34,5 +37,5 @@ public:
BMX055_Gyro(I2CBus *bus);
int init();
bool get_event(cereal::SensorEventData::Builder &event);
int shutdown() { return 0; }
int shutdown();
};

@ -155,6 +155,16 @@ int BMX055_Magn::init() {
return ret;
}
int BMX055_Magn::shutdown() {
// move to suspend mode
int ret = set_register(BMX055_MAGN_I2C_REG_PWR_0, 0);
if (ret < 0) {
LOGE("Could not move BMX055 MAGN in suspend mode!")
}
return ret;
}
bool BMX055_Magn::perform_self_test() {
uint8_t buffer[8];
int16_t x, y;

@ -60,5 +60,5 @@ public:
BMX055_Magn(I2CBus *bus);
int init();
bool get_event(cereal::SensorEventData::Builder &event);
int shutdown() { return 0; }
int shutdown();
};

@ -70,13 +70,26 @@ int LSM6DS3_Accel::shutdown() {
value &= ~(LSM6DS3_ACCEL_INT1_DRDY_XL);
ret = set_register(LSM6DS3_ACCEL_I2C_REG_INT1_CTRL, value);
if (ret < 0) {
LOGE("Could not disable lsm6ds3 acceleration interrupt!")
goto fail;
}
// enable power-down mode
value = 0;
ret = read_register(LSM6DS3_ACCEL_I2C_REG_CTRL1_XL, &value, 1);
if (ret < 0) {
goto fail;
}
return ret;
value &= 0x0F;
ret = set_register(LSM6DS3_ACCEL_I2C_REG_CTRL1_XL, value);
if (ret < 0) {
LOGE("Could not power-down lsm6ds3 accelerometer!")
goto fail;
}
fail:
LOGE("Could not disable lsm6ds3 acceleration interrupt!")
return ret;
}

@ -73,13 +73,26 @@ int LSM6DS3_Gyro::shutdown() {
value &= ~(LSM6DS3_GYRO_INT1_DRDY_G);
ret = set_register(LSM6DS3_GYRO_I2C_REG_INT1_CTRL, value);
if (ret < 0) {
LOGE("Could not disable lsm6ds3 gyroscope interrupt!")
goto fail;
}
// enable power-down mode
value = 0;
ret = read_register(LSM6DS3_GYRO_I2C_REG_CTRL2_G, &value, 1);
if (ret < 0) {
goto fail;
}
return ret;
value &= 0x0F;
ret = set_register(LSM6DS3_GYRO_I2C_REG_CTRL2_G, value);
if (ret < 0) {
LOGE("Could not power-down lsm6ds3 gyroscope!")
goto fail;
}
fail:
LOGE("Could not disable lsm6ds3 gyroscope interrupt!")
return ret;
}

@ -51,6 +51,34 @@ fail:
return ret;
}
int MMC5603NJ_Magn::shutdown() {
int ret = 0;
// disable auto reset of measurements
uint8_t value = 0;
ret = read_register(MMC5603NJ_I2C_REG_INTERNAL_0, &value, 1);
if (ret < 0) {
goto fail;
}
value &= ~(MMC5603NJ_CMM_FREQ_EN | MMC5603NJ_AUTO_SR_EN);
ret = set_register(MMC5603NJ_I2C_REG_INTERNAL_0, value);
if (ret < 0) {
goto fail;
}
// set ODR to 0 to leave continuous mode
ret = set_register(MMC5603NJ_I2C_REG_ODR, 0);
if (ret < 0) {
goto fail;
}
return ret;
fail:
LOGE("Could not disable mmc5603nj auto set reset")
return ret;
}
bool MMC5603NJ_Magn::get_event(cereal::SensorEventData::Builder &event) {
uint64_t start_time = nanos_since_boot();

@ -26,5 +26,5 @@ public:
MMC5603NJ_Magn(I2CBus *bus);
int init();
bool get_event(cereal::SensorEventData::Builder &event);
int shutdown() { return 0; }
int shutdown();
};

@ -28,6 +28,10 @@
ExitHandler do_exit;
std::mutex pm_mutex;
// filter first values (0.5sec) as those may contain inaccuracies
uint64_t init_ts = 0;
constexpr uint64_t init_delay = 500*1e6;
void interrupt_loop(int fd, std::vector<Sensor *>& sensors, PubMaster& pm) {
struct pollfd fd_list[1] = {0};
fd_list[0].fd = fd;
@ -88,11 +92,13 @@ void interrupt_loop(int fd, std::vector<Sensor *>& sensors, PubMaster& pm) {
events.adoptWithCaveats(i, kj::mv(collected_events[i]));
}
{
if (ts - init_ts < init_delay) {
continue;
}
std::lock_guard<std::mutex> lock(pm_mutex);
pm.send("sensorEvents", msg);
}
}
// poweroff sensors, disable interrupts
for (Sensor *sensor : sensors) {
@ -168,7 +174,13 @@ int sensor_loop() {
return -1;
}
// increase interrupt quality by pinning interrupt and process to core 1
setpriority(PRIO_PROCESS, 0, -18);
util::set_core_affinity({1});
std::system("sudo su -c 'echo 1 > /proc/irq/336/smp_affinity_list'");
PubMaster pm({"sensorEvents"});
init_ts = nanos_since_boot();
// thread for reading events via interrupts
std::vector<Sensor *> lsm_interrupt_sensors = {&lsm6ds3_accel, &lsm6ds3_gyro};
@ -187,6 +199,10 @@ int sensor_loop() {
sensors[i]->get_event(event);
}
if (nanos_since_boot() - init_ts < init_delay) {
continue;
}
{
std::lock_guard<std::mutex> lock(pm_mutex);
pm.send("sensorEvents", msg);
@ -196,12 +212,15 @@ int sensor_loop() {
std::this_thread::sleep_for(std::chrono::milliseconds(10) - (end - begin));
}
for (Sensor *sensor : sensors) {
sensor->shutdown();
}
lsm_interrupt_thread.join();
delete i2c_bus_imu;
return 0;
}
int main(int argc, char *argv[]) {
setpriority(PRIO_PROCESS, 0, -18);
return sensor_loop();
}

@ -1,15 +1,13 @@
#!/usr/bin/env python3
import os
import time
import unittest
import numpy as np
from collections import namedtuple
from smbus2 import SMBus
import cereal.messaging as messaging
from cereal import log
from system.hardware import TICI, HARDWARE
from selfdrive.test.helpers import with_processes
from selfdrive.manager.process_config import managed_processes
SENSOR_CONFIGURATIONS = (
@ -50,33 +48,33 @@ SENSOR_CONFIGURATIONS = (
)
Sensor = log.SensorEventData.SensorSource
SensorConfig = namedtuple('SensorConfig', ['type', 'min_samples', 'sanity_min', 'sanity_max'])
SensorConfig = namedtuple('SensorConfig', ['type', 'sanity_min', 'sanity_max'])
ALL_SENSORS = {
Sensor.rpr0521: {
SensorConfig("light", 100, 0, 150),
SensorConfig("light", 0, 150),
},
Sensor.lsm6ds3: {
SensorConfig("acceleration", 100, 5, 15),
SensorConfig("gyroUncalibrated", 100, 0, .2),
SensorConfig("temperature", 100, 0, 60),
SensorConfig("acceleration", 5, 15),
SensorConfig("gyroUncalibrated", 0, .2),
SensorConfig("temperature", 0, 60),
},
Sensor.lsm6ds3trc: {
SensorConfig("acceleration", 100, 5, 15),
SensorConfig("gyroUncalibrated", 100, 0, .2),
SensorConfig("temperature", 100, 0, 60),
SensorConfig("acceleration", 5, 15),
SensorConfig("gyroUncalibrated", 0, .2),
SensorConfig("temperature", 0, 60),
},
Sensor.bmx055: {
SensorConfig("acceleration", 100, 5, 15),
SensorConfig("gyroUncalibrated", 100, 0, .2),
SensorConfig("magneticUncalibrated", 100, 0, 300),
SensorConfig("temperature", 100, 0, 60),
SensorConfig("acceleration", 5, 15),
SensorConfig("gyroUncalibrated", 0, .2),
SensorConfig("magneticUncalibrated", 0, 300),
SensorConfig("temperature", 0, 60),
},
Sensor.mmc5603nj: {
SensorConfig("magneticUncalibrated", 100, 0, 300),
SensorConfig("magneticUncalibrated", 0, 300),
}
}
@ -96,7 +94,6 @@ def read_sensor_events(duration_sec):
return events
def get_proc_interrupts(int_pin):
with open("/proc/interrupts") as f:
lines = f.read().split("\n")
@ -117,12 +114,18 @@ class TestSensord(unittest.TestCase):
HARDWARE.initialize_hardware()
# read initial sensor values every test case can use
os.system("pkill -f ./_sensord")
cls.sample_secs = 5
managed_processes["sensord"].start()
cls.events = read_sensor_events(5)
time.sleep(2)
cls.events = read_sensor_events(cls.sample_secs)
managed_processes["sensord"].stop()
@classmethod
def tearDownClass(cls):
managed_processes["sensord"].stop()
def tearDown(self):
# interrupt check might leave sensord running
managed_processes["sensord"].stop()
def test_sensors_present(self):
@ -138,34 +141,32 @@ class TestSensord(unittest.TestCase):
self.assertIn(seen, SENSOR_CONFIGURATIONS)
def test_lsm6ds3_100Hz(self):
# verify measurements are sampled and published at a 100Hz rate
def test_lsm6ds3_timing(self):
# verify measurements are sampled and published at 104Hz
data_points = set()
sensor_t = {
1: [], # accel
5: [], # gyro
}
for event in self.events:
for measurement in event.sensorEvents:
if str(measurement.source).startswith("lsm6ds3") and measurement.sensor in sensor_t:
sensor_t[measurement.sensor].append(measurement.timestamp)
# skip lsm6ds3 temperature measurements
if measurement.which() == 'temperature':
continue
if str(measurement.source).startswith("lsm6ds3"):
data_points.add(measurement.timestamp)
assert len(data_points) != 0, "No lsm6ds3 sensor events"
data_list = list(data_points)
data_list.sort()
tdiffs = np.diff(data_list)
for s, vals in sensor_t.items():
with self.subTest(sensor=s):
assert len(vals) > 0
tdiffs = np.diff(vals) / 1e6 # millis
high_delay_diffs = set(filter(lambda d: d >= 10.1*10**6, tdiffs))
assert len(high_delay_diffs) < 10, f"Too many high delay packages: {high_delay_diffs}"
high_delay_diffs = list(filter(lambda d: d >= 20., tdiffs))
assert len(high_delay_diffs) < 15, f"Too many large diffs: {high_delay_diffs}"
# 100-108Hz, expected 104Hz
avg_diff = sum(tdiffs)/len(tdiffs)
assert avg_diff > 9.6*10**6, f"avg difference {avg_diff}, below threshold"
assert 9.3 < avg_diff < 10., f"avg difference {avg_diff}, below threshold"
stddev = np.std(tdiffs)
assert stddev < 1.5*10**6, f"Standard-dev to big {stddev}"
assert stddev < 2.0, f"Standard-dev to big {stddev}"
def test_events_check(self):
# verify if all sensors produce events
@ -217,13 +218,9 @@ class TestSensord(unittest.TestCase):
stddev = np.std(tdiffs)
assert stddev < 2*10**6, f"Timing diffs have to high stddev: {stddev}"
@with_processes(['sensord'])
def test_sensor_values_sanity_check(self):
events = read_sensor_events(2)
sensor_values = dict()
for event in events:
for event in self.events:
for m in event.sensorEvents:
# filter unset events (bmx magn)
@ -250,8 +247,9 @@ class TestSensord(unittest.TestCase):
key = (sensor, s.type)
val_cnt = len(sensor_values[key])
err_msg = f"Sensor {sensor} {s.type} got {val_cnt} measurements, expected {s.min_samples}"
assert val_cnt > s.min_samples, err_msg
min_samples = self.sample_secs * 100 # Hz
err_msg = f"Sensor {sensor} {s.type} got {val_cnt} measurements, expected {min_samples}"
assert min_samples*0.9 < val_cnt < min_samples*1.1, err_msg
mean_norm = np.mean(np.linalg.norm(sensor_values[key], axis=1))
err_msg = f"Sensor '{sensor} {s.type}' failed sanity checks {mean_norm} is not between {s.sanity_min} and {s.sanity_max}"
@ -260,26 +258,17 @@ class TestSensord(unittest.TestCase):
def test_sensor_verify_no_interrupts_after_stop(self):
managed_processes["sensord"].start()
time.sleep(1)
# check if the interrupts are enableds
with SMBus(SENSOR_BUS, force=True) as bus:
int1_ctrl_reg = bus.read_byte_data(I2C_ADDR_LSM, 0x0D)
assert int1_ctrl_reg == 3, "Interrupts not enabled!"
time.sleep(3)
# read /proc/interrupts to verify interrupts are received
state_one = get_proc_interrupts(LSM_INT_GPIO)
time.sleep(1)
state_two = get_proc_interrupts(LSM_INT_GPIO)
assert state_one != state_two, "no Interrupts received after sensord start!"
assert state_one != state_two, f"no interrupts received after sensord start!\n{state_one} {state_two}"
managed_processes["sensord"].stop()
# check if the interrupts got disabled
with SMBus(SENSOR_BUS, force=True) as bus:
int1_ctrl_reg = bus.read_byte_data(I2C_ADDR_LSM, 0x0D)
assert int1_ctrl_reg == 0, "Interrupts not disabled!"
time.sleep(1)
# read /proc/interrupts to verify no more interrupts are received
state_one = get_proc_interrupts(LSM_INT_GPIO)

@ -229,6 +229,15 @@ def calibration_rcv_callback(msg, CP, cfg, fsm):
return recv_socks, fsm.frame == 0 or msg.which() == 'cameraOdometry'
def torqued_rcv_callback(msg, CP, cfg, fsm):
# should_recv always true to increment frame
recv_socks = []
frame = fsm.frame + 1 # incrementing hasn't happened yet in SubMaster
if msg.which() == 'liveLocationKalman' and (frame % 5) == 0:
recv_socks = ["liveTorqueParameters"]
return recv_socks, fsm.frame == 0 or msg.which() == 'liveLocationKalman'
def ublox_rcv_callback(msg):
msg_class, msg_id = msg.ubloxRaw[2:4]
if (msg_class, msg_id) in {(1, 7 * 16)}:
@ -251,8 +260,10 @@ CONFIGS = [
proc_name="controlsd",
pub_sub={
"can": ["controlsState", "carState", "carControl", "sendcan", "carEvents", "carParams"],
"deviceState": [], "pandaStates": [], "peripheralState": [], "liveCalibration": [], "driverMonitoringState": [], "longitudinalPlan": [], "lateralPlan": [], "liveLocationKalman": [], "liveParameters": [], "radarState": [],
"modelV2": [], "driverCameraState": [], "roadCameraState": [], "wideRoadCameraState": [], "managerState": [], "testJoystick": [],
"deviceState": [], "pandaStates": [], "peripheralState": [], "liveCalibration": [], "driverMonitoringState": [],
"longitudinalPlan": [], "lateralPlan": [], "liveLocationKalman": [], "liveParameters": [], "radarState": [],
"modelV2": [], "driverCameraState": [], "roadCameraState": [], "wideRoadCameraState": [], "managerState": [],
"testJoystick": [], "liveTorqueParameters": [],
},
ignore=["logMonoTime", "valid", "controlsState.startMonoTime", "controlsState.cumLagMs"],
init_callback=fingerprint,
@ -374,6 +385,18 @@ CONFIGS = [
tolerance=NUMPY_TOLERANCE,
fake_pubsubmaster=True,
),
ProcessConfig(
proc_name="torqued",
pub_sub={
"liveLocationKalman": ["liveTorqueParameters"],
"carState": [], "controlsState": [],
},
ignore=["logMonoTime"],
init_callback=get_car_params,
should_recv_callback=torqued_rcv_callback,
tolerance=NUMPY_TOLERANCE,
fake_pubsubmaster=True,
),
]

@ -1 +1 @@
ef5395e5f36550d2b485216eee5406bf6062e9c9
051fa5bea42027c1a756ae61fd0c752c1e911899

@ -269,11 +269,11 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False):
return seg_path
def regen_and_save(route, sidx, upload=False, use_route_meta=False, outdir=FAKEDATA, disable_tqdm=False):
def regen_and_save(route, sidx, upload=False, use_route_meta=True, outdir=FAKEDATA, disable_tqdm=False):
if use_route_meta:
r = Route(args.route)
lr = LogReader(r.log_paths()[args.seg])
fr = FrameReader(r.camera_paths()[args.seg])
r = Route(route)
lr = LogReader(r.log_paths()[sidx])
fr = FrameReader(r.camera_paths()[sidx])
else:
lr = LogReader(f"cd:/{route.replace('|', '/')}/{sidx}/rlog.bz2")
fr = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/fcamera.hevc")

@ -3,11 +3,12 @@ import argparse
import concurrent.futures
import os
import random
import traceback
from tqdm import tqdm
from selfdrive.test.process_replay.helpers import OpenpilotPrefix
from selfdrive.test.process_replay.regen import regen_and_save
from selfdrive.test.process_replay.test_processes import FAKEDATA, original_segments as segments
from selfdrive.test.process_replay.test_processes import FAKEDATA, source_segments as segments
from tools.lib.route import SegmentName
@ -16,11 +17,15 @@ def regen_job(segment, upload, disable_tqdm):
sn = SegmentName(segment[1])
fake_dongle_id = 'regen' + ''.join(random.choice('0123456789ABCDEF') for _ in range(11))
try:
relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, use_route_meta=False, outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm)
relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, use_route_meta=False,
outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm)
relr = '|'.join(relr.split('/')[-2:])
return f' ("{segment[0]}", "{relr}"), '
except Exception as e:
return f" {segment} failed: {str(e)}"
err = f" {segment} failed: {str(e)}"
err += traceback.format_exc()
err += "\n\n"
return err
if __name__ == "__main__":

@ -15,22 +15,22 @@ from system.version import get_commit
from tools.lib.filereader import FileReader
from tools.lib.logreader import LogReader
original_segments = [
source_segments = [
("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY
("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA
("HYUNDAI", "d824e27e8c60172c|2022-08-19--17-58-07--2"), # HYUNDAI.KIA_EV6
("HYUNDAI", "d824e27e8c60172c|2022-09-13--11-26-50--2"), # HYUNDAI.KIA_EV6
("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI)
("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR)
("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2
("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.CIVIC (NIDEC)
("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.ACCORD (BOSCH)
("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.PACIFICA
("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"), # CHRYSLER.RAM_1500
("SUBARU", "4d70bc5e608678be|2021-01-15--17-02-04--5"), # SUBARU.IMPREZA
("RAM", "2f4452b03ccb98f0|2022-09-07--13-55-08--10"), # CHRYSLER.RAM_1500
("SUBARU", "341dccd5359e3c97|2022-09-12--10-35-33--3"), # SUBARU.OUTBACK
("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT
("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL
("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.GOLF
("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--2"), # MAZDA.CX9_2021
("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.CX9_2021
# Enable when port is tested and dashcamOnly is no longer set
#("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS
@ -38,21 +38,21 @@ original_segments = [
]
segments = [
("BODY", "regen660D86654BA|2022-07-06--14-27-15--0"),
("HYUNDAI", "regen114E5FF24D8|2022-07-14--17-08-47--0"),
("HYUNDAI", "d824e27e8c60172c|2022-08-19--17-58-07--2"),
("TOYOTA", "regenBA97410FBEC|2022-07-06--14-26-49--0"),
("TOYOTA2", "regenDEDB1D9C991|2022-07-06--14-54-08--0"),
("TOYOTA3", "regenDDC1FE60734|2022-07-06--14-32-06--0"),
("HONDA", "regenE62960EEC38|2022-07-14--19-33-24--0"),
("HONDA2", "regenC3EBD92F029|2022-07-14--19-29-47--0"),
("CHRYSLER", "regen38346FB33D0|2022-07-14--18-05-26--0"),
("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"),
("SUBARU", "regen54A1E2BE5AA|2022-07-14--18-07-50--0"),
("GM", "regen76027B408B7|2022-08-16--19-56-58--0"),
("NISSAN", "regenCA0B0DC946E|2022-07-14--18-10-17--0"),
("VOLKSWAGEN", "regen007098CA0EF|2022-07-06--15-01-26--0"),
("MAZDA", "regen61BA413D53B|2022-07-06--14-39-42--0"),
("BODY", "regen9D38397D30D|2022-09-09--13-12-48--0"),
("HYUNDAI", "regenB3953B393C0|2022-09-09--14-49-37--0"),
("HYUNDAI", "regen8DB830E5376|2022-09-13--17-24-37--0"),
("TOYOTA", "regen8FCBB6F06F1|2022-09-09--13-14-07--0"),
("TOYOTA2", "regen956BFA75300|2022-09-09--14-51-24--0"),
("TOYOTA3", "regenE909BC2F430|2022-09-09--20-44-49--0"),
("HONDA", "regenD1D10209015|2022-09-09--14-53-09--0"),
("HONDA2", "regen3F7C2EFDC08|2022-09-09--19-41-19--0"),
("CHRYSLER", "regen92783EAE66B|2022-09-09--13-15-44--0"),
("RAM", "regenBE5DAAEF30F|2022-09-13--17-06-24--0"),
("SUBARU", "regen8A363AF7E14|2022-09-13--17-20-39--0"),
("GM", "regen31EA3F9A37C|2022-09-09--21-06-36--0"),
("NISSAN", "regenAA21ADE5921|2022-09-09--19-44-37--0"),
("VOLKSWAGEN", "regenA1BF4D17761|2022-09-09--19-46-24--0"),
("MAZDA", "regen1994C97E977|2022-09-13--16-34-44--0"),
]
# dashcamOnly makes don't need to be tested until a full port is done

@ -36,6 +36,7 @@ PROCS = {
"./_dmonitoringmodeld": 5.0,
"selfdrive.thermald.thermald": 3.87,
"selfdrive.locationd.calibrationd": 2.0,
"selfdrive.locationd.torqued": 5.0,
"./_soundd": 1.0,
"selfdrive.monitoring.dmonitoringd": 4.0,
"./proclogd": 1.54,

@ -4,7 +4,7 @@ import subprocess
from azure.storage.blob import BlockBlobService # pylint: disable=import-error
from selfdrive.car.tests.routes import routes as test_car_models_routes
from selfdrive.test.process_replay.test_processes import original_segments as replay_segments
from selfdrive.test.process_replay.test_processes import source_segments as replay_segments
from xx.chffr.lib import azureutil # pylint: disable=import-error
from xx.chffr.lib.storage import _DATA_ACCOUNT_PRODUCTION, _DATA_ACCOUNT_CI, _DATA_BUCKET_PRODUCTION # pylint: disable=import-error

@ -41,6 +41,7 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
setAttribute(Qt::WA_NoSystemBackground);
QObject::connect(uiState(), &UIState::uiUpdate, this, &HomeWindow::updateState);
QObject::connect(uiState(), &UIState::offroadTransition, this, &HomeWindow::offroadTransition);
QObject::connect(uiState(), &UIState::offroadTransition, sidebar, &Sidebar::offroadTransition);
}
void HomeWindow::showSidebar(bool show) {

@ -204,7 +204,8 @@ void MapWindow::updateState(const UIState &s) {
if (zoom_counter == 0) {
m_map->setZoom(util::map_val<float>(velocity_filter.x(), 0, 30, MAX_ZOOM, MIN_ZOOM));
} else {
zoom_counter = -1;
} else if (zoom_counter > 0) {
zoom_counter--;
}

@ -98,7 +98,7 @@ private:
// Panning
QPointF m_lastPos;
int pan_counter = 0;
int zoom_counter = 0;
int zoom_counter = -1;
// Position
std::optional<QMapbox::Coordinate> last_position;

@ -134,8 +134,8 @@ void TogglesPanel::updateToggles() {
e2e_toggle->setEnabled(false);
params.remove("EndToEndLong");
const QString no_long = "openpilot longitudinal control is not currently available for this car.";
const QString exp_long = "Enable experimental longitudinal control to enable this.";
const QString no_long = tr("openpilot longitudinal control is not currently available for this car.");
const QString exp_long = tr("Enable experimental longitudinal control to enable this.");
e2e_toggle->setDescription("<b>" + (CP.getExperimentalLongitudinalAvailable() ? exp_long : no_long) + "</b><br><br>" + e2e_description);
}

@ -45,7 +45,7 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
installBtn = new ButtonControl(tr("Install Update"), tr("INSTALL"));
connect(installBtn, &ButtonControl::clicked, [=]() {
installBtn->setEnabled(false);
params.putBool("DoShutdown", true);
params.putBool("DoReboot", true);
});
addItem(installBtn);

@ -26,6 +26,11 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
split->setSpacing(0);
split->addWidget(nvg);
if (getenv("DUAL_CAMERA_VIEW")) {
CameraViewWidget *arCam = new CameraViewWidget("camerad", VISION_STREAM_ROAD, true, this);
split->insertWidget(0, arCam);
}
stacked_layout->addWidget(split_wrapper);
alerts = new OnroadAlerts(this);

@ -32,8 +32,9 @@ void Sidebar::drawMetric(QPainter &p, const QPair<QString, QString> &label, QCol
p.drawText(label_rect, Qt::AlignCenter, label.second);
}
Sidebar::Sidebar(QWidget *parent) : QFrame(parent) {
Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(false), settings_pressed(false) {
home_img = loadPixmap("../assets/images/button_home.png", home_btn.size());
flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size());
settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio);
connect(this, &Sidebar::valueChanged, [=] { update(); });
@ -47,17 +48,35 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent) {
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"userFlag"});
}
void Sidebar::mousePressEvent(QMouseEvent *event) {
if (onroad && home_btn.contains(event->pos())) {
flag_pressed = true;
update();
} else if (settings_btn.contains(event->pos())) {
settings_pressed = true;
update();
}
}
void Sidebar::mouseReleaseEvent(QMouseEvent *event) {
if (flag_pressed || settings_pressed) {
flag_pressed = settings_pressed = false;
update();
}
if (home_btn.contains(event->pos())) {
MessageBuilder msg;
msg.initEvent().initUserFlag();
pm->send("userFlag", msg);
}
if (settings_btn.contains(event->pos())) {
} else if (settings_btn.contains(event->pos())) {
emit openSettings();
}
}
void Sidebar::offroadTransition(bool offroad) {
onroad = !offroad;
update();
}
void Sidebar::updateState(const UIState &s) {
if (!isVisible()) return;
@ -102,11 +121,12 @@ void Sidebar::paintEvent(QPaintEvent *event) {
p.fillRect(rect(), QColor(57, 57, 57));
// static imgs
p.setOpacity(0.65);
// buttons
p.setOpacity(settings_pressed ? 0.65 : 1.0);
p.drawPixmap(settings_btn.x(), settings_btn.y(), settings_img);
p.setOpacity(onroad && flag_pressed ? 0.65 : 1.0);
p.drawPixmap(home_btn.x(), home_btn.y(), onroad ? flag_img : home_img);
p.setOpacity(1.0);
p.drawPixmap(home_btn.x(), home_btn.y(), home_img);
// network
int x = 58;

@ -24,14 +24,17 @@ signals:
void valueChanged();
public slots:
void offroadTransition(bool offroad);
void updateState(const UIState &s);
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void drawMetric(QPainter &p, const QPair<QString, QString> &label, QColor c, int y);
QPixmap home_img, settings_img;
QPixmap home_img, flag_img, settings_img;
bool onroad, flag_pressed, settings_pressed;
const QMap<cereal::DeviceState::NetworkType, QString> network_type = {
{cereal::DeviceState::NetworkType::NONE, tr("--")},
{cereal::DeviceState::NetworkType::WIFI, tr("Wi-Fi")},

@ -18,8 +18,6 @@ QFrame *horizontal_line(QWidget *parent) {
}
AbstractControl::AbstractControl(const QString &title, const QString &desc, const QString &icon, QWidget *parent) : QFrame(parent) {
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setMargin(0);

@ -277,7 +277,7 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
primeUser = new PrimeUserWidget;
mainLayout->addWidget(primeUser);
mainLayout->setCurrentWidget(primeAd);
mainLayout->setCurrentWidget(uiState()->prime_type ? (QWidget*)primeUser : (QWidget*)primeAd);
setFixedWidth(750);
setStyleSheet(R"(
@ -299,11 +299,9 @@ SetupWidget::SetupWidget(QWidget* parent) : QFrame(parent) {
QObject::connect(repeater, &RequestRepeater::requestDone, this, &SetupWidget::replyFinished);
}
hide(); // Only show when first request comes back
}
void SetupWidget::replyFinished(const QString &response, bool success) {
show();
if (!success) return;
QJsonDocument doc = QJsonDocument::fromJson(response.toUtf8());

@ -29,10 +29,7 @@ class TestTranslations(unittest.TestCase):
def _read_translation_file(path, file):
tr_file = os.path.join(path, f"{file}.ts")
with open(tr_file, "r") as f:
# ignore locations when checking if translations are updated
lines = [line for line in f.read().splitlines() if
not line.strip().startswith(LOCATION_TAG)]
return "\n".join(lines)
return f.read()
def test_missing_translation_files(self):
for name, file in self.translation_files.items():
@ -93,6 +90,13 @@ class TestTranslations(unittest.TestCase):
self.assertTrue(all([re.search("%[0-9]+", t) is None for t in numerusform]),
"Plural translations must use %n, not %1, %2, etc.: {}".format(numerusform))
def test_no_locations(self):
for name, file in self.translation_files.items():
with self.subTest(name=name, file=file):
for line in self._read_translation_file(TRANSLATIONS_DIR, file).splitlines():
self.assertFalse(line.strip().startswith(LOCATION_TAG),
f"Line contains location tag: {line.strip()}, remove all line numbers.")
if __name__ == "__main__":
unittest.main()

@ -4,7 +4,6 @@
<context>
<name>InputDialog</name>
<message numerus="yes">
<location filename="../qt/widgets/input.cc" line="+168"/>
<source>Need at least %n character(s)!</source>
<translation>
<numerusform>Need at least %n character!</numerusform>
@ -15,7 +14,6 @@
<context>
<name>QObject</name>
<message numerus="yes">
<location filename="../qt/util.cc" line="+82"/>
<source>%n minute(s) ago</source>
<translation>
<numerusform>%n minute ago</numerusform>
@ -23,7 +21,6 @@
</translation>
</message>
<message numerus="yes">
<location line="+3"/>
<source>%n hour(s) ago</source>
<translation>
<numerusform>%n hour ago</numerusform>
@ -31,7 +28,6 @@
</translation>
</message>
<message numerus="yes">
<location line="+3"/>
<source>%n day(s) ago</source>
<translation>
<numerusform>%n day ago</numerusform>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -19,7 +19,7 @@ def update_translations(vanish=False, plural_only=None, translations_dir=TRANSLA
for file in translation_files.values():
tr_file = os.path.join(translations_dir, f"{file}.ts")
args = f"lupdate -locations relative -recursive {UI_DIR} -ts {tr_file}"
args = f"lupdate -locations none -recursive {UI_DIR} -ts {tr_file}"
if vanish:
args += " -no-obsolete"
if file in plural_only:

@ -52,6 +52,8 @@ OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata")
OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged")
FINALIZED = os.path.join(STAGING_ROOT, "finalized")
OVERLAY_INIT = Path(os.path.join(BASEDIR, ".overlay_init"))
DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
@ -134,12 +136,10 @@ def dismount_overlay() -> None:
def init_overlay() -> None:
overlay_init_file = Path(os.path.join(BASEDIR, ".overlay_init"))
# Re-create the overlay if BASEDIR/.git has changed since we created the overlay
if overlay_init_file.is_file():
if OVERLAY_INIT.is_file() and os.path.ismount(OVERLAY_MERGED):
git_dir_path = os.path.join(BASEDIR, ".git")
new_files = run(["find", git_dir_path, "-newer", str(overlay_init_file)])
new_files = run(["find", git_dir_path, "-newer", str(OVERLAY_INIT)])
if not len(new_files.splitlines()):
# A valid overlay already exists
return
@ -170,7 +170,7 @@ def init_overlay() -> None:
consistent_file = Path(os.path.join(BASEDIR, ".overlay_consistent"))
if consistent_file.is_file():
consistent_file.unlink()
overlay_init_file.touch()
OVERLAY_INIT.touch()
os.sync()
overlay_opts = f"lowerdir={BASEDIR},upperdir={OVERLAY_UPPER},workdir={OVERLAY_METADATA}"
@ -240,7 +240,7 @@ def handle_agnos_update() -> None:
class Updater:
def __init__(self):
self.params = Params()
self.branches = defaultdict(lambda: None)
self.branches = defaultdict(lambda: '')
@property
def target_branch(self) -> str:
@ -374,8 +374,8 @@ class Updater:
cloudlog.info("git reset in progress")
cmds = [
["git", "checkout", "--force", "--no-recurse-submodules", branch],
["git", "reset", "--hard", f"origin/{branch}"],
["git", "checkout", "--force", "--no-recurse-submodules", "-B", branch, "FETCH_HEAD"],
["git", "reset", "--hard"],
["git", "clean", "-xdf"],
["git", "submodule", "init"],
["git", "submodule", "update"],
@ -419,9 +419,6 @@ def main() -> None:
t = datetime.datetime.utcnow().isoformat()
params.put("InstallDate", t.encode('utf8'))
overlay_init = Path(os.path.join(BASEDIR, ".overlay_init"))
overlay_init.unlink(missing_ok=True)
updater = Updater()
update_failed_count = 0 # TODO: Load from param?
@ -461,11 +458,11 @@ def main() -> None:
returncode=e.returncode
)
exception = f"command failed: {e.cmd}\n{e.output}"
overlay_init.unlink(missing_ok=True)
OVERLAY_INIT.unlink(missing_ok=True)
except Exception as e:
cloudlog.exception("uncaught updated exception, shouldn't happen")
exception = str(e)
overlay_init.unlink(missing_ok=True)
OVERLAY_INIT.unlink(missing_ok=True)
try:
params.put("UpdaterState", "idle")

@ -65,11 +65,9 @@ private:
void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType init_yuv_type) {
vipc_server = v;
this->yuv_type = init_yuv_type;
const CameraInfo *ci = &s->ci;
camera_state = s;
frame_buf_count = frame_cnt;
const CameraInfo *ci = &s->ci;
// RAW frame
const int frame_size = (ci->frame_height + ci->extra_height) * ci->frame_stride;
camera_bufs = std::make_unique<VisionBuf[]>(frame_buf_count);
@ -118,24 +116,18 @@ bool CameraBuf::acquire() {
if (camera_bufs_metadata[cur_buf_idx].frame_id == -1) {
LOGE("no frame data? wtf");
release();
return false;
}
cur_frame_data = camera_bufs_metadata[cur_buf_idx];
cur_yuv_buf = vipc_server->get_buffer(yuv_type);
cl_mem camrabuf_cl = camera_bufs[cur_buf_idx].buf_cl;
cl_event event;
double start_time = millis_since_boot();
cur_camera_buf = &camera_bufs[cur_buf_idx];
debayer->queue(q, camrabuf_cl, cur_yuv_buf->buf_cl, rgb_width, rgb_height, &event);
double start_time = millis_since_boot();
cl_event event;
debayer->queue(q, camera_bufs[cur_buf_idx].buf_cl, cur_yuv_buf->buf_cl, rgb_width, rgb_height, &event);
clWaitForEvents(1, &event);
CL_CHECK(clReleaseEvent(event));
cur_frame_data.processing_time = (millis_since_boot() - start_time) / 1000.0;
VisionIpcBufExtra extra = {
@ -149,10 +141,6 @@ bool CameraBuf::acquire() {
return true;
}
void CameraBuf::release() {
// Empty
}
void CameraBuf::queue(size_t buf_idx) {
safe_queue.push(buf_idx);
}
@ -330,7 +318,6 @@ void *processing_thread(MultiCameraState *cameras, CameraState *cs, process_thre
// this takes 10ms???
publish_thumbnail(cameras->pm, &(cs->buf));
}
cs->buf.release();
++cnt;
}
return NULL;
@ -349,6 +336,7 @@ void camerad_thread() {
cl_context context = CL_CHECK_ERR(clCreateContext(NULL, 1, &device_id, NULL, NULL, &err));
#endif
{
MultiCameraState cameras = {};
VisionIpcServer vipc_server("camerad", device_id, context);
@ -358,6 +346,7 @@ void camerad_thread() {
vipc_server.start_listener();
cameras_run(&cameras);
}
CL_CHECK(clReleaseContext(context));
}

@ -75,21 +75,16 @@ typedef struct FrameMetadata {
} FrameMetadata;
struct MultiCameraState;
struct CameraState;
class CameraState;
class Debayer;
class CameraBuf {
private:
VisionIpcServer *vipc_server;
CameraState *camera_state;
Debayer *debayer = nullptr;
VisionStreamType yuv_type;
int cur_buf_idx;
SafeQueue<int> safe_queue;
int frame_buf_count;
public:
@ -107,7 +102,6 @@ public:
~CameraBuf();
void init(cl_device_id device_id, cl_context context, CameraState *s, VisionIpcServer * v, int frame_cnt, VisionStreamType yuv_type);
bool acquire();
void release();
void queue(size_t buf_idx);
};
@ -122,7 +116,6 @@ void cameras_init(VisionIpcServer *v, MultiCameraState *s, cl_device_id device_i
void cameras_open(MultiCameraState *s);
void cameras_run(MultiCameraState *s);
void cameras_close(MultiCameraState *s);
void camera_autoexposure(CameraState *s, float grey_frac);
void camerad_thread();
int open_v4l_by_name_and_index(const char name[], int index = 0, int flags = O_RDWR | O_NONBLOCK);

@ -52,7 +52,8 @@ CameraInfo cameras_supported[CAMERA_ID_MAX] = {
.frame_width = FRAME_WIDTH,
.frame_height = FRAME_HEIGHT,
.frame_stride = FRAME_STRIDE, // (0xa80*12//8)
.extra_height = 16, // this right?
.extra_height = 16, // top 2 + bot 14
.frame_offset = 2,
},
};
@ -821,8 +822,8 @@ void cameras_open(MultiCameraState *s) {
// query icp for MMU handles
LOG("-- Query ICP for MMU handles");
static struct cam_isp_query_cap_cmd isp_query_cap_cmd = {0};
static struct cam_query_cap_cmd query_cap_cmd = {0};
struct cam_isp_query_cap_cmd isp_query_cap_cmd = {0};
struct cam_query_cap_cmd query_cap_cmd = {0};
query_cap_cmd.handle_type = 1;
query_cap_cmd.caps_handle = (uint64_t)&isp_query_cap_cmd;
query_cap_cmd.size = sizeof(isp_query_cap_cmd);
@ -835,7 +836,7 @@ void cameras_open(MultiCameraState *s) {
// subscribe
LOG("-- Subscribing");
static struct v4l2_event_subscription sub = {0};
struct v4l2_event_subscription sub = {0};
sub.type = V4L_EVENT_CAM_REQ_MGR_EVENT;
sub.id = V4L_EVENT_CAM_REQ_MGR_SOF_BOOT_TS;
ret = HANDLE_EINTR(ioctl(s->video0_fd, VIDIOC_SUBSCRIBE_EVENT, &sub));
@ -864,7 +865,7 @@ void CameraState::camera_close() {
LOGD("stop csiphy: %d", ret);
// link control stop
LOG("-- Stop link control");
static struct cam_req_mgr_link_control req_mgr_link_control = {0};
struct cam_req_mgr_link_control req_mgr_link_control = {0};
req_mgr_link_control.ops = CAM_REQ_MGR_LINK_DEACTIVATE;
req_mgr_link_control.session_hdl = session_handle;
req_mgr_link_control.num_links = 1;
@ -874,7 +875,7 @@ void CameraState::camera_close() {
// unlink
LOG("-- Unlink");
static struct cam_req_mgr_unlink_info req_mgr_unlink_info = {0};
struct cam_req_mgr_unlink_info req_mgr_unlink_info = {0};
req_mgr_unlink_info.session_hdl = session_handle;
req_mgr_unlink_info.link_hdl = link_handle;
ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_UNLINK, &req_mgr_unlink_info, sizeof(req_mgr_unlink_info));
@ -1180,10 +1181,6 @@ void CameraState::set_camera_exposure(float grey_frac) {
}
}
void camera_autoexposure(CameraState *s, float grey_frac) {
s->set_camera_exposure(grey_frac);
}
static float ar0231_parse_temp_sensor(uint16_t calib1, uint16_t calib2, uint16_t data_reg) {
// See AR0231 Developer Guide - page 36
float slope = (125.0 - 55.0) / ((float)calib1 - (float)calib2);
@ -1210,15 +1207,8 @@ static void ar0231_process_registers(MultiCameraState *s, CameraState *c, cereal
framed.setTemperaturesC({temp_0, temp_1});
}
static void driver_cam_auto_exposure(CameraState *c) {
struct ExpRect {int x1, x2, x_skip, y1, y2, y_skip;};
const CameraBuf *b = &c->buf;
static ExpRect rect = {96, 1832, 2, 242, 1148, 4};
camera_autoexposure(c, set_exposure_target(b, rect.x1, rect.x2, rect.x_skip, rect.y1, rect.y2, rect.y_skip));
}
static void process_driver_camera(MultiCameraState *s, CameraState *c, int cnt) {
driver_cam_auto_exposure(c);
c->set_camera_exposure(set_exposure_target(&c->buf, 96, 1832, 2, 242, 1148, 4));
MessageBuilder msg;
auto framed = msg.initEvent().initDriverCameraState();
@ -1254,7 +1244,7 @@ void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) {
const auto [x, y, w, h] = (c == &s->wide_road_cam) ? std::tuple(96, 250, 1734, 524) : std::tuple(96, 160, 1734, 986);
const int skip = 2;
camera_autoexposure(c, set_exposure_target(b, x, x + w, skip, y, y + h, skip));
c->set_camera_exposure(set_exposure_target(b, x, x + w, skip, y, y + h, skip));
}
void cameras_run(MultiCameraState *s) {

@ -9,9 +9,9 @@
float3 color_correct(float3 rgb) {
// color correction
#if IS_OX
float3 x = rgb.x * (float3)(1.81485125, -0.51650643, -0.06985117);
x += rgb.y * (float3)(-0.51681964, 1.85935946, -0.49871889);
x += rgb.z * (float3)(-0.29803161, -0.34285304, 1.56857006);
float3 x = rgb.x * (float3)(1.5664815 , -0.29808738, -0.03973474);
x += rgb.y * (float3)(-0.48672447, 1.41914433, -0.40295248);
x += rgb.z * (float3)(-0.07975703, -0.12105695, 1.44268722);
#else
float3 x = rgb.x * (float3)(1.82717181, -0.31231438, 0.07307673);
x += rgb.y * (float3)(-0.5743977, 1.36858544, -0.53183455);

@ -727,10 +727,10 @@ struct i2c_random_wr_payload init_array_ox03c10[] = {
// color balance gains
// blue
{0x5280, 0x06}, {0x5281, 0x4A}, // hcg
{0x5480, 0x06}, {0x5481, 0x4A}, // lcg
{0x5680, 0x07}, {0x5681, 0xDD}, // spd
{0x5880, 0x06}, {0x5881, 0x4A}, // vs
{0x5280, 0x06}, {0x5281, 0xCB}, // hcg
{0x5480, 0x06}, {0x5481, 0xCB}, // lcg
{0x5680, 0x06}, {0x5681, 0xCB}, // spd
{0x5880, 0x06}, {0x5881, 0xCB}, // vs
// green(blue)
{0x5282, 0x04}, {0x5283, 0x00},
@ -745,10 +745,10 @@ struct i2c_random_wr_payload init_array_ox03c10[] = {
{0x5884, 0x04}, {0x5885, 0x00},
// red
{0x5286, 0x08}, {0x5287, 0x6C},
{0x5486, 0x08}, {0x5487, 0x6C},
{0x5686, 0x08}, {0x5687, 0xAA},
{0x5886, 0x08}, {0x5887, 0x6C},
{0x5286, 0x08}, {0x5287, 0xDE},
{0x5486, 0x08}, {0x5487, 0xDE},
{0x5686, 0x08}, {0x5687, 0xDE},
{0x5886, 0x08}, {0x5887, 0xDE},
};
struct i2c_random_wr_payload init_array_ar0231[] = {

@ -1,9 +1,9 @@
[
{
"name": "boot",
"url": "https://commadist.azureedge.net/agnosupdate/boot-243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8.img.xz",
"hash": "243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8",
"hash_raw": "243ddbb9e2256aa7af7fed0daf8cff4017a3c838c759373a634b8539f271bfb8",
"url": "https://commadist.azureedge.net/agnosupdate/boot-57626d7737ab2fa1318e8707a202b1295b5da79ad2fa0a36377cc9481ad0d136.img.xz",
"hash": "57626d7737ab2fa1318e8707a202b1295b5da79ad2fa0a36377cc9481ad0d136",
"hash_raw": "57626d7737ab2fa1318e8707a202b1295b5da79ad2fa0a36377cc9481ad0d136",
"size": 14780416,
"sparse": false,
"full_check": true,
@ -41,9 +41,9 @@
},
{
"name": "system",
"url": "https://commadist.azureedge.net/agnosupdate/system-59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13.img.xz",
"hash": "44da205d17b44b2be7c94854a6bb3efb2928ec9a9889fe62af8b322d2295b74f",
"hash_raw": "59622eddd068d49f2e9df69ef5115e3f205ad369539690a5b240c8c93796dd13",
"url": "https://commadist.azureedge.net/agnosupdate/system-9db38e27c912005472f3ac02be336af4f82307295118b6db22921479d44a941d.img.xz",
"hash": "05e7ce440b33721b020a249043d9568a5898080e26411ca250fb330ad2e5ed8e",
"hash_raw": "9db38e27c912005472f3ac02be336af4f82307295118b6db22921479d44a941d",
"size": 10737418240,
"sparse": true,
"full_check": false,

@ -462,17 +462,6 @@ class Tici(HardwareBase):
sudo_write("N", "/sys/kernel/debug/msm_vidc/clock_scaling")
sudo_write("Y", "/sys/kernel/debug/msm_vidc/disable_thermal_mitigation")
# *** unexport GPIO for sensors ***
# remove from /userspace/usr/comma/gpio.sh
sudo_write(str(GPIO.BMX055_ACCEL_INT), "/sys/class/gpio/unexport")
sudo_write(str(GPIO.BMX055_GYRO_INT), "/sys/class/gpio/unexport")
sudo_write(str(GPIO.BMX055_MAGN_INT), "/sys/class/gpio/unexport")
sudo_write(str(GPIO.LSM_INT), "/sys/class/gpio/unexport")
# *** set /dev/gpiochip0 rights to make accessible by sensord
os.system("sudo chmod +r /dev/gpiochip0")
def configure_modem(self):
sim_id = self.get_sim_info().get('sim_id', '')

@ -85,6 +85,16 @@ def decoder(addr, sock_name, vipc_server, vst, nvidia):
time_q = time_q[1:]
print("%2d %4d %.3f %.3f roll %6.2f ms latency %6.2f ms + %6.2f ms + %6.2f ms = %6.2f ms" % (len(msgs), evta.idx.encodeId, evt.logMonoTime/1e9, evta.idx.timestampEof/1e6, frame_latency, process_latency, network_latency, pc_latency, process_latency+network_latency+pc_latency ), len(evta.data), sock_name)
def main(addr, cams, nvidia=False):
vipc_server = VisionIpcServer("camerad")
for vst in cams.values():
vipc_server.create_buffers(vst, 4, False, W, H)
vipc_server.start_listener()
for k, v in cams.items():
multiprocessing.Process(target=decoder, args=(addr, k, vipc_server, v, nvidia)).start()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Decode video streams and broadcast on VisionIPC")
parser.add_argument("addr", help="Address of comma three")
@ -98,11 +108,4 @@ if __name__ == "__main__":
("driverEncodeData", VisionStreamType.VISION_STREAM_DRIVER),
]
cams = dict([all_cams[int(x)] for x in args.cams.split(",")])
vipc_server = VisionIpcServer("camerad")
for vst in cams.values():
vipc_server.create_buffers(vst, 4, False, W, H)
vipc_server.start_listener()
for k,v in cams.items():
multiprocessing.Process(target=decoder, args=(args.addr, k, vipc_server, v, args.nvidia)).start()
main(args.addr, cams, args.nvidia)

@ -290,6 +290,7 @@ void Replay::startStream(const Segment *cur_segment) {
auto words = capnp::messageToFlatArray(builder);
auto bytes = words.asBytes();
Params().put("CarParams", (const char *)bytes.begin(), bytes.size());
Params().put("CarParamsPersistent", (const char *)bytes.begin(), bytes.size());
} else {
rWarning("failed to read CarParams from current segment");
}

Loading…
Cancel
Save