openpilot v0.7 release

old-commit-hash: c025b96e8a
commatwo_master
Vehicle Researcher 6 years ago
parent ee493eed79
commit 99b637c7ce
  1. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 12
      .gitignore
  3. 10
      Dockerfile.openpilot
  4. 4
      Pipfile
  5. 4
      Pipfile.lock
  6. 193
      README.md
  7. 36
      README_chffrplus.md
  8. 15
      RELEASES.md
  9. 212
      SConstruct
  10. 4
      apk/ai.comma.plus.frame.apk
  11. 4
      apk/ai.comma.plus.offroad.apk
  12. 1
      common/.gitignore
  13. 6
      common/SConscript
  14. 73
      common/android.py
  15. 98
      common/apk.py
  16. 20
      common/common_pyx_setup.py
  17. 276
      common/dbc.py
  18. 10
      common/kalman/Makefile
  19. 6
      common/kalman/SConscript
  20. 8
      common/kalman/simple_kalman.py
  21. 2
      common/kalman/simple_kalman_setup.py
  22. 5
      common/params.py
  23. 10
      common/realtime.py
  24. 33
      common/spinner.py
  25. 6
      common/transformations/camera.py
  26. 8
      installer/updater/update.json
  27. 13
      launch_chffrplus.sh
  28. 4
      models/driving_model.dlc
  29. 3
      models/monitoring_model.dlc
  30. 3
      models/monitoring_model_q.dlc
  31. BIN
      panda/board/obj/panda.bin.signed
  32. 3
      phonelibs/SConscript
  33. 3
      phonelibs/boringssl/LICENSE.boringssl
  34. 3
      phonelibs/eigen/COPYING.BSD
  35. 3
      phonelibs/eigen/COPYING.GPL
  36. 3
      phonelibs/eigen/COPYING.LGPL
  37. 3
      phonelibs/eigen/COPYING.MINPACK
  38. 3
      phonelibs/eigen/COPYING.MPL2
  39. 3
      phonelibs/eigen/COPYING.README
  40. 3
      phonelibs/eigen/Eigen/CMakeLists.txt
  41. 3
      phonelibs/eigen/Eigen/Cholesky
  42. 3
      phonelibs/eigen/Eigen/CholmodSupport
  43. 3
      phonelibs/eigen/Eigen/Core
  44. 3
      phonelibs/eigen/Eigen/Dense
  45. 3
      phonelibs/eigen/Eigen/Eigen
  46. 3
      phonelibs/eigen/Eigen/Eigenvalues
  47. 3
      phonelibs/eigen/Eigen/Geometry
  48. 3
      phonelibs/eigen/Eigen/Householder
  49. 3
      phonelibs/eigen/Eigen/IterativeLinearSolvers
  50. 3
      phonelibs/eigen/Eigen/Jacobi
  51. 3
      phonelibs/eigen/Eigen/LU
  52. 3
      phonelibs/eigen/Eigen/MetisSupport
  53. 3
      phonelibs/eigen/Eigen/OrderingMethods
  54. 3
      phonelibs/eigen/Eigen/PaStiXSupport
  55. 3
      phonelibs/eigen/Eigen/PardisoSupport
  56. 3
      phonelibs/eigen/Eigen/QR
  57. 3
      phonelibs/eigen/Eigen/QtAlignedMalloc
  58. 3
      phonelibs/eigen/Eigen/SPQRSupport
  59. 3
      phonelibs/eigen/Eigen/SVD
  60. 3
      phonelibs/eigen/Eigen/Sparse
  61. 3
      phonelibs/eigen/Eigen/SparseCholesky
  62. 3
      phonelibs/eigen/Eigen/SparseCore
  63. 3
      phonelibs/eigen/Eigen/SparseLU
  64. 3
      phonelibs/eigen/Eigen/SparseQR
  65. 3
      phonelibs/eigen/Eigen/StdDeque
  66. 3
      phonelibs/eigen/Eigen/StdList
  67. 3
      phonelibs/eigen/Eigen/StdVector
  68. 3
      phonelibs/eigen/Eigen/SuperLUSupport
  69. 3
      phonelibs/eigen/Eigen/UmfPackSupport
  70. 3
      phonelibs/eigen/Eigen/src/Cholesky/LDLT.h
  71. 3
      phonelibs/eigen/Eigen/src/Cholesky/LLT.h
  72. 3
      phonelibs/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h
  73. 3
      phonelibs/eigen/Eigen/src/CholmodSupport/CholmodSupport.h
  74. 3
      phonelibs/eigen/Eigen/src/Core/Array.h
  75. 3
      phonelibs/eigen/Eigen/src/Core/ArrayBase.h
  76. 3
      phonelibs/eigen/Eigen/src/Core/ArrayWrapper.h
  77. 3
      phonelibs/eigen/Eigen/src/Core/Assign.h
  78. 3
      phonelibs/eigen/Eigen/src/Core/AssignEvaluator.h
  79. 3
      phonelibs/eigen/Eigen/src/Core/Assign_MKL.h
  80. 3
      phonelibs/eigen/Eigen/src/Core/BandMatrix.h
  81. 3
      phonelibs/eigen/Eigen/src/Core/Block.h
  82. 3
      phonelibs/eigen/Eigen/src/Core/BooleanRedux.h
  83. 3
      phonelibs/eigen/Eigen/src/Core/CommaInitializer.h
  84. 3
      phonelibs/eigen/Eigen/src/Core/ConditionEstimator.h
  85. 3
      phonelibs/eigen/Eigen/src/Core/CoreEvaluators.h
  86. 3
      phonelibs/eigen/Eigen/src/Core/CoreIterators.h
  87. 3
      phonelibs/eigen/Eigen/src/Core/CwiseBinaryOp.h
  88. 3
      phonelibs/eigen/Eigen/src/Core/CwiseNullaryOp.h
  89. 3
      phonelibs/eigen/Eigen/src/Core/CwiseTernaryOp.h
  90. 3
      phonelibs/eigen/Eigen/src/Core/CwiseUnaryOp.h
  91. 3
      phonelibs/eigen/Eigen/src/Core/CwiseUnaryView.h
  92. 3
      phonelibs/eigen/Eigen/src/Core/DenseBase.h
  93. 3
      phonelibs/eigen/Eigen/src/Core/DenseCoeffsBase.h
  94. 3
      phonelibs/eigen/Eigen/src/Core/DenseStorage.h
  95. 3
      phonelibs/eigen/Eigen/src/Core/Diagonal.h
  96. 3
      phonelibs/eigen/Eigen/src/Core/DiagonalMatrix.h
  97. 3
      phonelibs/eigen/Eigen/src/Core/DiagonalProduct.h
  98. 3
      phonelibs/eigen/Eigen/src/Core/Dot.h
  99. 3
      phonelibs/eigen/Eigen/src/Core/EigenBase.h
  100. 3
      phonelibs/eigen/Eigen/src/Core/ForceAlignedAccess.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -16,7 +16,7 @@ Steps to reproduce the behavior, or a explorer/cabana link to the exact drive an
**Expected behavior**
A clear and concise description of what you expected to happen.
** Device/Version information (please complete the following information):**
**Device/Version information (please complete the following information):**
- Device: [e.g. EON/EON Gold]
- Version: [e.g. 0.6.4], or commit hash when on devel
- Car make/model [e.g. Toyota Prius 2016]

12
.gitignore vendored

@ -15,7 +15,9 @@ a.out
.*.swp
.*.swo
.*.un~
*.tmp
*.o
*.os
*.so
*.a
*.clb
@ -30,18 +32,22 @@ selfdrive/boardd/boardd
selfdrive/logcatd/logcatd
selfdrive/mapd/default_speeds_by_region.json
selfdrive/proclogd/proclogd
selfdrive/ui/ui
selfdrive/ui/_ui
selfdrive/test/longitudinal_maneuvers/out
selfdrive/visiond/visiond
selfdrive/loggerd/loggerd
selfdrive/sensord/gpsd
selfdrive/sensord/sensord
selfdrive/sensord/_gpsd
selfdrive/sensord/_sensord
selfdrive/camerad/camerad
selfdrive/modeld/_modeld
selfdrive/modeld/_monitoringd
/src/
one
openpilot
notebooks
xx
panda_jungle
.coverage*
htmlcov

@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y \
libeigen3-dev \
libffi-dev \
libglew-dev \
libgles2-mesa-dev \
libglib2.0-0 \
liblzma-dev \
libmysqlclient-dev \
@ -23,7 +24,7 @@ RUN apt-get update && apt-get install -y \
libopencv-dev \
libssl-dev \
libtool \
libusb-1.0-0 \
libusb-1.0-0-dev \
libzmq5-dev \
locales \
ocl-icd-libopencl1 \
@ -63,7 +64,7 @@ RUN pip install matplotlib==3.1.1 dictdiffer==0.8.0 fastcluster==1.1.25 aenum==2
COPY phonelibs/install_capnp.sh /tmp/install_capnp.sh
RUN /tmp/install_capnp.sh
RUN git clone --branch v0.6.5 https://github.com/commaai/openpilot-tools.git /tmp/openpilot/tools
RUN git clone --branch v0.7 https://github.com/commaai/openpilot-tools.git /tmp/openpilot/tools
ENV PYTHONPATH /tmp/openpilot:${PYTHONPATH}
COPY ./.pylintrc /tmp/openpilot/.pylintrc
@ -75,6 +76,7 @@ COPY ./phonelibs /tmp/openpilot/phonelibs
COPY ./pyextra /tmp/openpilot/pyextra
COPY ./panda /tmp/openpilot/panda
COPY SConstruct /tmp/openpilot/SConstruct
RUN mkdir -p /tmp/openpilot/selfdrive/test/out
RUN make -C /tmp/openpilot/selfdrive/controls/lib/longitudinal_mpc clean
RUN make -C /tmp/openpilot/selfdrive/controls/lib/lateral_mpc clean
RUN cd /tmp/openpilot && scons -j$(nproc)

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c6eff576ba07fc45d0257241e024075ac4e3d6c3391ed75d496f140d146e72b
size 2535
oid sha256:5e6997ef9a2f37fb6783d0b41c6d85b8c275e916f0e66dcbd8b1050461892852
size 2599

4
Pipfile.lock generated

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eeb5d8af1db839a0bf1a594af50c52d0d79dc6e764569819dc8e78dbb039090c
size 159193
oid sha256:67e035ae5f7a07977f9839dcff6ff49189f5742e2e2e92977b2cfc0e041189df
size 168833

@ -4,14 +4,14 @@ Table of Contents
=======================
* [What is openpilot?](#what-is-openpilot)
* [Integration with Stock Features](#integration-with-stock-features)
* [Supported Hardware](#supported-hardware)
* [Supported Cars](#supported-cars)
* [Community Maintained Cars and Features](#community-maintained-cars-and-features)
* [Installation Instructions](#installation-instructions)
* [Limitations of openpilot ALC](#limitations-of-openpilot-alc)
* [Limitations of openpilot ACC](#limitations-of-openpilot-acc)
* [Limitations of openpilot ALC and LDW](#limitations-of-openpilot-alc-and-ldw)
* [Limitations of openpilot ACC and FCW](#limitations-of-openpilot-acc-and-fcw)
* [Limitations of openpilot DM](#limitations-of-openpilot-dm)
* [Integration with Stock Features](#integration-with-stock-features)
* [User Data and comma Account](#user-data-and-comma-account)
* [Safety and Testing](#safety-and-testing)
* [Testing on PC](#testing-on-pc)
@ -24,7 +24,7 @@ Table of Contents
What is openpilot?
------
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC) and Automated Lane Centering (ALC) for a growing variety of supported [car makes, models and model years](#supported-cars). In addition, while openpilot is engaged, a camera based Driver Monitoring (DM) feature alerts distracted or asleep drivers.
[openpilot](http://github.com/commaai/openpilot) is an open source driver assistance system. Currently, openpilot performs the functions of Adaptive Cruise Control (ACC), Automated Lane Centering (ALC), Forward Collision Warning (FCW) and Lane Departure Warning (LDW) for a growing variety of supported [car makes, models and model years](#supported-cars). In addition, while openpilot is engaged, a camera based Driver Monitoring (DM) feature alerts distracted and asleep drivers.
<table>
<tr>
@ -41,6 +41,19 @@ What is openpilot?
</tr>
</table>
Integration with Stock Features
------
In all supported cars:
* Stock Lane Keep Assist (LKA) and stock ALC are replaced by openpilot ALC, which only functions when openpilot is engaged by the user.
* Stock LDW is replaced by openpilot LDW.
Additionally, on specific supported cars (see ACC column in [supported cars](#supported-cars)):
* Stock ACC is replaced by openpilot ACC.
* openpilot FCW operates in addition to stock FCW.
openpilot should preserve all other vehicle's stock features, including, but are not limited to: FCW, Automatic Emergency Braking (AEB), auto high-beam, blind spot warning, and side collision warning.
Supported Hardware
------
@ -49,87 +62,87 @@ At the moment, openpilot supports the [EON DevKit](https://comma.ai/shop/product
Supported Cars
------
| Make | Model (US Market Reference) | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below |
| ----------| -----------------------------------| ------------------| --------| -----------------| -----------------| ---------------|
| Acura | ILX 2016-18 | AcuraWatch Plus | Yes | Yes | 25mph<sup>6</sup>| 25mph |
| Acura | RDX 2016-18 | AcuraWatch Plus | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Chrysler | Pacifica 2017-18<sup>1</sup> | Adaptive Cruise | Yes | Stock | 0mph | 9mph |
| Chrysler | Pacifica Hybrid 2017-18<sup>1</sup>| Adaptive Cruise | Yes | Stock | 0mph | 9mph |
| Chrysler | Pacifica Hybrid 2019<sup>1</sup> | Adaptive Cruise | Yes | Stock | 0mph | 39mph |
| Honda | Accord 2018-19 | All | Yes | Stock | 0mph | 3mph |
| Honda | Accord Hybrid 2018-19 | All | Yes | Stock | 0mph | 3mph |
| Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | Yes | Yes | 0mph | 12mph |
| Honda | Civic Sedan/Coupe 2019 | Honda Sensing | Yes | Stock | 0mph | 2mph |
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Honda | CR-V 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Yes | Stock | 0mph | 12mph |
| Honda | Fit 2018-19 | Honda Sensing | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Honda | Odyssey 2018-20 | Honda Sensing | Yes | Yes | 25mph<sup>6</sup>| 0mph |
| Honda | Passport 2019 | All | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Honda | Pilot 2016-18 | Honda Sensing | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Honda | Pilot 2019 | All | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Honda | Ridgeline 2017-19 | Honda Sensing | Yes | Yes | 25mph<sup>6</sup>| 12mph |
| Hyundai | Santa Fe 2019<sup>2</sup> | All | Yes | Stock | 0mph | 0mph |
| Hyundai | Elantra 2017-19<sup>2</sup> | SCC + LKAS | Yes | Stock | 19mph | 34mph |
| Hyundai | Genesis 2018<sup>2</sup> | All | Yes | Stock | 19mph | 34mph |
| Jeep | Grand Cherokee 2016-18<sup>1</sup> | Adaptive Cruise | Yes | Stock | 0mph | 9mph |
| Jeep | Grand Cherokee 2019<sup>1</sup> | Adaptive Cruise | Yes | Stock | 0mph | 39mph |
| Kia | Optima 2019<sup>2</sup> | SCC + LKAS | Yes | Stock | 0mph | 0mph |
| Kia | Sorento 2018<sup>2</sup> | All | Yes | Stock | 0mph | 0mph |
| Kia | Stinger 2018<sup>2</sup> | SCC + LKAS | Yes | Stock | 0mph | 0mph |
| Lexus | CT Hybrid 2017-18 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Lexus | ES Hybrid 2019 | All | Yes | Yes | 0mph | 0mph |
| Lexus | RX Hybrid 2016-19 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Lexus | IS 2017-2019 | All | Yes | Stock | 22mph | 0mph |
| Lexus | IS Hybrid 2017 | All | Yes | Stock | 0mph | 0mph |
| Subaru | Crosstrek 2018-19 | EyeSight | Yes | Stock | 0mph | 0mph |
| Subaru | Impreza 2019-20 | EyeSight | Yes | Stock | 0mph | 0mph |
| Toyota | Avalon 2016 | TSS-P | Yes | Stock<sup>5</sup>| 20mph<sup>6</sup>| 0mph |
| Toyota | Avalon 2017-18 | All | Yes | Stock<sup>5</sup>| 20mph<sup>6</sup>| 0mph |
| Toyota | Camry 2018-19 | All | Yes | Stock | 0mph<sup>3</sup> | 0mph |
| Toyota | Camry Hybrid 2018-19 | All | Yes | Stock | 0mph<sup>3</sup> | 0mph |
| Toyota | C-HR 2017-19 | All | Yes | Stock | 0mph | 0mph |
| Toyota | C-HR Hybrid 2017-19 | All | Yes | Stock | 0mph | 0mph |
| Toyota | Corolla 2017-19 | All | Yes | Stock<sup>5</sup>| 20mph<sup>6</sup>| 0mph |
| Toyota | Corolla 2020 | All | Yes | Yes | 0mph | 0mph |
| Toyota | Corolla Hatchback 2019 | All | Yes | Yes | 0mph | 0mph |
| Toyota | Corolla Hybrid 2020 | All | Yes | Yes | 0mph | 0mph |
| Toyota | Highlander 2017-19 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Highlander Hybrid 2017-19 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius 2016 | TSS-P | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius 2017-19 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius Prime 2017-20 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Rav4 2016 | TSS-P | Yes | Stock<sup>5</sup>| 20mph<sup>6</sup>| 0mph |
| Toyota | Rav4 2017-18 | All | Yes | Stock<sup>5</sup>| 20mph<sup>6</sup>| 0mph |
| Toyota | Rav4 2019 | All | Yes | Yes | 0mph | 0mph |
| Toyota | Rav4 Hybrid 2016 | TSS-P | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Rav4 Hybrid 2017-18 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Sienna 2018 | All | Yes | Stock<sup>5</sup>| 0mph | 0mph |
| Volkswagen| Golf 2016-19<sup>4</sup> | Driver Assistance | Yes | Stock | 0mph | 0mph |
| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below |
| ----------| -----------------------------------| ------------------| -----------------| -------------------| -------------|
| Acura | ILX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>6</sup> | 25mph |
| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>6</sup> | 12mph |
| Chrysler | Pacifica 2017-18<sup>1</sup> | Adaptive Cruise | Stock | 0mph | 9mph |
| Chrysler | Pacifica Hybrid 2017-18<sup>1</sup>| Adaptive Cruise | Stock | 0mph | 9mph |
| Chrysler | Pacifica Hybrid 2019<sup>1</sup> | Adaptive Cruise | Stock | 0mph | 39mph |
| Honda | Accord 2018-19 | All | Stock | 0mph | 3mph |
| Honda | Accord Hybrid 2018-19 | All | Stock | 0mph | 3mph |
| Honda | Civic Sedan/Coupe 2016-18 | Honda Sensing | openpilot | 0mph | 12mph |
| Honda | Civic Sedan/Coupe 2019 | Honda Sensing | Stock | 0mph | 2mph |
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
| Honda | CR-V 2015-16 | Touring | openpilot | 25mph<sup>6</sup> | 12mph |
| Honda | CR-V 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Stock | 0mph | 12mph |
| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph<sup>6</sup> | 12mph |
| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph<sup>6</sup> | 0mph |
| Honda | Passport 2019 | All | openpilot | 25mph<sup>6</sup> | 12mph |
| Honda | Pilot 2016-18 | Honda Sensing | openpilot | 25mph<sup>6</sup> | 12mph |
| Honda | Pilot 2019 | All | openpilot | 25mph<sup>6</sup> | 12mph |
| Honda | Ridgeline 2017-19 | Honda Sensing | openpilot | 25mph<sup>6</sup> | 12mph |
| Hyundai | Santa Fe 2019<sup>2</sup> | All | Stock | 0mph | 0mph |
| Hyundai | Elantra 2017-19<sup>2</sup> | SCC + LKAS | Stock | 19mph | 34mph |
| Hyundai | Genesis 2018<sup>2</sup> | All | Stock | 19mph | 34mph |
| Jeep | Grand Cherokee 2016-18<sup>1</sup> | Adaptive Cruise | Stock | 0mph | 9mph |
| Jeep | Grand Cherokee 2019<sup>1</sup> | Adaptive Cruise | Stock | 0mph | 39mph |
| Kia | Optima 2019<sup>2</sup> | SCC + LKAS | Stock | 0mph | 0mph |
| Kia | Sorento 2018<sup>2</sup> | All | Stock | 0mph | 0mph |
| Kia | Stinger 2018<sup>2</sup> | SCC + LKAS | Stock | 0mph | 0mph |
| Lexus | CT Hybrid 2017-18 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Lexus | ES Hybrid 2019 | All | openpilot | 0mph | 0mph |
| Lexus | RX Hybrid 2016-19 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Lexus | IS 2017-2019 | All | Stock | 22mph | 0mph |
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
| Subaru | Impreza 2019-20 | EyeSight | Stock | 0mph | 0mph |
| Toyota | Avalon 2016 | TSS-P | Stock<sup>5</sup>| 20mph<sup>6</sup> | 0mph |
| Toyota | Avalon 2017-18 | All | Stock<sup>5</sup>| 20mph<sup>6</sup> | 0mph |
| Toyota | Camry 2018-19 | All | Stock | 0mph<sup>3</sup> | 0mph |
| Toyota | Camry Hybrid 2018-19 | All | Stock | 0mph<sup>3</sup> | 0mph |
| Toyota | C-HR 2017-19 | All | Stock | 0mph | 0mph |
| Toyota | C-HR Hybrid 2017-19 | All | Stock | 0mph | 0mph |
| Toyota | Corolla 2017-19 | All | Stock<sup>5</sup>| 20mph<sup>6</sup> | 0mph |
| Toyota | Corolla 2020 | All | openpilot | 0mph | 0mph |
| Toyota | Corolla Hatchback 2019 | All | openpilot | 0mph | 0mph |
| Toyota | Corolla Hybrid 2020 | All | openpilot | 0mph | 0mph |
| Toyota | Highlander 2017-19 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Highlander Hybrid 2017-19 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius 2016 | TSS-P | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius 2017-19 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Prius Prime 2017-20 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Rav4 2016 | TSS-P | Stock<sup>5</sup>| 20mph<sup>6</sup> | 0mph |
| Toyota | Rav4 2017-18 | All | Stock<sup>5</sup>| 20mph<sup>6</sup> | 0mph |
| Toyota | Rav4 2019 | All | openpilot | 0mph | 0mph |
| Toyota | Rav4 Hybrid 2016 | TSS-P | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Rav4 Hybrid 2017-18 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Toyota | Sienna 2018 | All | Stock<sup>5</sup>| 0mph | 0mph |
| Volkswagen| Golf 2016-19<sup>4</sup> | Driver Assistance | Stock | 0mph | 0mph |
<sup>1</sup>Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and [FCA giraffe](https://comma.ai/shop/products/giraffe) <br />
<sup>2</sup>Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai), designed for the 2019 Sante Fe; pinout may differ for other Hyundai and Kia models. <br />
<sup>2</sup>Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and open sourced [Hyundai giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai), designed for the 2019 Sante Fe; pinout may differ for other Hyundai and Kia models. <br />
<sup>3</sup>28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. <br />
<sup>4</sup>Requires a [custom connector](https://community.comma.ai/wiki/index.php/Volkswagen#Integration_at_R242_Camera) for the [car harness](https://comma.ai/shop/products/car-harness) <br />
Community Maintained Cars and Features
------
| Make | Model (US Market Reference) | Supported Package | Lateral | Longitudinal | No Accel Below | No Steer Below |
| ----------| -----------------------------------| ------------------| --------| -----------------| -----------------| ---------------|
| Buick | Regal 2018<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| Chevrolet | Malibu 2017<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| Chevrolet | Volt 2017-18<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| Cadillac | ATS 2018<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| GMC | Acadia Denali 2018<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| Holden | Astra 2017<sup>7</sup> | Adaptive Cruise | Yes | Yes | 0mph | 7mph |
| Make | Model (US Market Reference) | Supported Package | ACC | No ACC accel below | No ALC below |
| ----------| -----------------------------------| ------------------| -----------------| -------------------| -------------|
| Buick | Regal 2018<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
| Chevrolet | Malibu 2017<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
| Chevrolet | Volt 2017-18<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
| Cadillac | ATS 2018<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
| GMC | Acadia Denali 2018<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
| Holden | Astra 2017<sup>7</sup> | Adaptive Cruise | openpilot | 0mph | 7mph |
<sup>5</sup>When disconnecting the Driver Support Unit (DSU), openpilot longitudinal control will replace stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota). ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).*** <br />
<sup>5</sup>When disconnecting the Driver Support Unit (DSU), openpilot ACC will replace stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota). ***NOTE: disconnecting the DSU disables Automatic Emergency Braking (AEB).*** <br />
<sup>6</sup>[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma](https://comma.ai).*** <br />
<sup>7</sup>Requires a [panda](https://comma.ai/shop/products/panda-obd-ii-dongle) and [community built giraffe](https://zoneos.com/volt/). ***NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).*** <br />
Community Maintained Cars and Features are not confirmed by comma to meet our [safety model](SAFETY.md). Be extra cautious using them.
Community Maintained Cars and Features are not verified by comma to meet our [safety model](SAFETY.md). Be extra cautious using them. They are only available after enabling the toggle in `Settings->Developer->Enable Community Features`.
Installation Instructions
------
@ -138,14 +151,16 @@ Install openpilot on a EON by entering ``https://openpilot.comma.ai`` during the
Follow this [video instructions](https://youtu.be/3nlkomHathI) to properly mount the EON on the windshield. Note: openpilot features an automatic pose calibration routine and openpilot performance should not be affected by small pitch and yaw misalignments caused by imprecise EON mounting.
Before placing the device on your windshield, check the state and local laws and ordinances where you drive. Some state laws prohibit or restrict the placement of objects on the windshield of a motor vehicle.
You will be able to engage openpilot after reviewing the onboarding screens and finishing the calibration procedure.
Limitations of openpilot ALC
Limitations of openpilot ALC and LDW
------
openpilot Automated Lane Centering (ALC) does not automatically drive the vehicle or reduce the amount of attention that must be paid to operate your vehicle. The driver must always keep control of the steering wheel and be ready to correct the openpilot ALC action at all times.
openpilot ALC and openpilot LDW do not automatically drive the vehicle or reduce the amount of attention that must be paid to operate your vehicle. The driver must always keep control of the steering wheel and be ready to correct the openpilot ALC action at all times.
Many factors can impact the performance of openpilot ALC, causing it to be unable to function as intended. These include, but are not limited to:
Many factors can impact the performance of openpilot ALC and openpilot LDW, causing them to be unable to function as intended. These include, but are not limited to:
* Poor visibility (heavy rain, snow, fog, etc.) or weather conditions that may interfere with sensor operation.
* The road facing camera is obstructed, covered or damaged by mud, ice, snow, etc.
@ -160,12 +175,12 @@ Many factors can impact the performance of openpilot ALC, causing it to be unabl
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. It is the driver's responsibility to be in control of the vehicle at all times.
Limitations of openpilot ACC
Limitations of openpilot ACC and FCW
------
openpilot Adaptive Cruise Control (ACC) is not a system that allows careless or inattentive driving. It is still necessary for the driver to pay close attention to the vehicle’s surroundings and to be ready to re-take control of the gas and the brake at all times.
openpilot ACC and openpilot FCW are not systems that allow careless or inattentive driving. It is still necessary for the driver to pay close attention to the vehicle’s surroundings and to be ready to re-take control of the gas and the brake at all times.
Many factors can impact the performance of openpilot ACC, causing it to be unable to function as intended. These include, but are not limited to:
Many factors can impact the performance of openpilot ACC and openpilot FCW, causing them to be unable to function as intended. These include, but are not limited to:
* Poor visibility (heavy rain, snow, fog, etc.) or weather conditions that may interfere with sensor operation.
* The road facing camera or radar are obstructed, covered, or damaged by mud, ice, snow, etc.
@ -185,37 +200,29 @@ Many factors can impact the performance of openpilot ACC, causing it to be unabl
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. It is the driver's responsibility to be in control of the vehicle at all times.
Limitation of openpilot DM
Limitations of openpilot DM
------
openpilot Driver Monitoring (DM) should not be considered an exact measurements of the status of alertness of the driver.
openpilot DM should not be considered an exact measurements of the status of alertness of the driver.
Many factors can impact the performance of openpilot DM, causing it to be unable to function as intended. These include, but are not limited to:
* Low light conditions, such as driving at night or in dark tunnels.
* Bright light (due to oncoming headlights, direct sunlight, etc.).
* The driver face is partially or completely outside field of view of the the driver facing camera.
* The driver face is partially or completely outside field of view of the driver facing camera.
* Right hand driving vehicles.
* The driver facing camera is obstructed, covered, or damaged.
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. A fatigued or impared driver should not rely on openpilot DM to asses his level of attention.
Integration with Stock Features
------
Lane Departure Warning (LDW), Lane Keep Assist (LKAS), and Automated Lane Centering (ALC) are replaced by openpilot ALC, which only functions when openpilot is engaged.
Adaptive Cruise Control (ACC) is replaced by openpilot ACC.
openpilot preserves all other vehicle's stock features, including, but are not limited to: AEB, auto high-beam, blind spot warning, and side collision warning.
The list above does not represent an exhaustive list of situations that may interfere with proper operation of openpilot components. A driver should not rely on openpilot DM to assess their level of attention.
User Data and comma Account
------
By default, openpilot uploads the driving data to our servers. You can also access your data by pairing with the comma connect app ([iOS](https://apps.apple.com/us/app/comma-connect/id1456551889), [android](https://play.google.com/store/apps/details?id=ai.comma.connect&hl=en_US)). We use your data to train better models and improve openpilot for everyone.
By default, openpilot uploads the driving data to our servers. You can also access your data by pairing with the comma connect app ([iOS](https://apps.apple.com/us/app/comma-connect/id1456551889), [Android](https://play.google.com/store/apps/details?id=ai.comma.connect&hl=en_US)). We use your data to train better models and improve openpilot for everyone.
openpilot is open source software: the user is free to disable data collection if they wish to do so.
It logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
openpilot logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
The driver facing camera is only logged if you explicitly opt-in in settings. The microphone is not recorded.
By using openpilot, you agree to [our Privacy Policy](https://my.comma.ai/privacy). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma for the use of this data.

@ -1,36 +0,0 @@
Welcome to chffrplus
======
[chffrplus](https://github.com/commaai/chffrplus) is an open source dashcam.
This is the shipping reference software for the comma EON Dashcam DevKit. It keeps many of the niceities of [openpilot](https://github.com/commaai/openpilot), like high quality sensors, great camera, and good autostart and stop. Though unlike openpilot, it cannot control your car. chffrplus can interface with your car through a [panda](https://shop.comma.ai/products/panda-obd-ii-dongle), but just like our dashcam app [chffr](https://getchffr.com/), it is read only.
It integrates with the rest of the comma ecosystem, so you can view your drives on the [chffr](https://getchffr.com/) app for Android or iOS, and reverse engineer your car with [cabana](https://community.comma.ai/cabana/?demo=1).
Hardware
------
Right now chffrplus supports the [EON Dashcam DevKit](https://shop.comma.ai/products/eon-dashcam-devkit) for hardware to run on.
Install chffrplus on a EON device by entering ``https://chffrplus.comma.ai`` during NEOS setup.
User Data / chffr Account / Crash Reporting
------
By default chffrplus creates an account and includes a client for chffr, our dashcam app.
It's open source software, so you are free to disable it if you wish.
It logs the road facing camera, CAN, GPS, IMU, magnetometer, thermal sensors, crashes, and operating system logs.
It does not log the user facing camera or the microphone.
By using it, you agree to [our privacy policy](https://beta.comma.ai/privacy.html). You understand that use of this software or its related services will generate certain types of user data, which may be logged and stored at the sole discretion of comma.ai. By accepting this agreement, you grant an irrevocable, perpetual, worldwide right to comma.ai for the use of this data.
Licensing
------
chffrplus is released under the MIT license.

@ -1,3 +1,18 @@
Version 0.7 (2019-12-13)
========================
* Move to SCons build system!
* Add Lane Departure Warning (LDW) for all supported vehicles!
* NEOS update: increase wifi speed thanks to jyoung8607!
* Adaptive driver monitoring based on scene
* New driving model trained end-to-end: improve lane lines and lead detection
* Smarter torque limit alerts for all cars
* Improve GM longitudinal control: proper computations for 15Hz radar
* Move GM port, Toyota with DSU removed, comma pedal in community features; toggle switch required
* Remove upload over cellular toggle: only upload qlog and qcamera files if not on wifi
* Refactor Panda code towards ISO26262 and SIL2 compliancy
* Forward stock FCW for Honda Nidec
* Volkswagen port now standard: comma Harness intercepts stock camera
Version 0.6.6 (2019-11-05)
========================
* Volkswagen support thanks to jyoung8607!

@ -0,0 +1,212 @@
import os
import subprocess
import sys
AddOption('--test',
action='store_true',
help='build test files')
AddOption('--asan',
action='store_true',
help='turn on ASAN')
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
if arch == "aarch64":
lenv = {
"LD_LIBRARY_PATH": '/data/data/com.termux/files/usr/lib',
"PATH": os.environ['PATH'],
"ANDROID_DATA": os.environ['ANDROID_DATA'],
"ANDROID_ROOT": os.environ['ANDROID_ROOT'],
}
cpppath = [
"#phonelibs/opencl/include",
]
libpath = [
"#phonelibs/snpe/aarch64-android-clang3.8",
"/usr/lib",
"/data/data/com.termux/files/usr/lib",
"/system/vendor/lib64",
"/system/comma/usr/lib",
"#phonelibs/yaml-cpp/lib",
"#phonelibs/nanovg",
"#phonelibs/libyuv/lib",
]
cflags = ["-DQCOM", "-mcpu=cortex-a57"]
cxxflags = ["-DQCOM", "-mcpu=cortex-a57"]
rpath = ["/system/vendor/lib64"]
else:
lenv = {
"PATH": "#external/bin:" + os.environ['PATH'],
}
cpppath = [
"#phonelibs/capnp-cpp/include",
"#phonelibs/capnp-c/include",
"#phonelibs/zmq/x64/include",
]
libpath = [
"#phonelibs/capnp-cpp/x64/lib",
"#phonelibs/capnp-c/x64/lib",
"#phonelibs/yaml-cpp/x64/lib",
"#phonelibs/snpe/x86_64-linux-clang",
"#phonelibs/zmq/x64/lib",
"#phonelibs/libyuv/x64/lib",
"#external/zmq/lib",
"#cereal",
"#selfdrive/common",
"/usr/lib",
"/usr/local/lib",
]
rpath = ["phonelibs/capnp-cpp/x64/lib",
"cereal",
"selfdrive/common"]
# allows shared libraries to work globally
rpath = [os.path.join(os.getcwd(), x) for x in rpath]
cflags = []
cxxflags = []
ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] if GetOption('asan') else []
ldflags_asan = ["-fsanitize=address"] if GetOption('asan') else []
# change pythonpath to this
lenv["PYTHONPATH"] = Dir("#").path
env = Environment(
ENV=lenv,
CCFLAGS=[
"-g",
"-fPIC",
"-O2",
"-Werror=implicit-function-declaration",
"-Werror=incompatible-pointer-types",
"-Werror=int-conversion",
"-Werror=return-type",
"-Werror=format-extra-args",
] + cflags + ccflags_asan,
CPPPATH=cpppath + [
"#",
"#selfdrive",
"#phonelibs/bzip2",
"#phonelibs/libyuv/include",
"#phonelibs/yaml-cpp/include",
"#phonelibs/openmax/include",
"#phonelibs/json/src",
"#phonelibs/json11",
"#phonelibs/eigen",
"#phonelibs/curl/include",
"#phonelibs/opencv/include",
"#phonelibs/libgralloc/include",
"#phonelibs/android_frameworks_native/include",
"#phonelibs/android_hardware_libhardware/include",
"#phonelibs/android_system_core/include",
"#phonelibs/linux/include",
"#phonelibs/snpe/include",
"#phonelibs/nanovg",
"#selfdrive/common",
"#selfdrive/camerad",
"#selfdrive/camerad/include",
"#selfdrive/loggerd/include",
"#selfdrive/modeld",
"#cereal/messaging",
"#cereal",
"#opendbc/can",
],
CC='clang',
CXX='clang++',
LINKFLAGS=ldflags_asan,
RPATH=rpath,
CFLAGS=["-std=gnu11"] + cflags,
CXXFLAGS=["-std=c++14"] + cxxflags,
LIBPATH=libpath +
[
"#cereal",
"#selfdrive/common",
"#phonelibs",
]
)
if os.environ.get('SCONS_CACHE'):
CacheDir('/tmp/scons_cache')
node_interval = 5
node_count = 0
def progress_function(node):
global node_count
node_count += node_interval
sys.stderr.write("progress: %d\n" % node_count)
if os.environ.get('SCONS_PROGRESS'):
Progress(progress_function, interval=node_interval)
SHARED = False
def abspath(x):
if arch == 'aarch64':
pth = os.path.join("/data/pythonpath", x[0].path)
env.Depends(pth, x)
return File(pth)
else:
# rpath works elsewhere
return x[0].path.rsplit("/", 1)[1][:-3]
#zmq = 'zmq'
# still needed for apks
zmq = FindFile("libzmq.a", libpath)
Export('env', 'arch', 'zmq', 'SHARED')
# cereal and messaging are shared with the system
SConscript(['cereal/SConscript'])
if SHARED:
cereal = abspath([File('cereal/libcereal_shared.so')])
messaging = abspath([File('cereal/libmessaging_shared.so')])
else:
cereal = [File('#cereal/libcereal.a')]
messaging = [File('#cereal/libmessaging.a')]
Export('cereal', 'messaging')
SConscript(['selfdrive/common/SConscript'])
Import('_common', '_visionipc', '_gpucommon', '_gpu_libs')
if SHARED:
common, visionipc, gpucommon = abspath(common), abspath(visionipc), abspath(gpucommon)
else:
common = [_common, 'json']
visionipc = _visionipc
gpucommon = [_gpucommon] + _gpu_libs
Export('common', 'visionipc', 'gpucommon')
SConscript(['opendbc/can/SConscript'])
SConscript(['common/SConscript'])
SConscript(['common/kalman/SConscript'])
SConscript(['phonelibs/SConscript'])
SConscript(['selfdrive/modeld/SConscript'])
SConscript(['selfdrive/camerad/SConscript'])
SConscript(['selfdrive/controls/lib/cluster/SConscript'])
SConscript(['selfdrive/controls/lib/lateral_mpc/SConscript'])
SConscript(['selfdrive/controls/lib/longitudinal_mpc/SConscript'])
SConscript(['selfdrive/boardd/SConscript'])
SConscript(['selfdrive/proclogd/SConscript'])
if arch == "aarch64":
SConscript(['selfdrive/logcatd/SConscript'])
SConscript(['selfdrive/ui/SConscript'])
SConscript(['selfdrive/sensord/SConscript'])
SConscript(['selfdrive/loggerd/SConscript'])
SConscript(['selfdrive/locationd/SConscript'])
# TODO: finish cereal, dbcbuilder, MPC

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1d3e4d7e9a84cb5a507137f1d57046649ffc000f2ff0bbd047438846f07d04d5
size 2616780
oid sha256:8b20fb584bc1cc3637e5cb58b6688e9e250bb7f9eacb8b6e0d50a890e79d7797
size 2848396

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:930595cab227f8288a5dafaa04d3e71c98166c55cf6399e25e46f51237f1ac98
size 17796274
oid sha256:7a35f3ee4353210c0cfe714653920c05c588fb40c6c62088f81cd02bfc7eb6d3
size 16150762

1
common/.gitignore vendored

@ -0,0 +1 @@
*.cpp

@ -0,0 +1,6 @@
Import('env')
# parser
env.Command(['common_pyx.so'],
['common_pyx_setup.py', 'clock.pyx'],
"cd common && python3 common_pyx_setup.py build_ext --inplace")

@ -0,0 +1,73 @@
import binascii
import itertools
import re
import struct
import subprocess
def getprop(key):
return subprocess.check_output(["getprop", key], encoding='utf8').strip()
def get_imei():
ret = getprop("oem.device.imeicache")
if ret == "":
ret = "000000000000000"
return ret
def get_serial():
return getprop("ro.serialno")
def get_subscriber_info():
ret = parse_service_call_string(["iphonesubinfo", "7"])
if ret is None or len(ret) < 8:
return ""
return ret
def reboot(reason=None):
if reason is None:
reason_args = ["null"]
else:
reason_args = ["s16", reason]
subprocess.check_output([
"service", "call", "power", "16", # IPowerManager.reboot
"i32", "0", # no confirmation,
*reason_args,
"i32", "1" # wait
])
def parse_service_call_unpack(call, fmt):
r = parse_service_call_bytes(call)
try:
return struct.unpack(fmt, r)[0]
except Exception:
return None
def parse_service_call_string(call):
r = parse_service_call_bytes(call)
try:
r = r[8:] # Cut off length field
r = r.decode('utf_16_be')
# All pairs of two characters seem to be swapped. Not sure why
result = ""
for a, b, in itertools.zip_longest(r[::2], r[1::2], fillvalue='\x00'):
result += b + a
result = result.replace('\x00', '')
return result
except Exception:
return None
def parse_service_call_bytes(call):
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
if 'Parcel' not in ret:
return None
try:
r = b""
for hex_part in re.findall(r'[ (]([0-9a-f]{8})', ret):
r += binascii.unhexlify(hex_part)
return r
except Exception:
return None

@ -0,0 +1,98 @@
import os
import subprocess
import glob
import hashlib
import shutil
from common.basedir import BASEDIR
from selfdrive.swaglog import cloudlog
android_packages = ("ai.comma.plus.offroad", "ai.comma.plus.frame")
def get_installed_apks():
dat = subprocess.check_output(["pm", "list", "packages", "-f"], encoding='utf8').strip().split("\n")
ret = {}
for x in dat:
if x.startswith("package:"):
v,k = x.split("package:")[1].split("=")
ret[k] = v
return ret
def install_apk(path):
# can only install from world readable path
install_path = "/sdcard/%s" % os.path.basename(path)
shutil.copyfile(path, install_path)
ret = subprocess.call(["pm", "install", "-r", install_path])
os.remove(install_path)
return ret == 0
def start_frame():
set_package_permissions()
system("am start -n ai.comma.plus.frame/.MainActivity")
def set_package_permissions():
pm_grant("ai.comma.plus.offroad", "android.permission.ACCESS_FINE_LOCATION")
appops_set("ai.comma.plus.offroad", "SU", "allow")
appops_set("ai.comma.plus.offroad", "WIFI_SCAN", "allow")
appops_set("ai.comma.plus.offroad", "READ_EXTERNAL_STORAGE", "allow")
appops_set("ai.comma.plus.offroad", "WRITE_EXTERNAL_STORAGE", "allow")
def appops_set(package, op, mode):
system(f"LD_LIBRARY_PATH= appops set {package} {op} {mode}")
def pm_grant(package, permission):
system(f"pm grant {package} {permission}")
def system(cmd):
try:
cloudlog.info("running %s" % cmd)
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError as e:
cloudlog.event("running failed",
cmd=e.cmd,
output=e.output[-1024:],
returncode=e.returncode)
# *** external functions ***
def update_apks():
# install apks
installed = get_installed_apks()
install_apks = glob.glob(os.path.join(BASEDIR, "apk/*.apk"))
for apk in install_apks:
app = os.path.basename(apk)[:-4]
if app not in installed:
installed[app] = None
cloudlog.info("installed apks %s" % (str(installed), ))
for app in installed.keys():
apk_path = os.path.join(BASEDIR, "apk/"+app+".apk")
if not os.path.exists(apk_path):
continue
h1 = hashlib.sha1(open(apk_path, 'rb').read()).hexdigest()
h2 = None
if installed[app] is not None:
h2 = hashlib.sha1(open(installed[app], 'rb').read()).hexdigest()
cloudlog.info("comparing version of %s %s vs %s" % (app, h1, h2))
if h2 is None or h1 != h2:
cloudlog.info("installing %s" % app)
success = install_apk(apk_path)
if not success:
cloudlog.info("needing to uninstall %s" % app)
system("pm uninstall %s" % app)
success = install_apk(apk_path)
assert success
def pm_apply_packages(cmd):
for p in android_packages:
system("pm %s %s" % (cmd, p))
if __name__ == "__main__":
update_apks()

@ -0,0 +1,20 @@
from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module
from Cython.Build import cythonize
from common.cython_hacks import BuildExtWithoutPlatformSuffix
sourcefiles = ['clock.pyx']
extra_compile_args = ["-std=c++11"]
setup(name='Common',
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
ext_modules=cythonize(
Extension(
"common_pyx",
language="c++",
sources=sourcefiles,
extra_compile_args=extra_compile_args,
)
),
nthreads=4,
)

@ -1,276 +0,0 @@
import re
import os
import struct
import sys
import numbers
from collections import namedtuple, defaultdict
def int_or_float(s):
# return number, trying to maintain int format
if s.isdigit():
return int(s, 10)
else:
return float(s)
DBCSignal = namedtuple(
"DBCSignal", ["name", "start_bit", "size", "is_little_endian", "is_signed",
"factor", "offset", "tmin", "tmax", "units"])
class dbc():
def __init__(self, fn):
self.name, _ = os.path.splitext(os.path.basename(fn))
with open(fn, encoding="ascii") as f:
self.txt = f.readlines()
self._warned_addresses = set()
# regexps from https://github.com/ebroecker/canmatrix/blob/master/canmatrix/importdbc.py
bo_regexp = re.compile(r"^BO\_ (\w+) (\w+) *: (\w+) (\w+)")
sg_regexp = re.compile(r"^SG\_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
sgm_regexp = re.compile(r"^SG\_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)")
val_regexp = re.compile(r"VAL\_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*)")
# A dictionary which maps message ids to tuples ((name, size), signals).
# name is the ASCII name of the message.
# size is the size of the message in bytes.
# signals is a list signals contained in the message.
# signals is a list of DBCSignal in order of increasing start_bit.
self.msgs = {}
# A dictionary which maps message ids to a list of tuples (signal name, definition value pairs)
self.def_vals = defaultdict(list)
# lookup to bit reverse each byte
self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in range(64)]
for l in self.txt:
l = l.strip()
if l.startswith("BO_ "):
# new group
dat = bo_regexp.match(l)
if dat is None:
print("bad BO {0}".format(l))
name = dat.group(2)
size = int(dat.group(3))
ids = int(dat.group(1), 0) # could be hex
if ids in self.msgs:
sys.exit("Duplicate address detected %d %s" % (ids, self.name))
self.msgs[ids] = ((name, size), [])
if l.startswith("SG_ "):
# new signal
dat = sg_regexp.match(l)
go = 0
if dat is None:
dat = sgm_regexp.match(l)
go = 1
if dat is None:
print("bad SG {0}".format(l))
sgname = dat.group(1)
start_bit = int(dat.group(go+2))
signal_size = int(dat.group(go+3))
is_little_endian = int(dat.group(go+4))==1
is_signed = dat.group(go+5)=='-'
factor = int_or_float(dat.group(go+6))
offset = int_or_float(dat.group(go+7))
tmin = int_or_float(dat.group(go+8))
tmax = int_or_float(dat.group(go+9))
units = dat.group(go+10)
self.msgs[ids][1].append(
DBCSignal(sgname, start_bit, signal_size, is_little_endian,
is_signed, factor, offset, tmin, tmax, units))
if l.startswith("VAL_ "):
# new signal value/definition
dat = val_regexp.match(l)
if dat is None:
print("bad VAL {0}".format(l))
ids = int(dat.group(1), 0) # could be hex
sgname = dat.group(2)
defvals = dat.group(3)
defvals = defvals.replace("?",r"\?") #escape sequence in C++
defvals = defvals.split('"')[:-1]
# convert strings to UPPER_CASE_WITH_UNDERSCORES
defvals[1::2] = [d.strip().upper().replace(" ","_") for d in defvals[1::2]]
defvals = '"'+"".join(str(i) for i in defvals)+'"'
self.def_vals[ids].append((sgname, defvals))
for msg in self.msgs.values():
msg[1].sort(key=lambda x: x.start_bit)
self.msg_name_to_address = {}
for address, m in self.msgs.items():
name = m[0][0]
self.msg_name_to_address[name] = address
def lookup_msg_id(self, msg_id):
if not isinstance(msg_id, numbers.Number):
msg_id = self.msg_name_to_address[msg_id]
return msg_id
def reverse_bytes(self, x):
return ((x & 0xff00000000000000) >> 56) | \
((x & 0x00ff000000000000) >> 40) | \
((x & 0x0000ff0000000000) >> 24) | \
((x & 0x000000ff00000000) >> 8) | \
((x & 0x00000000ff000000) << 8) | \
((x & 0x0000000000ff0000) << 24) | \
((x & 0x000000000000ff00) << 40) | \
((x & 0x00000000000000ff) << 56)
def encode(self, msg_id, dd):
"""Encode a CAN message using the dbc.
Inputs:
msg_id: The message ID.
dd: A dictionary mapping signal name to signal data.
"""
msg_id = self.lookup_msg_id(msg_id)
msg_def = self.msgs[msg_id]
size = msg_def[0][1]
result = 0
for s in msg_def[1]:
ival = dd.get(s.name)
if ival is not None:
ival = (ival / s.factor) - s.offset
ival = int(round(ival))
if s.is_signed and ival < 0:
ival = (1 << s.size) + ival
if s.is_little_endian:
shift = s.start_bit
else:
b1 = (s.start_bit // 8) * 8 + (-s.start_bit - 1) % 8
shift = 64 - (b1 + s.size)
mask = ((1 << s.size) - 1) << shift
dat = (ival & ((1 << s.size) - 1)) << shift
if s.is_little_endian:
mask = self.reverse_bytes(mask)
dat = self.reverse_bytes(dat)
result &= ~mask
result |= dat
result = struct.pack('>Q', result)
return result[:size]
def decode(self, x, arr=None, debug=False):
"""Decode a CAN message using the dbc.
Inputs:
x: A collection with elements (address, time, data), where address is
the CAN address, time is the bus time, and data is the CAN data as a
hex string.
arr: Optional list of signals which should be decoded and returned.
debug: True to print debugging statements.
Returns:
A tuple (name, data), where name is the name of the CAN message and data
is the decoded result. If arr is None, data is a dict of properties.
Otherwise data is a list of the same length as arr.
Returns (None, None) if the message could not be decoded.
"""
if arr is None:
out = {}
else:
out = [None]*len(arr)
msg = self.msgs.get(x[0])
if msg is None:
if x[0] not in self._warned_addresses:
#print("WARNING: Unknown message address {}".format(x[0]))
self._warned_addresses.add(x[0])
return None, None
name = msg[0][0]
if debug:
print(name)
st = x[2].ljust(8, b'\x00')
le, be = None, None
for s in msg[1]:
if arr is not None and s[0] not in arr:
continue
start_bit = s[1]
signal_size = s[2]
little_endian = s[3]
signed = s[4]
factor = s[5]
offset = s[6]
if little_endian:
if le is None:
le = struct.unpack("<Q", st)[0]
tmp = le
shift_amount = start_bit
else:
if be is None:
be = struct.unpack(">Q", st)[0]
tmp = be
b1 = (start_bit // 8) * 8 + (-start_bit - 1) % 8
shift_amount = 64 - (b1 + signal_size)
if shift_amount < 0:
continue
tmp = (tmp >> shift_amount) & ((1 << signal_size) - 1)
if signed and (tmp >> (signal_size - 1)):
tmp -= (1 << signal_size)
tmp = tmp * factor + offset
# if debug:
# print("%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], tmp, s[-1]))
if arr is None:
out[s[0]] = tmp
else:
out[arr.index(s[0])] = tmp
return name, out
def get_signals(self, msg):
msg = self.lookup_msg_id(msg)
return [sgs.name for sgs in self.msgs[msg][1]]
if __name__ == "__main__":
from opendbc import DBC_PATH
import numpy as np
dbc_test = dbc(os.path.join(DBC_PATH, 'toyota_prius_2017_pt_generated.dbc'))
msg = ('STEER_ANGLE_SENSOR', {'STEER_ANGLE': -6.0, 'STEER_RATE': 4, 'STEER_FRACTION': -0.2})
encoded = dbc_test.encode(*msg)
decoded = dbc_test.decode((0x25, 0, encoded))
assert decoded == msg
dbc_test = dbc(os.path.join(DBC_PATH, 'hyundai_santa_fe_2019_ccan.dbc'))
decoded = dbc_test.decode((0x2b0, 0, "\xfa\xfe\x00\x07\x12"))
assert np.isclose(decoded[1]['SAS_Angle'], -26.2)
msg = ('SAS11', {'SAS_Stat': 7.0, 'MsgCount': 0.0, 'SAS_Angle': -26.200000000000003, 'SAS_Speed': 0.0, 'CheckSum': 0.0})
encoded = dbc_test.encode(*msg)
decoded = dbc_test.decode((0x2b0, 0, encoded))
assert decoded == msg

@ -1,10 +0,0 @@
all: simple_kalman_impl.so
simple_kalman_impl.so: simple_kalman_impl.pyx simple_kalman_impl.pxd simple_kalman_setup.py
python3 simple_kalman_setup.py build_ext --inplace
rm -rf build
rm simple_kalman_impl.c
.PHONY: clean
clean:
rm -f simple_kalman_impl.so

@ -0,0 +1,6 @@
Import('env')
env.Command(['simple_kalman_impl.so'],
['simple_kalman_impl.pyx', 'simple_kalman_impl.pxd', 'simple_kalman_setup.py'],
"cd common/kalman && python3 simple_kalman_setup.py build_ext --inplace")

@ -1,9 +1,3 @@
# pylint: skip-file
import os
import subprocess
kalman_dir = os.path.dirname(os.path.abspath(__file__))
subprocess.check_call(["make", "simple_kalman_impl.so"], cwd=kalman_dir)
from .simple_kalman_impl import KF1D as KF1D
from common.kalman.simple_kalman_impl import KF1D as KF1D
assert KF1D

@ -1,4 +1,4 @@
from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module
from distutils.core import Extension, setup
from Cython.Build import cythonize

@ -55,6 +55,7 @@ keys = {
"CalibrationParams": [TxType.PERSISTENT],
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CommunityFeaturesToggle": [TxType.PERSISTENT],
"CompletedTrainingVersion": [TxType.PERSISTENT],
"ControlsParams": [TxType.PERSISTENT],
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
@ -65,12 +66,13 @@ keys = {
"GithubSshKeys": [TxType.PERSISTENT],
"HasAcceptedTerms": [TxType.PERSISTENT],
"HasCompletedSetup": [TxType.PERSISTENT],
"IsLdwEnabled": [TxType.PERSISTENT],
"IsGeofenceEnabled": [TxType.PERSISTENT],
"IsMetric": [TxType.PERSISTENT],
"IsRHD": [TxType.PERSISTENT],
"IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
"IsUpdateAvailable": [TxType.PERSISTENT],
"IsUploadRawEnabled": [TxType.PERSISTENT],
"IsUploadVideoOverCellularEnabled": [TxType.PERSISTENT],
"LastUpdateTime": [TxType.PERSISTENT],
"LimitSetSpeed": [TxType.PERSISTENT],
"LimitSetSpeedNeural": [TxType.PERSISTENT],
@ -95,6 +97,7 @@ keys = {
"Offroad_TemperatureTooHigh": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_PandaFirmwareMismatch": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"Offroad_InvalidTime": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
}

@ -6,20 +6,12 @@ import subprocess
import multiprocessing
from cffi import FFI
# Build and load cython module
import pyximport
installer = pyximport.install(inplace=True, build_dir='/tmp')
from common.clock import monotonic_time, sec_since_boot # pylint: disable=no-name-in-module, import-error
pyximport.uninstall(*installer)
assert monotonic_time
assert sec_since_boot
from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error
# time step for each process
DT_CTRL = 0.01 # controlsd
DT_PLAN = 0.05 # mpc
DT_MDL = 0.05 # model
DT_RDR = 0.05 # radar
DT_DMON = 0.1 # driver monitoring
DT_TRML = 0.5 # thermald and manager

@ -2,22 +2,46 @@ import os
import subprocess
from common.basedir import BASEDIR
class Spinner():
def __enter__(self):
def __init__(self):
self.spinner_proc = subprocess.Popen(["./spinner"],
stdin=subprocess.PIPE,
cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"),
close_fds=True)
def __enter__(self):
return self
def update(self, spinner_text):
self.spinner_proc.stdin.write(spinner_text.encode('utf8') + b"\n")
self.spinner_proc.stdin.flush()
def close(self):
if self.spinner_proc is not None:
self.spinner_proc.stdin.close()
self.spinner_proc.terminate()
self.spinner_proc = None
def __del__(self):
self.close()
def __exit__(self, type, value, traceback):
self.spinner_proc.stdin.close()
self.spinner_proc.terminate()
self.close()
class FakeSpinner():
def __init__(self):
pass
def __enter__(self):
return self
def update(self, _):
pass
def __exit__(self, type, value, traceback):
pass
if __name__ == "__main__":
@ -25,4 +49,5 @@ if __name__ == "__main__":
with Spinner() as s:
s.update("Spinner text")
time.sleep(5.0)
print("gone")
time.sleep(5.0)

@ -125,7 +125,7 @@ def img_from_device(pt_device):
#TODO please use generic img transform below
def rotate_img(img, eulers, crop=None, intrinsics=eon_intrinsics):
import cv2 # pylint: disable=no-name-in-module, import-error
import cv2 # pylint: disable=import-error
size = img.shape[:2]
rot = orient.rot_from_euler(eulers)
@ -183,7 +183,7 @@ def transform_img(base_img,
alpha=1.0,
beta=0,
blur=0):
import cv2 # pylint: disable=no-name-in-module, import-error
import cv2 # pylint: disable=import-error
cv2.setNumThreads(1)
if yuv:
@ -241,7 +241,7 @@ def transform_img(base_img,
def yuv_crop(frame, output_size, center=None):
# output_size in camera coordinates so u,v
# center in array coordinates so row, column
import cv2 # pylint: disable=no-name-in-module, import-error
import cv2 # pylint: disable=import-error
rgb = cv2.cvtColor(frame, cv2.COLOR_YUV2RGB_I420)
if not center:
center = (rgb.shape[0]/2, rgb.shape[1]/2)

@ -1,7 +1,7 @@
{
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-7a0117425bc4a6673958d265312994e124654a566228f3cec2f0f9bc8120a9ab.zip",
"ota_hash": "7a0117425bc4a6673958d265312994e124654a566228f3cec2f0f9bc8120a9ab",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-3dc234d868c29a3739f6ca3bd47b1c2d3c570d9f478b6849a4fada129ee4af76.img",
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-07df505453684371b6c22583ffbb74ee414fcd389a46ff369ffd1b6bac75414e.zip",
"ota_hash": "07df505453684371b6c22583ffbb74ee414fcd389a46ff369ffd1b6bac75414e",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-3a6f973295ded6e4ff5cfff3b12e19c80d3bf45e2e8dd8699da3fc25b23ed7c6.img",
"recovery_len": 15848748,
"recovery_hash": "3dc234d868c29a3739f6ca3bd47b1c2d3c570d9f478b6849a4fada129ee4af76"
"recovery_hash": "3a6f973295ded6e4ff5cfff3b12e19c80d3bf45e2e8dd8699da3fc25b23ed7c6"
}

@ -11,17 +11,14 @@ if [ -z "$PASSIVE" ]; then
fi
function launch {
# Wifi scan
wpa_cli IFNAME=wlan0 SCAN
# apply update
if [ "$(git rev-parse HEAD)" != "$(git rev-parse @{u})" ]; then
git reset --hard @{u} &&
git clean -xdf &&
# Touch all files on release2 after checkout to prevent rebuild
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" == "release2" ]]; then
touch **
fi
exec "${BASH_SOURCE[0]}"
fi
@ -40,7 +37,7 @@ function launch {
fi
# Check for NEOS update
if [ $(< /VERSION) != "12" ]; then
if [ $(< /VERSION) != "13" ]; then
if [ -f "$DIR/scripts/continue.sh" ]; then
cp "$DIR/scripts/continue.sh" "/data/data/com.termux/files/continue.sh"
fi
@ -51,7 +48,7 @@ function launch {
# handle pythonpath
ln -s /data/openpilot /data/pythonpath
ln -sfn $(pwd) /data/pythonpath
export PYTHONPATH="$PWD"
# start manager

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28d88850097f33d58fac5ed95d41c8336fdc054832f97ce3937e56e29e4796bb
size 16950543
oid sha256:53948734c96a5aee45fcaed9fd6191056328ed3467dcd3d40d25f310d38c2297
size 15207664

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e6ea68609a1477fb55e27b066af5c65f343b930eaf8ade38d91df68ec594c5a7
size 158713

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f6305c44138a387e1757ed30a9bb6487d35c8919d0ae258998acb0e74b584e1
size 186615

Binary file not shown.

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5934a6cb5c1dd3031adb8eccee3c6419c7c966882c02dd978e772130c8f397e
size 446

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:888d6979bad138089fa6e8f720e5b61a47f2892f746438a5731853464ea02938
size 9280

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4f877e5ae4672568ef82cfd0023e2cef4a7cf55d867ab249efc9569a7eb9e5b1
size 1516

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ceb4b9ee5adedde47b31e975c1d90c73ad27b6b165a1dcd80c7c545eb65b903
size 35147

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc626520dcd53a22f727af3ee42c770e56c97a64fe3adb063799d8ab032fe551
size 26530

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f5b330efdad110cdd84d585ec61220b0650461fa599e36b13e1726c9346dcfb9
size 2246

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85
size 16726

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c83230b770f17ef1386ea1fd3681271dd98aa93646bdbfb5bff3a1b7050fff9d
size 779

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e99debb6c24423664cf610d53fab092eeab1ec23076b966476ddfe73af120202
size 694

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:acfe8307dc7a4732359166d24c39f3dec6a63f1534f010557851cf54b342fad8
size 1129

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:26f0d1bd0677785394f1f4eb2cddf763423f703c0941b3e58373e955b0130327
size 1900

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:80114769016320aac2e10fe4f80aa264ae63d5c98dc15913092ab01cee8c9956
size 17361

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5325c9d4d693e504ee012c5275ad4b10b135a701cbd87c14466d2ea21ea22ee5
size 122

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b0473b5d7c0cd9311d4a90548162e8cf160904476871f7fb749e9624e9b3dfd1
size 35

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a4d5cac960365e774da86d73410c4091d982fdc7ff7e63360e19b19985f1c18b
size 1763

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:31e95666fedc8e0a421f5c0e213d0916eae85ca4b427512ee124a0d717671a49
size 2050

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fae2c45c354729a373934f5104602458dbb38b3b6e61f58ef5b156b7babab749
size 874

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:84ffa38ac1ef3be005bff500b78b529c1e164fc50637836ff8648fea127b74f7
size 2083

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c48a6074e2e65b3648dd8671574a74cee253d8e2b94866f5410f124a55589232
size 939

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ca8ab01c365777a73a7ca80de3f0a27a174d423ac5ae41e8f3face19ae38fc5f
size 1374

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e46d51d3065962408a403480f2c9cad4e7d61fb509c1e4a695274751274969a2
size 991

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9a298753f1bc00c6591cf3d8faf2053ac9b0c8d362e71ba2136504ca8cbd8d9e
size 2483

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:11485398858b54ffc195cc51d31543fc65fea79a8cd901ef95da405ce790e370
size 1676

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:50ec5003df399fabf518620e220f71c717ff3a03a7218b8650a974dc3ad06b15
size 1116

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a63a1d392e01ca8f1dda6573c37a4566ee10b39402df38a2463bc4415193d5ef
size 1258

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6e8424527e5f68f1ddefe36a892908600601b1e68c4a2735ff256e9c038aa259
size 940

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4fa2d73b998c0794682d63dffbfff795bea41a7d18665840b1c357e66ff1c89d
size 1162

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7e30c5ec54f305c75f16bb3f92204de44599126fd1d756baf94675a8f7a6b800
size 1570

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fb92e4b1c0b85d3e9292d064b1b1700bf1d488d4905c64aa23b9e40feda75478
size 919

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7fefd6f6aa714052d1a67ef9f598d47bdfa2e21f237c820c4c0e37d013b49229
size 1371

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2323c1e3179dfc6abf348161b78c1bf5ecd0caa8f452c70caca9a1cdfdd6a6ae
size 2240

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cf9296fbb3c7d68329013fdc7464e1d696d1aeae9c778d9e06d370d108fad9a2
size 1713

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9756bad84167491b44d9990613ea2e889857eeb54ffca50d590410846f5c67d2
size 1222

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c1885167a447825ab7c35573422c3efa23dec62f5b630ac322ffe658e0ee5242
size 797

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:03540e297ae96ed03e828d9a433bb7f5a5e93aa83c6f50a6c271c78f9283d667
size 726

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7e8b1060757a1140298ff3905df70edb59ad1083f505681df30dc9dc9963d8ab
size 803

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8aa601f3fa1e6bfc03b799666bf39ebc42d44917a5fb2aaa489beafd63901f72
size 2243

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:003d41fa08cde68b1c4698499fa9bf9c803cebb27ae748615851519f42dc56ac
size 1382

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8747c66f7ea0535fa3a3944554ac1395499be9d63b1cd2341163e5a4de96fce5
size 24254

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:faf39aa4957943b68e735a3f7905a0461daaeefd36594ba44e8e40960b15cc7a
size 17834

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1efc3720834ec96ba0df4a0622aa20c3a80ae48d90d60cfaad5e0bf9c1cfa04b
size 3974

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eec5b84c2c576530670fe2607d8979811025eef44eedbca03f56bbbdc777f9ae
size 22307

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9639ee6c3918b5dfacd9db51169972a9cfd654266ecb0ad6ff5159b69a785660
size 11944

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8b0df9645c11e3aa3479ea789f0ff8c34e993631c6b7bde6a130d98af30f6eb7
size 8107

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fa56fc43ceede869132d9e9d6e925468d4605c193ad435e5f20b9f52920cdb0d
size 6571

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3dfc6a05fef83bb7743f3d45e8028cccdff4010a5d516396c6087a45529e694e
size 2720

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:648105b4058d1abc31843792cacd208061fd8e79c6f896bea62820bc52a289ae
size 38120

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f965654d06dc2888bcb098b50eff171b0f3697cda6a432c1da7f6cc13ded862
size 12221

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bcad8b0d59a56e9f3d4f39ee6396e27cf4143d24fbd24c91fab7e03c7415c564
size 13910

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:551858019e0ae5a66ef5638036f18124c18033b3cfe04ba7c4c934d15ebbc747
size 18064

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1f6b1837c81ba9056b1c73e91723282b5fd6103a38218013411d057272b2e27
size 4249

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e21f93bef2476ffc5362644cfc669b24f94da5cf44870e2c140ffdfb93e76d59
size 5689

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5d44345e7ccf669ba2b343f09ce32c08cd8ed04f2c40dc9a0de88daee5f83041
size 6970

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4a20c03255610ed4c885231e39c9419d359161343b673511ba1640b86791727d
size 61293

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9aa4f2f822089d478d0ae3277716c204e3035a6bd0edd50cf3942f99342c7f91
size 4525

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c3a41fbda9a5c2af43a627468d4e66fdac13fc9586867a233d22e1bd764d47d
size 7593

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5531aa255cf9e26963fac152b8692ebb4b29219049ab080edd8ae8e0e5157c92
size 30704

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:97d9e03c73e1a101352d8b00ee191013b6b6acf00e90c887dd54bea4551de7be
size 8256

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:16a8224c1758e79ca01692110137ee5cfeccdf8018020571569d1102cf0e5616
size 3877

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:140671a011363e16bc49eca3c9ffc808f9fcf7569e45f8580d320e2023d2037c
size 5282

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3e51c22c1080077da6f2256c3edea062464a1c93bebe7518a8dd77bc7aa746e2
size 27367

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5e7f54eddcb464a1863e5bfb1b1060bbede58cdca60a720a3244d46844252b03
size 24212

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0f42190688b6a803a9094344c729c9c220939274e38f0c69ecd28702965b1a8b
size 21959

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b876cccf1671adf2dbb2149961d4bc28fcdc5f152d55df952611611976e8d0d4
size 9507

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e3cdb9bedbf570b230d8f19f3cfbb58f3342e6fc4407bb0ea24397ca094fb6c0
size 12666

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:14712906425a63d11c226826ed588553756a055bb8c72a73788eadc23c3320d8
size 970

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:611b37c1cad422d5c0e152cc0812405816196dd80fc52513879786fac5a43662
size 11392

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a88d0ccb46e1c902a4fa66f4be3ad20aa76eb2a1b784a1b3e4c25dfdc85e1853
size 5540

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:179a8ebf0fdba78414a9e01b130db5fbf78dc5d1c7fd48c5d49dcc7ccca4aaff
size 4769

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save