Compare commits

...

96 Commits

Author SHA1 Message Date
DevTekVE a233c3949c Enable verbose Git logging in push-changes workflow step
Add `GIT_TRACE=2` and `GIT_CURL_VERBOSE=1` to enhance Git command logging during the push-changes step. This provides detailed trace and curl debugging information for troubleshooting CI/CD issues.
2025-03-06 15:34:26 +01:00
DevTekVE 7ddaf52b2b CI: adjust allow 1 retry for first time contributor and fork and skip sync lfs on fork PRs (#647)
* Update workflow condition to skip forked PRs during sync

This change ensures the LFS maintenance workflow does not run for pull requests originating from forked repositories. It enhances efficiency by avoiding unnecessary sync actions in these cases.

* Modified retry conditions in GitHub workflow file

Adjusted the retry conditions in the GitHub workflow setup file. The updated condition allows for a second attempt if the pull request originator is a 'FIRST_TIME_CONTRIBUTOR' from a forked repository. This modification lends more flexibility to first-time contributors by providing them with an additional chance to pass the tests.

* test

* test2

* test3

* Fix conditional logic for retry check in workflow script

The condition now correctly checks if the pull request is not from a fork using 'false' instead of 'true'. This ensures proper validation of retry attempts based on the contributor and repository source.

* Fix placement of event JSON logging in workflow script

Moved the `toJSON(github.event)` logging statement to ensure it runs after retry logic validation. This improves the logical flow of the script and maintains appropriate debugging output.

* Add debug logs for PR metadata and run attempt values

This change introduces debug logs to output key PR metadata, such as fork status, author association, and the GitHub run attempt value. These logs will aid in debugging and provide better visibility into workflow execution.

* Add debug log for PR fork and author association check

This change adds a debug log to display the evaluation of the fork and author association condition in the workflow. It helps in troubleshooting PR handling logic and ensures better visibility into the condition being assessed.

* Fix logical negation for fork checks in workflow script

Correct the evaluation of fork status using proper negation syntax. This ensures accurate logic in pull request conditions, improving the reliability of the workflow execution.

* Add log for first-time contributor check in workflow

This adds a debug statement to log whether the PR author is a first-time contributor. It helps improve observability and makes it easier to debug workflows involving author associations.

* Simplify log output in GitHub action script

Removed unnecessary debug echo statements to streamline the script and improve readability. Retained essential logic to handle retries and enforce restrictions on test flakiness.

* Simplify retry logic for pull request contributors.

Updated the condition to correctly identify and handle retries for first-time contributors and forked repositories. This ensures a clearer and more accurate retry policy in the workflow.

* Refine workflow conditions for PR checks and retries

Adjusted conditional logic in `lfs-maintenance.yaml` to improve readability and ensure proper handling of draft PRs. Updated retry logic in `setup/action.yaml` to reflect correct author association for stricter validations.
2025-03-06 15:02:29 +01:00
DevTekVE a51ed062ca CI: allow 1 retry for first time contributor and fork and skip sync lfs on fork PRs (#646)
* Update workflow condition to skip forked PRs during sync

This change ensures the LFS maintenance workflow does not run for pull requests originating from forked repositories. It enhances efficiency by avoiding unnecessary sync actions in these cases.

* Modified retry conditions in GitHub workflow file

Adjusted the retry conditions in the GitHub workflow setup file. The updated condition allows for a second attempt if the pull request originator is a 'FIRST_TIME_CONTRIBUTOR' from a forked repository. This modification lends more flexibility to first-time contributors by providing them with an additional chance to pass the tests.
2025-03-06 10:24:14 +01:00
DevTekVE 17d292c773 CI: Protecting /release/ci with CODEOWNERS 2025-03-06 09:38:58 +01:00
DevTekVE 8c3f8064b2 Uploading codeowners (#645) 2025-03-06 09:34:33 +01:00
DevTekVE b791d4ed55 Model: Handle missing 'sim_pose' gracefully in model outputs. (#644)
Handle missing 'sim_pose' gracefully in model outputs.

Check for the presence of 'sim_pose' in output data before processing. If absent, fallback to using 'plan' data to populate temporal pose fields, ensuring robustness and preventing potential runtime errors.
2025-03-02 20:52:44 +01:00
DevTekVE 1a8dd310ae Model: split modeld into it's own contained modeld implementation (#642)
* Add support for TinyGrad model runner processing

Introduced a new function `is_tinygrad_model` to detect TinyGrad as an active model runner. Updated the `is_stock_model` logic to account for TinyGrad models and added a new process entry for TinyGrad in the model manager. This enables handling TinyGrad models alongside existing configurations.

adding modeld back

Add support for `modeld_v2` and update paths for consistency

Updated `SConscript` files to integrate `modeld_v2` alongside `modeld` and adjusted script paths for correct metadata handling. Adjusted various configurations and scripts, such as `labeler.yaml` and `build_release.sh`, to include `modeld_v2` and ensure cohesive project structure.

Refactor imports to use updated `modeld_v2` paths.

Replaced outdated `modeld` references with their `modeld_v2` counterparts for consistency and clarity across the codebase. Also updated `.gitignore` to accommodate new directory structure. This change ensures better maintainability and alignment with the new directory schema.

Refactor and reorganize modeld to sunnypilot/modeld_v2 structure.

Moved and renamed `modeld` components to the new `sunnypilot/modeld_v2` directory for better organization and modularity. Updated imports and file references to align with the new structure, ensuring compatibility and functionality. Streamlined project structure to improve maintainability and future development.

* typo

* Use `stock` model runner and refactor model checks.

Replaces outdated model detection logic with unified `stock` runner integration, simplifying the decision flow for model selection. Includes `stock` as a new enum in the `Runner` type and updates affected references accordingly.

* Handle missing 'sim_pose' in model outputs gracefully.

Added conditional checks to ensure the code handles cases where 'sim_pose' is absent in the model outputs. Fallback behaviors use 'plan' data when 'sim_pose' is unavailable, preventing potential errors and enhancing robustness.
2025-03-02 20:49:30 +01:00
DevTekVE cce0f14976 CI: Fix runner install script (#639)
Not sure why it stopped working before but this should work now
2025-03-01 15:29:31 +01:00
Jason Wen d5aa4ba997 Sync: commaai/openpilot:master into sunnypilot/sunnypilot:master-new (#635) 2025-02-17 00:07:06 -05:00
Jason Wen 564914c3a4 test_processes: update ref logs to a0a1635 2025-02-16 23:43:51 -05:00
Jason Wen a0a1635c55 Merge branch 'upstream/openpilot/master' into sync-20250215
# Conflicts:
#	common/params.cc
#	opendbc_repo
#	panda
#	selfdrive/car/tests/test_models.py
#	selfdrive/modeld/fill_model_msg.py
#	selfdrive/test/process_replay/process_replay.py
#	selfdrive/test/process_replay/ref_commit
#	selfdrive/ui/qt/offroad/developer_panel.cc
#	selfdrive/ui/tests/test_ui/run.py
#	selfdrive/ui/translations/main_ar.ts
#	selfdrive/ui/translations/main_de.ts
#	selfdrive/ui/translations/main_es.ts
#	selfdrive/ui/translations/main_fr.ts
#	selfdrive/ui/translations/main_ja.ts
#	selfdrive/ui/translations/main_ko.ts
#	selfdrive/ui/translations/main_pt-BR.ts
#	selfdrive/ui/translations/main_th.ts
#	selfdrive/ui/translations/main_tr.ts
#	selfdrive/ui/translations/main_zh-CHS.ts
#	selfdrive/ui/translations/main_zh-CHT.ts
#	system/athena/athenad.py
2025-02-16 22:10:32 -05:00
Adeeb Shihadeh 917b45afd0 Remove EncodeIdx packets from qlog (#34590) 2025-02-15 15:17:58 -08:00
Adeeb Shihadeh e86dbb622d update release notes 2025-02-15 15:16:39 -08:00
Dean Lee ce7ff5c0e6 ui: Initial UI rewrite using pyray (spinner and text window) (#34583)
* pyray init version

* remove c++ code

* cleanup

* restruct the directory layout

* improve GuiApplication

* smooth out the texture after resize

* use atexit to close app

* rename FontSize->FontWeight

* make files executable

* use Inter Regular for FrontWeight.NORMAL

* set FLAG_VSYNC_HINT to avoid tearing while scrolling

* smoother scrolling

* mange textures in gui_app
2025-02-15 12:44:20 -08:00
Adeeb Shihadeh 958c8d1ce3 Beautiful camera timings (#34558)
* the start of something beautiful

* mv that

* cleanup

* cleanup output

* the good stuff

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-14 21:33:50 -08:00
Adeeb Shihadeh c4ee645fbc tici: move kgsl affinity to modeld core (#34588) 2025-02-14 19:35:43 -08:00
Kacper Rączy 032f3688a2 plotjuggler: opt-out log migration (#34587)
* Option to migrate logs if needed

* Opt-out migration

* Remove late import
2025-02-15 02:41:39 +00:00
Adeeb Shihadeh ec6c7cd152 adjust default can_replay route slice to work with test_onroad 2025-02-14 17:29:01 -08:00
Adeeb Shihadeh efda24dbe1 camerad: match some BPS settings (#34548)
* start common

* fix bayer pattern

* lil more

* all 1q10

* cc en

* same pts?

* this is weird

* some cleanup

* less

* off

* clean up

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-14 16:05:00 -08:00
Maxime Desroches 9ccfecb813 use PyPI wheel for raylib on PC (#34586)
* wheel

* build
2025-02-14 15:17:26 -08:00
Maxime Desroches 4b278fe14f Jenkins in a loop (#34582)
* loop

* better

* clean

* more

* fix
2025-02-13 19:21:45 -08:00
Adeeb Shihadeh d1b93287f2 camerad: flush BPS requests (#34581)
* repro

* cleanup

* flush bps

* cleanup

* revert that

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-13 19:19:56 -08:00
Harald Schäfer 77a442c4e8 Long planner: allow negative accel constraint (#34565)
* allow negative accel constraint

* dont let MPC do clipping

* Typo

* whitespace

* Fix tests

* More cruise accel

* rm print

* ref commit
2025-02-12 13:11:32 -08:00
Shane Smiskol d6a0e49def Move safety constants to opendbc (#34573)
* forgot these

* bump

* get these

* and flags

* fix

* bump

* test

* debug

* print sim thread errors
2025-02-11 21:48:20 -08:00
Adeeb Shihadeh d98a554b17 tici: set core affinity for all realtime processes (#34574) 2025-02-11 21:20:31 -08:00
Adeeb Shihadeh 3d097faec0 Revert "camerad: enable BPS (#34570)"
This reverts commit da2a5f4305.
2025-02-11 20:30:37 -08:00
Adeeb Shihadeh fbf918b311 test_onroad fixups (#34572)
* test_onroad fixpus

* fix
2025-02-11 20:15:30 -08:00
Adeeb Shihadeh 6ec5d82a29 tici: affine ICP IRQ to camerad core (#34571) 2025-02-11 19:20:35 -08:00
Adeeb Shihadeh da2a5f4305 camerad: enable BPS (#34570)
* camerad: enable BPS

* update power draw
2025-02-11 14:03:32 -08:00
Dean Lee 644130ca3d encoderd: use AV_CODEC_ID_H264 codec for qcamera encoding (#34498) 2025-02-11 12:46:43 +00:00
Dean Lee 3c0990e716 move thumbnail generation from camerad to encoderd (#34554)
Co-authored-by: Cameron Clough <cameronjclough@gmail.com>
2025-02-10 23:43:46 +00:00
Dean Lee 27c11eb597 athena upload: streaming file upload (#34559)
streaming file upload
2025-02-10 13:57:31 -08:00
commaci-public 4cca971888 [bot] Update Python packages (#34561)
Update Python packages

Co-authored-by: Vehicle Researcher <user@comma.ai>
2025-02-10 10:26:48 -08:00
Adeeb Shihadeh c4c43bebd2 Drop Ubuntu 20.04 support (#34557) 2025-02-09 13:41:11 -08:00
Dean Lee ad2b1edbd0 replay: flush codec buffers after seeking (#34556)
* flush codec buffers after seeking

* replace avio_seek with the higher-level avformat_seek_file

* exit early
2025-02-09 13:02:43 -08:00
Dean Lee 65e478f27f camerad: simplify buffer indexing in enqueue_req_multi (#34553)
simplify buffer indexing in enqueue_req_multi
2025-02-09 09:58:47 -08:00
Dean Lee 4b7a25efc3 loggerd: remove unused zlib and libswscale linkage (#34552)
remove unused link
2025-02-09 09:13:58 -08:00
Adeeb Shihadeh 1090af6e3d camerad: IFE register cleanup (#34550)
* start there

* lil more

* get camera num out of there

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-08 14:02:49 -08:00
Adeeb Shihadeh 22591dc6f8 op: simplify service restart (#34551) 2025-02-08 13:59:50 -08:00
Dean Lee 9ec54f59c6 loggerd: switch logging from raw file format to zstd compressed files (#34549)
* switch logging from raw file format to zstd compressed files

* more zst suffix

* compress bootlog

* remove class RawFile

* Optimize ZstdFileWriter by adding input caching

* use ZSTD_compressStream2

* cleanup

* LOG_COMPRESSION_LEVEL=10

* space

* add zst suffix to LOGS_SIZE_RATE
2025-02-08 12:55:31 -08:00
Adeeb Shihadeh 4066d49d70 camerad: debayer in the BPS (#33763)
* bps support

* cleanup with offsetof

* cleanup

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-07 19:28:50 -08:00
Shane Smiskol 8b67e04d7d test_models: remove cereal (#34547)
rm more
2025-02-07 16:16:50 -08:00
Shane Smiskol 092685cae7 test_models: use opendbc CanData (#34546)
* replace with non-messaging CanData

* clean up
2025-02-07 15:55:52 -08:00
Shane Smiskol b4a9c67bbe qcomgps: fix NameError on teardown (#34545)
continue teardown if diag not there
2025-02-07 14:06:02 -08:00
Shane Smiskol fb517b5bca Remove can_capnp_to_can_list (#34542)
* about equal with multiprocessing

* but almost half without ;)

* rm

* Update tools/replay/can_replay.py
2025-02-06 20:54:31 -08:00
Shane Smiskol 3c72f1aa42 can_list_to_can_capnp: use opendbc CanFrame 2025-02-06 20:23:25 -08:00
Adeeb Shihadeh 49f7cb835b agnos 11.7 (#34471)
* agnos 11.7

* new build

* new build

* new build

* nb

* raylib

---------

Co-authored-by: Maxime Desroches <desroches.maxime@gmail.com>
2025-02-06 19:22:40 -08:00
Shane Smiskol 65d7b86902 test_models: remove selfdrived dependency (#34539)
* remove selfdrived

* fully

* todo

* yay

* moremoremore

* clean up

* more

* don't care

* update refs

* bump to master

* no more selfdrived

* yup

* too complex

* Update selfdrive/car/tests/test_models.py

* Update selfdrive/car/tests/test_models.py
2025-02-06 19:17:01 -08:00
Shane Smiskol 151e5ba20f test_models: remove Params 2025-02-06 18:55:07 -08:00
Shane Smiskol 951631e1ab Remove brand-specific button logic from car_specific.py (#34540)
* yay

* moremoremore

* clean up

* more

* don't care

* update refs

* bump to master
2025-02-06 18:02:31 -08:00
Adeeb Shihadeh 5b870c6f92 camerad: simple BPS support (#34538)
* camerad: simple BPS support

* works

* cleanup

* lil more

---------

Co-authored-by: Comma Device <device@comma.ai>
2025-02-06 15:23:19 -08:00
Adeeb Shihadeh e31ae06959 camerad: remove AR register processing (#34537) 2025-02-06 14:15:37 -08:00
Adeeb Shihadeh 9bc35c0919 Revert "athena upload: reduce memory usage and improve efficiency with streaming (#34528)"
This reverts commit 4c65f51a55.
2025-02-06 11:50:04 -08:00
Maxime Desroches 61fa7e1ead raylib python bindings (#34534)
* build

* fix

* build

* wheel

* arm

* linux

* both
2025-02-05 15:35:06 -08:00
Shane Smiskol 40863aa988 card: default events (#34532)
default events
2025-02-04 20:26:47 -08:00
commaci-public ddc29430ec [bot] Update Python packages (#34530)
Update Python packages

Co-authored-by: Vehicle Researcher <user@comma.ai>
2025-02-04 20:02:11 -08:00
Dean Lee 4c65f51a55 athena upload: reduce memory usage and improve efficiency with streaming (#34528)
* reduce memory usage and improve upload efficiency with streaming

* space
2025-02-04 13:10:13 -08:00
Robbe Derks 12307dcb37 op auth command (#34529)
* auth command

* no python
2025-02-04 11:26:57 -08:00
Shane Smiskol 26f972b9f7 Bump opendbc (#34525)
* no debug param and new import

* bump

* bump to master

* and fix that

* oop

* bump to master
2025-02-03 21:05:23 -08:00
Maxime Desroches 9658fcbe79 Revert "unpin pyopenssl (#34522)" (#34524)
This reverts commit b1843ee7a7.
2025-02-03 11:37:27 -08:00
Maxime Desroches b1843ee7a7 unpin pyopenssl (#34522)
try
2025-02-03 10:28:54 -08:00
commaci-public ebe48552cf [bot] Update Python packages (#34520)
* Update Python packages

* fix

---------

Co-authored-by: Vehicle Researcher <user@comma.ai>
Co-authored-by: Maxime Desroches <desroches.maxime@gmail.com>
2025-02-03 10:22:52 -08:00
Adeeb Shihadeh 17647f99a4 setup: try removing uv update loop 2025-02-02 21:45:13 -08:00
Jason Wen bb407ae9bf MADS: mute canBusMissing if vehicle is in Park and enabled (#613)
* Car: mute `canBusMissing` if vehicle is in Park

* only when mads is enabled
2025-02-01 22:26:19 -05:00
Jason Wen d7087d312c MADS: Properly handle gear events (#628)
* MADS: Properly handle gear events

* use referenced object directly

* fix tests

* unused

* rename
2025-02-01 22:11:10 -05:00
Adeeb Shihadeh cc14903137 strip output on sudo_read 2025-02-01 12:48:04 -08:00
Jason Wen 17b3092e76 modeld: script to generate new default model hash and name (#629)
* modeld: script to generate new default model hash and name

* break CI intentionally to trigger new changes

* more verbose and fix

* more verbose hehe
2025-02-01 02:55:52 -05:00
Jason Wen 977b164dd3 Vehicle Selector (#619)
* QFrame

* symlink for OP

* symlink dat

* search with user input

* single list is fine

* bump opendbc

* set actual fingerprint

* more precision search

* different prompt in onroad/offroad

* confirm/cancel

* set while initializing

* tldr

* show demo car

* old qt

* need that param too

* use toList

* Need to be str

* Encoding

* generate `car.CarParams.brand` in json

* start cleanup

* generate no car docs platforms

* add brand to parser

* include all dashcamOnly platforms

* pass all fields to a platform in json

* introduce `getPlatformBundle`

* extract platform from CarPlatformBundle directly

* Fix name

* do not include dashcamOnly yet

* slight cleanup

* bump opendbc

* it's a json now

* split set platform

* move loadPlatformList to sp util

* add year list to bundle

* bros

* missed header

* invoke platform selector on show event
2025-02-01 00:55:09 -05:00
Adeeb Shihadeh 6d12a47d05 Revert "camerad: disable ISP for now (#34440)"
This reverts commit e48752d8fa.
2025-01-31 19:17:07 -08:00
Shane Smiskol e3d83b4b13 camerad: fix tearing when hitting frame timeout (#34514)
* this works

* todo
2025-01-31 17:14:58 -08:00
eFini 913337d98c update CHT/CHS translations (#34513)
updated CHT/CHS translations
2025-01-31 08:47:13 -08:00
Dean Lee 2b19b8f3d7 ui/DeveloperPanel: initialize offroad state, refresh toggle, and cleanup Includes (#34510)
small fixes
2025-01-30 22:56:14 -08:00
Adeeb Shihadeh a5dd2ab2aa athena: upload logs in parallel (#34509)
Co-authored-by: Comma Device <device@comma.ai>
2025-01-30 20:12:00 -08:00
programanichiro bfb898ef3f update ja translations (#34506)
* 見切れる部分の見直しと表現を調整。

* 和訳を追加。

* Improved truncation
見切れを改善。

* FIREHOSEモード!
2025-01-30 14:56:16 -08:00
Kacper Rączy a8b829167d locationd: use cloudlog (#34508)
* Use cloudlog instead of print

* Changes
2025-01-30 22:36:20 +00:00
Shane Smiskol 1e35a24564 fdcan: rate limit CAN core reset (#34507)
bump panda
2025-01-30 14:08:27 -08:00
Adeeb Shihadeh 5d421020c3 Revert "SConstruct: remove CPPPATH entries for libyuv and json11 (#34504)"
This reverts commit 7792fee92c.
2025-01-30 11:47:49 -08:00
Maxime Desroches c82af71e83 model_replay: raise max modelV2 exec time (#34505)
raise
2025-01-30 11:21:45 -08:00
Andrei Radulescu d4a7a87a3c third_party: raylib builds on macos (#34499)
* updated raylib setup for macos

* raylib setup.sh renamed to build.sh

* simplified copy

* silent curl
2025-01-30 10:34:29 -08:00
Dean Lee 804b801ef8 SConstruct: remove duplicate -lzmq link (#34503)
remove duplicate -lzmq link
2025-01-30 10:30:54 -08:00
Dean Lee 7792fee92c SConstruct: remove CPPPATH entries for libyuv and json11 (#34504)
cleanup cpppath
2025-01-30 10:30:40 -08:00
Alexandre Nobuharu Sato cdf46e340f update pt-BR translations (#34500) 2025-01-30 09:48:04 -08:00
Dean Lee a9956c0116 cleanup: remove SNPE paths from SConstruct (#34501)
remove SNPE paths from SConstruct
2025-01-30 07:37:00 -08:00
Adeeb Shihadeh 79e52ea83d FIREHOSE mode v0.1 (#34496)
* add toggle

* athena

* fix mypy
2025-01-29 15:31:15 -08:00
Robbe Derks bf4e9170c5 Add Tesla to car_specific events (#34493) 2025-01-29 10:41:38 -08:00
Robbe Derks 0a17b21321 bump panda again 2025-01-29 17:02:24 +01:00
Robbe Derks acfc44a490 bump panda 2025-01-29 16:53:43 +01:00
Dean Lee 227bb68e18 replay: improve segment loading and event handling (#34490)
improve segment Loading and Event Handling
2025-01-28 15:37:05 -08:00
YassineYousfi 2eb3585dae Not Too Shabby Model (#34484)
* b25c27a8-263b-4f3f-b1f8-72ac49b4f9c7/700

* replay

* model_replay: support empty
2025-01-28 12:16:13 -08:00
Adeeb Shihadeh 82722217be selfdrived: remove ignored process list (#34491) 2025-01-27 21:17:27 -08:00
Dean Lee e7b63dce65 encoderd: enhance robustness of open() with HANDLE_EINTR Macro (#34478)
HANDLE_EINTR
2025-01-27 19:46:43 -08:00
Shane Smiskol 1b1d37db65 Toyota: clip pitch for PERMIT_BRAKING (#34489)
bump
2025-01-27 17:13:40 -08:00
Mauricio Alvarez Leon 3eb02f1d54 ui-preview: fix keyboard screenshot (#34482)
* update to click keyboard SSH ADD

* Update run.py
2025-01-27 17:05:46 -08:00
BirdZhang 15211b2e52 Update to new USB VID (#34487)
https://github.com/commaai/panda/pull/2112/files
2025-01-27 14:01:59 -08:00
commaci-public ca11a18061 [bot] Update Python packages (#34486)
Update Python packages

Co-authored-by: Vehicle Researcher <user@comma.ai>
2025-01-27 10:01:50 -08:00
YassineYousfi 8bfce0979d modeld: use temporalPose from model (#34460)
* modeld: use temporalPose from model

* cleanup
2025-01-26 10:29:58 -08:00
298 changed files with 5864 additions and 1515 deletions
+3
View File
@@ -0,0 +1,3 @@
* @sunnypilot/dev-internal
/.github/ @devtekve @sunnyhaibin
/release/ci/ @devtekve @sunnyhaibin
+1 -1
View File
@@ -24,4 +24,4 @@ multilanguage:
autonomy:
- changed-files:
- any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit}"
- any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit,sunnypilot/modeld*/models/**}"
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
sync:
runs-on: ubuntu-latest
# Skip if PR is in draft mode
if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)
if: (github.event_name != 'pull_request' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)) && !github.event.pull_request.head.repo.fork
steps:
- name: Checkout Repository
uses: actions/checkout@v4
+1 -1
View File
@@ -322,7 +322,7 @@ jobs:
run: |
${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \
source selfdrive/test/setup_vsound.sh && \
CI=1 pytest tools/sim/tests/test_metadrive_bridge.py"
CI=1 pytest -s tools/sim/tests/test_metadrive_bridge.py"
create_ui_report:
# This job name needs to be the same as UI_JOB_NAME in ui_preview.yaml
+1 -1
View File
@@ -19,7 +19,7 @@ runs:
- shell: bash
name: No retries!
run: |
if [ "${{ github.run_attempt }}" -gt 1 ]; then
if [ "${{ github.run_attempt }}" -gt ${{ github.event.pull_request.head.repo.fork && github.event.pull_request.author_association == 'NONE' && 2 || 1}} ]; then
echo -e "\033[0;31m##################################################"
echo -e "\033[0;31m Retries not allowed! Fix the flaky test! "
echo -e "\033[0;31m##################################################\033[0m"
@@ -116,6 +116,8 @@ jobs:
- name: Push changes if there are diffs
id: push-changes # Add an id so we can reference this step
run: |
GIT_TRACE=2
GIT_CURL_VERBOSE=1
TARGET_BRANCH="${{ inputs.target_branch || env.DEFAULT_TARGET_BRANCH }}"
# Fetch the latest from remote
+3 -3
View File
@@ -74,9 +74,9 @@ comma*.sh
selfdrive/modeld/thneed/compile
selfdrive/modeld/models/*.thneed
selfdrive/modeld/models/*.pkl
sunnypilot/modeld/thneed/compile
sunnypilot/modeld/models/*.thneed
sunnypilot/modeld/models/*.pkl
sunnypilot/modeld*/thneed/compile
sunnypilot/modeld*/models/*.thneed
sunnypilot/modeld*/models/*.pkl
*.bz2
*.zst
Vendored
+2 -2
View File
@@ -103,7 +103,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
def diffPaths = args.diffPaths ?: []
def cmdTimeout = args.timeout ?: 9999
if (branch != "master" && diffPaths && !hasPathChanged(gitDiff, diffPaths)) {
if (branch != "master" && !branch.contains("__jenkins_loop_") && diffPaths && !hasPathChanged(gitDiff, diffPaths)) {
println "Skipping ${name}: no changes in ${diffPaths}."
return
} else {
@@ -170,7 +170,7 @@ node {
'testing-closet*', 'hotfix-*']
def excludeRegex = excludeBranches.join('|').replaceAll('\\*', '.*')
if (env.BRANCH_NAME != 'master') {
if (env.BRANCH_NAME != 'master' && !env.BRANCH_NAME.contains('__jenkins_loop_')) {
properties([
disableConcurrentBuilds(abortPrevious: true)
])
+13 -14
View File
@@ -1,23 +1,22 @@
Version 0.9.9 (2025-03-30)
Version 0.9.8 (2025-02-27)
========================
* New driving model
* Model now gates applying positive acceleration in Chill mode
* New driving monitoring model
* Reduced false positives related to passengers
* Image processing pipeline moved to the ISP
* More GPU time for bigger driving models
* Power draw reduced 0.5W, which means your device runs cooler
* Added toggle to enable driver monitoring even when openpilot is not engaged
* FIREHOSE mode
* Allows you to maximize your training data uploads to improve the models
* Enable openpilot longitudinal control for Ford Q3 vehicles
* New Toyota TSS2 longitudinal tune
* Coming soon
* Rivian support
* F-150 & Mach-E support
* Tesla Model 3 support
Version 0.9.8 (2025-01-30)
========================
* New driving monitoring model
* Reduced false positives related to passengers
* Image processing pipeline moved to the ISP
* More GPU time for driving models
* Power draw reduced 0.5W, which means your device runs cooler
* Added toggle to enable driver monitoring even when openpilot is not engaged
* Enable openpilot longitudinal control for Ford Q3 vehicles
* New Toyota TSS2 longitudinal tune
* Coming soon
* New driving model with gas gating
* Training data upload mode
Version 0.9.7 (2024-06-13)
========================
+1 -2
View File
@@ -361,7 +361,7 @@ SConscript(['opendbc_repo/SConscript'], exports={'env': env_swaglog})
SConscript(['cereal/SConscript'])
Import('socketmaster', 'msgq')
messaging = [socketmaster, msgq, 'zmq', 'capnp', 'kj',]
messaging = [socketmaster, msgq, 'capnp', 'kj',]
Export('messaging')
@@ -373,7 +373,6 @@ SConscript(['rednose/SConscript'])
# Build system services
SConscript([
'system/ui/SConscript',
'system/proclogd/SConscript',
'system/ubloxd/SConscript',
'system/loggerd/SConscript',
+1
View File
@@ -70,6 +70,7 @@ struct ModelManagerSP @0xaedffd8f31e7b55d {
enum Runner {
snpe @0;
tinygrad @1;
stock @2;
}
struct ModelBundle {
+4 -4
View File
@@ -29,7 +29,7 @@ _services: dict[str, tuple] = {
"pandaStates": (True, 10., 1),
"peripheralState": (True, 2., 1),
"radarState": (True, 20., 5),
"roadEncodeIdx": (False, 20., 1),
"roadEncodeIdx": (False, 20., 20),
"liveTracks": (True, 20.),
"sendcan": (True, 100., 139),
"logMessage": (True, 0.),
@@ -53,15 +53,15 @@ _services: dict[str, tuple] = {
"livePose": (True, 20., 4),
"liveParameters": (True, 20., 5),
"cameraOdometry": (True, 20., 10),
"thumbnail": (True, 0.2, 1),
"thumbnail": (True, 1 / 60., 1),
"onroadEvents": (True, 1., 1),
"carParams": (True, 0.02, 1),
"roadCameraState": (True, 20., 20),
"driverCameraState": (True, 20., 20),
"driverEncodeIdx": (False, 20., 1),
"driverEncodeIdx": (False, 20., 20),
"driverStateV2": (True, 20., 10),
"driverMonitoringState": (True, 20., 10),
"wideRoadEncodeIdx": (False, 20., 1),
"wideRoadEncodeIdx": (False, 20., 20),
"wideRoadCameraState": (True, 20., 20),
"drivingModelData": (True, 20., 10),
"modelV2": (True, 20.),
+21
View File
@@ -1,6 +1,10 @@
import io
import os
import tempfile
import contextlib
import zstandard as zstd
LOG_COMPRESSION_LEVEL = 10 # little benefit up to level 15. level ~17 is a small step change
class CallbackReader:
@@ -35,3 +39,20 @@ def atomic_write_in_dir(path: str, mode: str = 'w', buffering: int = -1, encodin
yield tmp_file
tmp_file_name = tmp_file.name
os.replace(tmp_file_name, path)
def get_upload_stream(filepath: str, should_compress: bool) -> tuple[io.BufferedIOBase, int]:
if not should_compress:
file_size = os.path.getsize(filepath)
file_stream = open(filepath, "rb")
return file_stream, file_size
# Compress the file on the fly
compressed_stream = io.BytesIO()
compressor = zstd.ZstdCompressor(level=LOG_COMPRESSION_LEVEL)
with open(filepath, "rb") as f:
compressor.copy_stream(f, compressed_stream)
compressed_size = compressed_stream.tell()
compressed_stream.seek(0)
return compressed_stream, compressed_size
+1 -1
View File
@@ -1 +1 @@
#define DEFAULT_MODEL "Notre Dame (Default)"
#define DEFAULT_MODEL "Not Too Shabby (Default)"
+2
View File
@@ -120,6 +120,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"ExperimentalLongitudinalEnabled", PERSISTENT | DEVELOPMENT_ONLY | BACKUP},
{"ExperimentalMode", PERSISTENT | BACKUP},
{"ExperimentalModeConfirmed", PERSISTENT | BACKUP},
{"FirehoseMode", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"FirmwareQueryDone", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"ForcePowerDown", PERSISTENT},
{"GitBranch", PERSISTENT},
@@ -206,6 +207,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CarParamsSP", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"CarParamsSPCache", CLEAR_ON_MANAGER_START},
{"CarParamsSPPersistent", PERSISTENT},
{"CarPlatformBundle", PERSISTENT},
{"EnableGithubRunner", PERSISTENT | BACKUP},
{"ModelRunnerTypeCache", CLEAR_ON_ONROAD_TRANSITION},
{"OffroadMode", CLEAR_ON_MANAGER_START},
+2 -6
View File
@@ -27,11 +27,6 @@ class Priority:
CTRL_HIGH = 53
def set_realtime_priority(level: int) -> None:
if not PC:
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level))
def set_core_affinity(cores: list[int]) -> None:
if not PC:
os.sched_setaffinity(0, cores)
@@ -39,7 +34,8 @@ def set_core_affinity(cores: list[int]) -> None:
def config_realtime_process(cores: int | list[int], priority: int) -> None:
gc.disable()
set_realtime_priority(priority)
if not PC:
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(priority))
c = cores if isinstance(cores, list) else [cores, ]
set_core_affinity(c)
+1
View File
@@ -19,6 +19,7 @@ collect_ignore = [
collect_ignore_glob = [
"selfdrive/debug/*.py",
"selfdrive/modeld/*.py",
"sunnypilot/modeld*/*.py",
]
+1 -1
View File
@@ -184,7 +184,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Lexus|RX Hybrid 2016|Lexus Safety System+|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2016">Buy Here</a></sub></details>||
|Lexus|RX Hybrid 2017-19|All|openpilot available[<sup>2</sup>](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2017-19">Buy Here</a></sub></details>||
|Lexus|RX Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=RX Hybrid 2020-22">Buy Here</a></sub></details>||
|Lexus|UX Hybrid 2019-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=UX Hybrid 2019-23">Buy Here</a></sub></details>||
|Lexus|UX Hybrid 2019-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=UX Hybrid 2019-24">Buy Here</a></sub></details>||
|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lincoln&model=Aviator 2020-24">Buy Here</a></sub></details>||
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lincoln&model=Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=MAN&model=eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
+1 -1
View File
@@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1
if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="11.6"
export AGNOS_VERSION="11.8"
fi
export STAGING_ROOT="/data/safe_staging"
+1 -1
Submodule panda updated: 4ca963345a...44a9806bfb
+1
View File
@@ -111,6 +111,7 @@ dev = [
"tabulate",
"types-requests",
"types-tabulate",
"raylib",
]
tools = [
+1
View File
@@ -75,6 +75,7 @@ find . -name 'moc_*' -delete
find . -name '__pycache__' -delete
rm -rf .sconsign.dblite Jenkinsfile release/
rm selfdrive/modeld/models/supercombo.onnx
rm sunnypilot/modeld*/models/supercombo.onnx
find third_party/ -name '*x86*' -exec rm -r {} +
find third_party/ -name '*Darwin*' -exec rm -r {} +
+23 -14
View File
@@ -67,8 +67,6 @@ trap remount_ro EXIT
setup_runner_user() {
sudo useradd --comment 'GitHub Runner' --create-home --home-dir ${BASE_DIR} ${RUNNER_USER} --shell /bin/bash -G ${USER_GROUPS} || sudo usermod -aG ${USER_GROUPS} ${RUNNER_USER}
export BASE_DIR
sudo -u ${RUNNER_USER} bash -c "truncate -s 0 '${BASE_DIR}/.bash_logout'"
}
create_sudoers_entry() {
@@ -77,8 +75,8 @@ create_sudoers_entry() {
set_directory_permissions() {
sudo chown -R ${RUNNER_USER}:comma "$BASE_DIR"
sudo chmod g+rwx "$BASE_DIR"
sudo chmod g+s "$BASE_DIR"
sudo chmod -R g+rwx "$BASE_DIR"
sudo find "$BASE_DIR" -type d -exec chmod g+s {} +
}
setup_directories() {
@@ -86,30 +84,42 @@ setup_directories() {
sudo mkdir -p "$RUNNER_DIR" "$BUILDS_DIR" "$LOGS_DIR" "$CACHE_DIR" "$OPENPILOT_DIR"
mkdir -p "/data/openpilot"
sudo chown -R comma:comma "/data/openpilot"
sync
}
wipe_bash_logout() {
export BASE_DIR
sudo -u ${RUNNER_USER} bash -c "touch ${BASE_DIR}/.bash_logout"
sudo -u ${RUNNER_USER} bash -c "truncate -s 0 '${BASE_DIR}/.bash_logout'"
}
# System configuration functions (depends on basic utility functions)
setup_system_configs() {
echo "Setting up system configurations..."
remount_rw
setup_runner_user
create_sudoers_entry
remount_ro
set_directory_permissions
wipe_bash_logout
}
# Runner setup functions
install_runner() {
echo "Downloading and setting up runner..."
cd "$RUNNER_DIR"
curl -o actions-runner-linux-arm64-2.321.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.321.0/actions-runner-linux-arm64-2.321.0.tar.gz
tar xzf ./actions-runner-linux-arm64-2.321.0.tar.gz
rm ./actions-runner-linux-arm64-2.321.0.tar.gz
chmod +x ./config.sh
curl -o actions-runner-linux-arm64-2.322.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.322.0/actions-runner-linux-arm64-2.322.0.tar.gz
sudo -u ${RUNNER_USER} tar -xzf ./actions-runner-linux-arm64-2.322.0.tar.gz
sudo rm ./actions-runner-linux-arm64-2.322.0.tar.gz
sudo chmod +x ./config.sh
}
configure_runner() {
remount_rw
echo "Configuring runner..."
cd "$RUNNER_DIR"
sudo -u ${RUNNER_USER} ./config.sh --url "$REPO_URL" --token "$GITHUB_TOKEN" --name $(hostname) --runnergroup "tici-tizi" --labels "tici" --work "$BUILDS_DIR" --unattended
remount_ro
}
create_service_template() {
@@ -139,6 +149,7 @@ EOL
}
install_service() {
remount_rw
echo "Installing systemd service..."
cd "$RUNNER_DIR"
sudo ./svc.sh install $RUNNER_USER
@@ -152,6 +163,7 @@ install_service() {
fi
sudo systemctl disable "${service_name}"
fi
remount_ro
}
check_restore_prerequisites() {
@@ -203,23 +215,20 @@ check_restore_prerequisites() {
perform_restore() {
echo "Starting runner restoration..."
setup_directories
remount_rw
setup_system_configs
install_service
remount_ro
echo "Runner restoration completed successfully"
}
perform_install() {
echo "Starting fresh installation..."
setup_directories
install_runner
create_service_template
remount_rw
setup_system_configs
install_runner
set_directory_permissions
create_service_template
configure_runner
install_service
remount_ro
echo "Installation completed successfully"
}
+145
View File
@@ -0,0 +1,145 @@
#!/usr/bin/env bash
set -e
YELLOW='\033[0;33m'
GREEN='\033[0;32m'
UNDERLINE='\033[4m'
BOLD='\033[1m'
NC='\033[0m'
BRANCH="master"
RUNS="20"
COOKIE_JAR=/tmp/cookies
CRUMB=$(curl -s --cookie-jar $COOKIE_JAR 'https://jenkins.comma.life/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
function loop() {
JENKINS_BRANCH="__jenkins_loop_${BRANCH}"
API_ROUTE="https://jenkins.comma.life/job/openpilot/job/$JENKINS_BRANCH"
for run in $(seq 1 $((RUNS / 2))); do
N=2
TEST_BUILDS=()
# Try to find previous builds
ALL_BUILDS=( $(curl -s $API_ROUTE/api/json | jq .builds.[].number 2> /dev/null || :) )
# No builds. Create branch
if [[ ${#ALL_BUILDS[@]} -eq 0 ]]; then
TEMP_DIR=$(mktemp -d)
GIT_LFS_SKIP_SMUDGE=1 git clone --quiet -b $BRANCH --depth=1 --no-tags git@github.com:commaai/openpilot $TEMP_DIR
git -C $TEMP_DIR checkout --quiet -b $JENKINS_BRANCH
echo "TESTING" >> $TEMP_DIR/testing_jenkins
git -C $TEMP_DIR add testing_jenkins
git -C $TEMP_DIR commit --quiet -m "testing"
git -C $TEMP_DIR push --quiet -f origin $JENKINS_BRANCH
rm -rf $TEMP_DIR
FIRST_BUILD=1
echo ''
echo 'waiting on Jenkins...'
echo ''
sleep 90
else
# Found some builds. Wait for them to end if they are still running
for i in ${ALL_BUILDS[@]}; do
running=$(curl -s $API_ROUTE/$i/api/json/ | jq .inProgress)
if [[ $running == "false" ]]; then
continue
fi
TEST_BUILDS=( ${ALL_BUILDS[@]} )
N=${#TEST_BUILDS[@]}
break
done
fi
# No running builds found
if [[ ${#TEST_BUILDS[@]} -eq 0 ]]; then
FIRST_BUILD=$(curl -s $API_ROUTE/api/json | jq .nextBuildNumber)
LAST_BUILD=$((FIRST_BUILD+N-1))
TEST_BUILDS=( $(seq $FIRST_BUILD $LAST_BUILD) )
# Start N new builds
for i in ${TEST_BUILDS[@]};
do
echo "Starting build $i"
curl -s --output /dev/null --cookie $COOKIE_JAR -H "$CRUMB" -X POST $API_ROUTE/build?delay=0sec
sleep 5
done
echo ""
fi
# Wait for all builds to end
while true; do
sleep 30
count=0
for i in ${TEST_BUILDS[@]};
do
RES=$(curl -s -w "\n%{http_code}" --cookie $COOKIE_JAR -H "$CRUMB" $API_ROUTE/$i/api/json)
HTTP_CODE=$(tail -n1 <<< "$RES")
JSON=$(sed '$ d' <<< "$RES")
if [[ $HTTP_CODE == "200" ]]; then
STILL_RUNNING=$(echo $JSON | jq .inProgress)
if [[ $STILL_RUNNING == "true" ]]; then
echo -e "Build $i: ${YELLOW}still running${NC}"
continue
else
count=$((count+1))
echo -e "Build $i: ${GREEN}done${NC}"
fi
else
echo "No status for build $i"
fi
done
echo "See live results: ${API_ROUTE}/buildTimeTrend"
echo ""
if [[ $count -ge $N ]]; then
break
fi
done
done
}
function usage() {
echo ""
echo "Run the Jenkins tests multiple times on a specific branch"
echo ""
echo -e "${BOLD}${UNDERLINE}Options:${NC}"
echo -e " ${BOLD}-n, --n${NC}"
echo -e " Specify how many runs to do (default to ${BOLD}20${NC})"
echo -e " ${BOLD}-b, --branch${NC}"
echo -e " Specify which branch to run the tests against (default to ${BOLD}master${NC})"
echo ""
}
function _looper() {
if [[ $# -eq 0 ]]; then
usage
exit 0
fi
# parse Options
while [[ $# -gt 0 ]]; do
case $1 in
-n | --n ) shift 1; RUNS="$1"; shift 1 ;;
-b | --b | --branch | -branch ) shift 1; BRANCH="$1"; shift 1 ;;
* ) usage; exit 0 ;;
esac
done
echo ""
echo -e "You are about to start $RUNS Jenkins builds against the $BRANCH branch."
echo -e "If you expect this to run overnight, ${UNDERLINE}${BOLD}unplug the cold reboot power switch${NC} from the testing closet before."
echo ""
read -p "Press (y/Y) to confirm: " choice
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
loop
fi
}
_looper $@
-1
View File
@@ -53,7 +53,6 @@ function run_tests() {
run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES
run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES
run "check_nomerge_comments" $DIR/check_nomerge_comments.sh $ALL_FILES
run "check_raylib_includes" $DIR/check_raylib_includes.sh $ALL_FILES
if [[ -z "$FAST" ]]; then
run "mypy" mypy $PYTHON_FILES
+7 -16
View File
@@ -45,9 +45,6 @@ class CarSpecificEvents:
if self.CP.brand in ('body', 'mock'):
events = Events()
elif self.CP.brand in ('subaru', 'mazda'):
events = self.create_common_events(CS, CS_prev)
elif self.CP.brand == 'ford':
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.manumatic])
@@ -102,13 +99,9 @@ class CarSpecificEvents:
events.add(EventName.manualRestart)
elif self.CP.brand == 'gm':
# The ECM allows enabling on falling edge of set, but only rising edge of resume
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.sport, GearShifter.low,
GearShifter.eco, GearShifter.manumatic],
pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,))
if not self.CP.pcmCruise:
if any(b.type == ButtonType.accelCruise and b.pressed for b in CS.buttonEvents):
events.add(EventName.buttonEnable)
pcm_enable=self.CP.pcmCruise)
# Enabling at a standstill with brake is allowed
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
@@ -122,8 +115,7 @@ class CarSpecificEvents:
elif self.CP.brand == 'volkswagen':
events = self.create_common_events(CS, CS_prev, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=self.CP.pcmCruise,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
pcm_enable=self.CP.pcmCruise)
# Low speed steer alert hysteresis logic
if (self.CP.minSteerSpeed - 1e-3) > VWCarControllerParams.DEFAULT_MIN_STEER_SPEED and CS.vEgo < (self.CP.minSteerSpeed + 1.):
@@ -160,12 +152,12 @@ class CarSpecificEvents:
events.add(EventName.belowSteerSpeed)
else:
raise ValueError(f"Unsupported car: {self.CP.brand}")
events = self.create_common_events(CS, CS_prev)
return events
def create_common_events(self, CS: structs.CarState, CS_prev: car.CarState, extra_gears=None, pcm_enable=True,
allow_enable=True, allow_button_cancel=True, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
allow_enable=True, allow_button_cancel=True):
events = Events()
if CS.doorOpen:
@@ -209,12 +201,11 @@ class CarSpecificEvents:
events.add(EventName.invalidLkasSetting)
if CS.lowSpeedAlert:
events.add(EventName.belowSteerSpeed)
if CS.buttonEnable:
events.add(EventName.buttonEnable)
# Handle button presses
# Handle cancel button presses
for b in CS.buttonEvents:
# Enable OP long on falling edge of enable buttons (defaults to accelCruise and decelCruise, overridable per-port)
if not self.CP.pcmCruise and (b.type in enable_buttons and not b.pressed):
events.add(EventName.buttonEnable)
# Disable on rising and falling edge of cancel for both stock and OP long
# TODO: only check the cancel button with openpilot longitudinal on all brands to match panda safety
if b.type == ButtonType.cancel and (allow_button_cancel or not self.CP.pcmCruise):
+7 -4
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
import json
import os
import time
import threading
@@ -7,17 +8,17 @@ import cereal.messaging as messaging
from cereal import car, log, custom
from panda import ALTERNATIVE_EXPERIENCE
from openpilot.common.params import Params
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper
from openpilot.common.swaglog import cloudlog, ForwardingHandler
from opendbc.car import DT_CTRL, carlog, structs
from opendbc.car import DT_CTRL, structs
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
from opendbc.car.carlog import carlog
from opendbc.car.fw_versions import ObdCallback
from opendbc.car.car_helpers import get_car, get_radar_interface
from opendbc.car.interfaces import CarInterfaceBase, RadarInterfaceBase
from opendbc.safety import ALTERNATIVE_EXPERIENCE
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
from openpilot.selfdrive.car.cruise import VCruiseHelper
from openpilot.selfdrive.car.car_specific import MockCarState
@@ -104,7 +105,9 @@ class Car:
with car.CarParams.from_bytes(cached_params_raw) as _cached_params:
cached_params = _cached_params
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, cached_params)
fixed_fingerprint = json.loads(self.params.get("CarPlatformBundle", encoding='utf-8') or "{}").get("platform", None)
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, cached_params, fixed_fingerprint)
interfaces.setup_car_interface_sp(self.CI.CP, self.CI.CP_SP, self.params)
self.RI = get_radar_interface(self.CI.CP, self.CI.CP_SP)
self.CP = self.CI.CP
+10 -22
View File
@@ -1,3 +1,4 @@
import time
import capnp
import copy
import os
@@ -10,17 +11,15 @@ import hypothesis.strategies as st
from hypothesis import Phase, given, settings
from parameterized import parameterized_class
from cereal import messaging, log, car
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from opendbc.car import DT_CTRL, gen_empty_fingerprint, structs
from opendbc.car.fingerprints import all_known_cars, MIGRATION
from opendbc.car.can_definitions import CanData
from opendbc.car.car_helpers import FRAME_FINGERPRINT, interfaces
from opendbc.car.fingerprints import all_known_cars, MIGRATION
from opendbc.car.honda.values import CAR as HONDA, HondaFlags
from opendbc.car.values import Platform
from opendbc.car.structs import car
from opendbc.car.tests.routes import non_tested_cars, routes, CarTestRoute
from openpilot.selfdrive.selfdrived.events import ET
from openpilot.selfdrive.selfdrived.selfdrived import SelfdriveD
from opendbc.car.values import Platform
from openpilot.common.basedir import BASEDIR
from openpilot.selfdrive.pandad import can_capnp_to_list
from openpilot.selfdrive.test.helpers import read_segment_list
from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
@@ -30,8 +29,6 @@ from openpilot.tools.lib.route import SegmentName
from panda.tests.libpanda import libpanda_py
EventName = log.OnroadEvent.EventName
PandaType = log.PandaState.PandaType
SafetyModel = car.CarParams.SafetyModel
NUM_JOBS = int(os.environ.get("NUM_JOBS", "1"))
@@ -174,8 +171,6 @@ class TestCarModelBase(unittest.TestCase):
self.CI = self.CarInterface(self.CP.copy(), copy.deepcopy(self.CP_SP), self.CarController, self.CarState)
assert self.CI
Params().put_bool("OpenpilotEnabledToggle", self.openpilot_enabled)
# TODO: check safetyModel is in release panda build
self.safety = libpanda_py.libpanda
@@ -344,10 +339,8 @@ class TestCarModelBase(unittest.TestCase):
to_send = libpanda_py.make_CANPacket(address, bus, dat)
self.safety.safety_rx_hook(to_send)
can = messaging.new_message('can', 1)
can.can = [log.CanData(address=address, dat=dat, src=bus)]
CS = self.CI.update(can_capnp_to_list((can.to_bytes(),)))
can = [(int(time.monotonic() * 1e9), [CanData(address=address, dat=dat, src=bus)])]
CS = self.CI.update(can)
if self.safety.get_gas_pressed_prev() != prev_panda_gas:
self.assertEqual(CS.gasPressed, self.safety.get_gas_pressed_prev())
@@ -392,8 +385,6 @@ class TestCarModelBase(unittest.TestCase):
controls_allowed_prev = False
CS_prev = car.CarState.new_message()
checks = defaultdict(int)
selfdrived = SelfdriveD(CP=self.CP, CP_SP=self.CP_SP)
selfdrived.initialized = True
for idx, can in enumerate(self.can_msgs):
CS = self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), ))).as_reader()
for msg in filter(lambda m: m.src in range(64), can.can):
@@ -437,11 +428,8 @@ class TestCarModelBase(unittest.TestCase):
if not self.CP.notCar:
checks['cruiseState'] += CS.cruiseState.enabled != self.safety.get_cruise_engaged_prev()
else:
# Check for enable events on rising edge of controls allowed
selfdrived.update_events(CS)
selfdrived.CS_prev = CS
button_enable = (selfdrived.events.contains(ET.ENABLE) and
EventName.pedalPressed not in selfdrived.events.names)
# Check for user button enable on rising edge of controls allowed
button_enable = CS.buttonEnable and (not CS.brakePressed or CS.standstill)
mismatch = button_enable != (self.safety.get_controls_allowed() and not controls_allowed_prev)
checks['controlsAllowed'] += mismatch
controls_allowed_prev = self.safety.get_controls_allowed()
@@ -3,7 +3,7 @@ import os
import time
import numpy as np
from cereal import log
from opendbc.car.interfaces import ACCEL_MIN
from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX
from openpilot.common.realtime import DT_MDL
from openpilot.common.swaglog import cloudlog
# WARNING: imports outside of constants will not trigger a rebuild
@@ -55,6 +55,8 @@ FCW_IDXS = T_IDXS < 5.0
T_DIFFS = np.diff(T_IDXS, prepend=[0.])
COMFORT_BRAKE = 2.5
STOP_DISTANCE = 6.0
CRUISE_MIN_ACCEL = -1.2
CRUISE_MAX_ACCEL = 1.6
def get_jerk_factor(personality=log.LongitudinalPersonality.standard):
if personality==log.LongitudinalPersonality.relaxed:
@@ -281,7 +283,7 @@ class LongitudinalMpc:
elif self.mode == 'blended':
a_change_cost = 40.0 if prev_accel_constraint else 0
cost_weights = [0., 0.1, 0.2, 5.0, a_change_cost, 1.0]
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, 50.0]
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST]
else:
raise NotImplementedError(f'Planner mode {self.mode} not recognized in planner cost set')
self.set_cost_weights(cost_weights, constraint_cost_weights)
@@ -325,12 +327,6 @@ class LongitudinalMpc:
lead_xv = self.extrapolate_lead(x_lead, v_lead, a_lead, a_lead_tau)
return lead_xv
def set_accel_limits(self, min_a, max_a):
# TODO this sets a max accel limit, but the minimum limit is only for cruise decel
# needs refactor
self.cruise_min_a = min_a
self.max_a = max_a
def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard):
t_follow = get_T_FOLLOW(personality)
v_ego = self.x0[1]
@@ -346,8 +342,7 @@ class LongitudinalMpc:
lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1])
self.params[:,0] = ACCEL_MIN
# negative accel constraint causes problems because negative speed is not allowed
self.params[:,1] = max(0.0, self.max_a)
self.params[:,1] = ACCEL_MAX
# Update in ACC mode or ACC/e2e blend
if self.mode == 'acc':
@@ -355,9 +350,9 @@ class LongitudinalMpc:
# Fake an obstacle for cruise, this ensures smooth acceleration to set speed
# when the leads are no factor.
v_lower = v_ego + (T_IDXS * self.cruise_min_a * 1.05)
v_lower = v_ego + (T_IDXS * CRUISE_MIN_ACCEL * 1.05)
# TODO does this make sense when max_a is negative?
v_upper = v_ego + (T_IDXS * self.max_a * 1.05)
v_upper = v_ego + (T_IDXS * CRUISE_MAX_ACCEL * 1.05)
v_cruise_clipped = np.clip(v_cruise * np.ones(N+1),
v_lower,
v_upper)
+21 -18
View File
@@ -18,7 +18,6 @@ from openpilot.common.swaglog import cloudlog
from openpilot.sunnypilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlannerSP
LON_MPC_STEP = 0.2 # first step is 0.2s
A_CRUISE_MIN = -1.2
A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6]
A_CRUISE_MAX_BP = [0., 10.0, 25., 40.]
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
@@ -79,7 +78,10 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
self.a_desired = init_a
self.v_desired_filter = FirstOrderFilter(init_v, 2.0, self.dt)
self.prev_accel_clip = [ACCEL_MIN, ACCEL_MAX]
self.v_model_error = 0.0
self.output_a_target = 0.0
self.output_should_stop = False
self.v_desired_trajectory = np.zeros(CONTROL_N)
self.a_desired_trajectory = np.zeros(CONTROL_N)
@@ -134,17 +136,16 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
prev_accel_constraint = not (reset_state or sm['carState'].standstill)
if self.mpc.mode == 'acc':
accel_limits = [A_CRUISE_MIN, get_max_accel(v_ego)]
accel_clip = [ACCEL_MIN, get_max_accel(v_ego)]
steer_angle_without_offset = sm['carState'].steeringAngleDeg - sm['liveParameters'].angleOffsetDeg
accel_limits_turns = limit_accel_in_turns(v_ego, steer_angle_without_offset, accel_limits, self.CP)
accel_clip = limit_accel_in_turns(v_ego, steer_angle_without_offset, accel_clip, self.CP)
else:
accel_limits = [ACCEL_MIN, ACCEL_MAX]
accel_limits_turns = [ACCEL_MIN, ACCEL_MAX]
accel_clip = [ACCEL_MIN, ACCEL_MAX]
if reset_state:
self.v_desired_filter.x = v_ego
# Clip aEgo to cruise limits to prevent large accelerations when becoming active
self.a_desired = np.clip(sm['carState'].aEgo, accel_limits[0], accel_limits[1])
self.a_desired = np.clip(sm['carState'].aEgo, accel_clip[0], accel_clip[1])
# Prevent divergence, smooth in current v_ego
self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego))
@@ -155,18 +156,14 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED
if not self.allow_throttle:
clipped_accel_coast = max(accel_coast, accel_limits_turns[0])
clipped_accel_coast_interp = np.interp(v_ego, [MIN_ALLOW_THROTTLE_SPEED, MIN_ALLOW_THROTTLE_SPEED*2], [accel_limits_turns[1], clipped_accel_coast])
accel_limits_turns[1] = min(accel_limits_turns[1], clipped_accel_coast_interp)
clipped_accel_coast = max(accel_coast, accel_clip[0])
clipped_accel_coast_interp = np.interp(v_ego, [MIN_ALLOW_THROTTLE_SPEED, MIN_ALLOW_THROTTLE_SPEED*2], [accel_clip[1], clipped_accel_coast])
accel_clip[1] = min(accel_clip[1], clipped_accel_coast_interp)
if force_slow_decel:
v_cruise = 0.0
# clip limits, cannot init MPC outside of bounds
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
self.mpc.set_weights(prev_accel_constraint, personality=sm['selfdriveState'].personality)
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['selfdriveState'].personality)
@@ -184,6 +181,15 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
self.a_desired = float(np.interp(self.dt, CONTROL_N_T_IDX, self.a_desired_trajectory))
self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.a_desired + a_prev) / 2.0
action_t = self.CP.longitudinalActuatorDelay + DT_MDL
output_a_target, self.output_should_stop = get_accel_from_plan(self.v_desired_trajectory, self.a_desired_trajectory,
action_t=action_t, vEgoStopping=self.CP.vEgoStopping)
for idx in range(2):
accel_clip[idx] = np.clip(accel_clip[idx], self.prev_accel_clip[idx] - 0.05, self.prev_accel_clip[idx] + 0.05)
self.output_a_target = np.clip(output_a_target, accel_clip[0], accel_clip[1])
self.prev_accel_clip = accel_clip
def publish(self, sm, pm):
plan_send = messaging.new_message('longitudinalPlan')
@@ -202,11 +208,8 @@ class LongitudinalPlanner(LongitudinalPlannerSP):
longitudinalPlan.longitudinalPlanSource = self.mpc.source
longitudinalPlan.fcw = self.fcw
action_t = self.CP.longitudinalActuatorDelay + DT_MDL
a_target, should_stop = get_accel_from_plan(longitudinalPlan.speeds, longitudinalPlan.accels,
action_t=action_t, vEgoStopping=self.CP.vEgoStopping)
longitudinalPlan.aTarget = float(a_target)
longitudinalPlan.shouldStop = bool(should_stop)
longitudinalPlan.aTarget = float(self.output_a_target)
longitudinalPlan.shouldStop = bool(self.output_should_stop)
longitudinalPlan.allowBrake = True
longitudinalPlan.allowThrottle = bool(self.allow_throttle)
+1 -1
View File
@@ -11,5 +11,5 @@ if __name__ == "__main__":
time.sleep(1)
# honda bosch radar disable
disabled = disable_ecu(*can_callbacks, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5, debug=False)
disabled = disable_ecu(*can_callbacks, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5)
print(f"disabled: {disabled}")
+5 -1
View File
@@ -2,6 +2,7 @@
import argparse
import time
import cereal.messaging as messaging
from opendbc.car.carlog import carlog
from opendbc.car.ecu_addrs import get_all_ecu_addrs
from openpilot.common.params import Params
from openpilot.selfdrive.car.card import can_comm_callbacks, obd_callback
@@ -15,6 +16,9 @@ if __name__ == "__main__":
parser.add_argument('--timeout', type=float, default=1.0)
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
logcan = messaging.sub_sock('can')
sendcan = messaging.pub_sock('sendcan')
can_callbacks = can_comm_callbacks(logcan, sendcan)
@@ -29,7 +33,7 @@ if __name__ == "__main__":
obd_callback(params)(not args.no_obd)
print("Getting ECU addresses ...")
ecu_addrs = get_all_ecu_addrs(*can_callbacks, args.bus, args.timeout, debug=args.debug)
ecu_addrs = get_all_ecu_addrs(*can_callbacks, args.bus, args.timeout)
print()
print("Found ECUs on rx addresses:")
+6 -2
View File
@@ -3,6 +3,7 @@ import time
import argparse
import cereal.messaging as messaging
from cereal import car
from opendbc.car.carlog import carlog
from opendbc.car.fw_versions import get_fw_versions, match_fw_to_car
from opendbc.car.vin import get_vin
from openpilot.common.params import Params
@@ -18,6 +19,9 @@ if __name__ == "__main__":
parser.add_argument('--brand', help='Only query addresses/with requests for this brand')
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
logcan = messaging.sub_sock('can')
pandaStates_sock = messaging.sub_sock('pandaStates')
sendcan = messaging.pub_sock('sendcan')
@@ -46,13 +50,13 @@ if __name__ == "__main__":
t = time.time()
print("Getting vin...")
set_obd_multiplexing(True)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (0, 1), debug=args.debug)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (0, 1))
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
print(f"Getting VIN took {time.time() - t:.3f} s")
print()
t = time.time()
fw_vers = get_fw_versions(*can_callbacks, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, debug=args.debug, progress=True)
fw_vers = get_fw_versions(*can_callbacks, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, progress=True)
_, candidates = match_fw_to_car(fw_vers, vin)
print()
+5 -1
View File
@@ -2,6 +2,7 @@
import argparse
import time
import cereal.messaging as messaging
from opendbc.car.carlog import carlog
from opendbc.car.vin import get_vin
from openpilot.selfdrive.car.card import can_comm_callbacks
@@ -13,10 +14,13 @@ if __name__ == "__main__":
parser.add_argument('--retry', type=int, default=5)
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
sendcan = messaging.pub_sock('sendcan')
logcan = messaging.sub_sock('can')
can_callbacks = can_comm_callbacks(logcan, sendcan)
time.sleep(1)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (args.bus,), args.timeout, args.retry, debug=args.debug)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (args.bus,), args.timeout, args.retry)
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
+7 -2
View File
@@ -2,7 +2,9 @@
import sys
import argparse
from subprocess import check_output, CalledProcessError
from opendbc.car.carlog import carlog
from opendbc.car.uds import UdsClient, MessageTimeoutError, SESSION_TYPE, DTC_GROUP_TYPE
from opendbc.safety import Safety
from panda import Panda
parser = argparse.ArgumentParser(description="clear DTC status")
@@ -11,6 +13,9 @@ parser.add_argument("--bus", type=int, default=0)
parser.add_argument('--debug', action='store_true')
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
try:
check_output(["pidof", "pandad"])
print("pandad is running, please kill openpilot before running this script! (aborted)")
@@ -20,8 +25,8 @@ except CalledProcessError as e:
raise e
panda = Panda()
panda.set_safety_mode(Panda.SAFETY_ELM327)
uds_client = UdsClient(panda, args.addr, bus=args.bus, debug=args.debug)
panda.set_safety_mode(Safety.SAFETY_ELM327)
uds_client = UdsClient(panda, args.addr, bus=args.bus)
print("extended diagnostic session ...")
try:
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
@@ -16,7 +16,9 @@ import argparse
from typing import NamedTuple
from subprocess import check_output, CalledProcessError
from opendbc.car.carlog import carlog
from opendbc.car.uds import UdsClient, SESSION_TYPE, DATA_IDENTIFIER_TYPE
from opendbc.safety import Safety
from panda.python import Panda
class ConfigValues(NamedTuple):
@@ -78,6 +80,9 @@ if __name__ == "__main__":
parser.add_argument('--bus', type=int, default=0, help='can bus to use (default: 0)')
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
try:
check_output(["pidof", "pandad"])
print("pandad is running, please kill openpilot before running this script! (aborted)")
@@ -92,8 +97,8 @@ if __name__ == "__main__":
sys.exit(0)
panda = Panda()
panda.set_safety_mode(Panda.SAFETY_ELM327)
uds_client = UdsClient(panda, 0x7D0, bus=args.bus, debug=args.debug)
panda.set_safety_mode(Safety.SAFETY_ELM327)
uds_client = UdsClient(panda, 0x7D0, bus=args.bus)
print("\n[START DIAGNOSTIC SESSION]")
session_type : SESSION_TYPE = 0x07 # type: ignore
+1 -1
View File
@@ -6,7 +6,7 @@ from collections import defaultdict
import matplotlib.pyplot as plt
from cereal.services import SERVICE_LIST
from openpilot.system.loggerd.uploader import LOG_COMPRESSION_LEVEL
from openpilot.common.file_helpers import LOG_COMPRESSION_LEVEL
from openpilot.tools.lib.logreader import LogReader
from tqdm import tqdm
+7 -2
View File
@@ -2,7 +2,9 @@
import sys
import argparse
from subprocess import check_output, CalledProcessError
from opendbc.car.carlog import carlog
from opendbc.car.uds import UdsClient, SESSION_TYPE, DTC_REPORT_TYPE, DTC_STATUS_MASK_TYPE, get_dtc_num_as_str, get_dtc_status_names
from opendbc.safety import Safety
from panda import Panda
parser = argparse.ArgumentParser(description="read DTC status")
@@ -11,6 +13,9 @@ parser.add_argument("--bus", type=int, default=0)
parser.add_argument('--debug', action='store_true')
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
try:
check_output(["pidof", "pandad"])
print("pandad is running, please kill openpilot before running this script! (aborted)")
@@ -20,8 +25,8 @@ except CalledProcessError as e:
raise e
panda = Panda()
panda.set_safety_mode(Panda.SAFETY_ELM327)
uds_client = UdsClient(panda, args.addr, bus=args.bus, debug=args.debug)
panda.set_safety_mode(Safety.SAFETY_ELM327)
uds_client = UdsClient(panda, args.addr, bus=args.bus)
print("extended diagnostic session ...")
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
print("read diagnostic codes ...")
+8 -2
View File
@@ -3,19 +3,25 @@ import time
from cereal import car, log, messaging
from openpilot.common.params import Params
from openpilot.system.manager.process_config import managed_processes, is_snpe_model
from openpilot.system.manager.process_config import managed_processes, is_snpe_model, is_tinygrad_model, is_stock_model
from openpilot.system.hardware import HARDWARE
if __name__ == "__main__":
CP = car.CarParams(notCar=True, wheelbase=1, steerRatio=10)
params = Params()
params.put("CarParams", CP.to_bytes())
if use_snpe_modeld := is_snpe_model(False, params, CP):
print("Using SNPE modeld")
if use_tinygrad_modeld := is_tinygrad_model(False, params, CP):
print("Using TinyGrad modeld")
if use_stock_modeld := is_stock_model(False, params, CP):
print("Using stock modeld")
HARDWARE.set_power_save(False)
procs = ['camerad', 'ui', 'calibrationd', 'plannerd', 'dmonitoringmodeld', 'dmonitoringd']
procs += ["modeld_snpe" if use_snpe_modeld else "modeld"]
procs += ["modeld_snpe" if use_snpe_modeld else "modeld_tinygrad" if use_tinygrad_modeld else "modeld"]
for p in procs:
managed_processes[p].start()
+7 -2
View File
@@ -3,8 +3,10 @@
import argparse
import struct
from enum import IntEnum
from opendbc.car.carlog import carlog
from opendbc.car.uds import UdsClient, MessageTimeoutError, NegativeResponseError, SESSION_TYPE,\
DATA_IDENTIFIER_TYPE, ACCESS_TYPE
from opendbc.safety import Safety
from panda import Panda
from datetime import date
@@ -33,10 +35,13 @@ if __name__ == "__main__":
parser.add_argument("action", choices={"show", "enable", "disable"}, help="show or modify current EPS HCA config")
args = parser.parse_args()
if args.debug:
carlog.setLevel('DEBUG')
panda = Panda()
panda.set_safety_mode(Panda.SAFETY_ELM327)
panda.set_safety_mode(Safety.SAFETY_ELM327)
bus = 1 if panda.has_obd() else 0
uds_client = UdsClient(panda, MQB_EPS_CAN_ADDR, MQB_EPS_CAN_ADDR + RX_OFFSET, bus, timeout=0.2, debug=args.debug)
uds_client = UdsClient(panda, MQB_EPS_CAN_ADDR, MQB_EPS_CAN_ADDR + RX_OFFSET, bus, timeout=0.2)
try:
uds_client.diagnostic_session_control(SESSION_TYPE.EXTENDED_DIAGNOSTIC)
+2 -4
View File
@@ -6,7 +6,6 @@ While the roll calibration is a real value that can be estimated, here we assume
and the image input into the neural network is not corrected for roll.
'''
import gc
import os
import capnp
import numpy as np
@@ -16,7 +15,7 @@ from cereal import log
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
from openpilot.common.params import Params
from openpilot.common.realtime import set_realtime_priority
from openpilot.common.realtime import config_realtime_process
from openpilot.common.transformations.orientation import rot_from_euler, euler_from_rot
from openpilot.common.swaglog import cloudlog
@@ -256,8 +255,7 @@ class Calibrator:
def main() -> NoReturn:
gc.disable()
set_realtime_priority(1)
config_realtime_process([0, 1, 2, 3], 5)
pm = messaging.PubMaster(['liveCalibration'])
sm = messaging.SubMaster(['cameraOdometry', 'carState', 'carParams'], poll='cameraOdometry')
+7 -7
View File
@@ -12,6 +12,7 @@ from cereal.services import SERVICE_LIST
from openpilot.common.transformations.orientation import rot_from_euler
from openpilot.common.realtime import config_realtime_process
from openpilot.common.params import Params
from openpilot.common.swaglog import cloudlog
from openpilot.selfdrive.locationd.helpers import rotate_std
from openpilot.selfdrive.locationd.models.pose_kf import PoseKalman, States
from openpilot.selfdrive.locationd.models.constants import ObservationKind, GENERATED_DIR
@@ -78,20 +79,20 @@ class LocationEstimator:
# sensor time and log time should be close
sensor_time_invalid = abs(sensor_time - t) > MAX_SENSOR_TIME_DIFF
if sensor_time_invalid:
print("Sensor reading ignored, sensor timestamp more than 100ms off from log time")
cloudlog.warning("Sensor reading ignored, sensor timestamp more than 100ms off from log time")
return not sensor_time_invalid
def _validate_timestamp(self, t: float):
kf_t = self.kf.t
invalid = not np.isnan(kf_t) and (kf_t - t) > MAX_FILTER_REWIND_TIME
if invalid:
print("Observation timestamp is older than the max rewind threshold of the filter")
cloudlog.warning("Observation timestamp is older than the max rewind threshold of the filter")
return not invalid
def _finite_check(self, t: float, new_x: np.ndarray, new_P: np.ndarray):
all_finite = np.isfinite(new_x).all() and np.isfinite(new_P).all()
if not all_finite:
print("Non-finite values detected, kalman reset")
cloudlog.error("Non-finite values detected, kalman reset")
self.reset(t)
def handle_log(self, t: float, which: str, msg: capnp._DynamicStructReader) -> HandleLogResult:
@@ -308,13 +309,12 @@ def main():
continue
if res == HandleLogResult.TIMING_INVALID:
print(f"Observation {which} ignored due to failed timing check")
cloudlog.warning(f"Observation {which} ignored due to failed timing check")
observation_input_invalid[which] += 1
print(observation_input_invalid[which])
elif res == HandleLogResult.INPUT_INVALID:
print(f"Observation {which} ignored due to failed sanity check")
cloudlog.warning(f"Observation {which} ignored due to failed sanity check")
observation_input_invalid[which] += 1
else:
elif res == HandleLogResult.SUCCESS:
observation_input_invalid[which] *= input_invalid_decay[which]
else:
filter_initialized = sm.all_checks() and sensor_all_checks(acc_msgs, gyro_msgs, sensor_valid, sensor_recv_time, sensor_alive, SIMULATION)
+10 -10
View File
@@ -31,7 +31,6 @@ class ModelConstants:
DISENGAGE_WIDTH = 5
POSE_WIDTH = 6
WIDE_FROM_DEVICE_WIDTH = 3
SIM_POSE_WIDTH = 6
LEAD_WIDTH = 4
LANE_LINES_WIDTH = 2
ROAD_EDGES_WIDTH = 2
@@ -72,13 +71,14 @@ class Plan:
class Meta:
ENGAGED = slice(0, 1)
# next 2, 4, 6, 8, 10 seconds
GAS_DISENGAGE = slice(1, 36, 7)
BRAKE_DISENGAGE = slice(2, 36, 7)
STEER_OVERRIDE = slice(3, 36, 7)
HARD_BRAKE_3 = slice(4, 36, 7)
HARD_BRAKE_4 = slice(5, 36, 7)
HARD_BRAKE_5 = slice(6, 36, 7)
GAS_PRESS = slice(7, 36, 7)
GAS_DISENGAGE = slice(1, 31, 6)
BRAKE_DISENGAGE = slice(2, 31, 6)
STEER_OVERRIDE = slice(3, 31, 6)
HARD_BRAKE_3 = slice(4, 31, 6)
HARD_BRAKE_4 = slice(5, 31, 6)
HARD_BRAKE_5 = slice(6, 31, 6)
# next 0, 2, 4, 6, 8, 10 seconds
LEFT_BLINKER = slice(36, 48, 2)
RIGHT_BLINKER = slice(37, 48, 2)
GAS_PRESS = slice(31, 55, 4)
BRAKE_PRESS = slice(32, 55, 4)
LEFT_BLINKER = slice(33, 55, 4)
RIGHT_BLINKER = slice(34, 55, 4)
+2 -4
View File
@@ -8,7 +8,6 @@ if TICI:
os.environ['QCOM'] = '1'
else:
from openpilot.selfdrive.modeld.runners.ort_helpers import make_onnx_cpu_runner
import gc
import math
import time
import pickle
@@ -21,7 +20,7 @@ from cereal import messaging
from cereal.messaging import PubMaster, SubMaster
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
from openpilot.common.swaglog import cloudlog
from openpilot.common.realtime import set_realtime_priority
from openpilot.common.realtime import config_realtime_process
from openpilot.common.transformations.model import dmonitoringmodel_intrinsics, DM_INPUT_SIZE
from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye
from openpilot.selfdrive.modeld.models.commonmodel_pyx import CLContext, MonitoringModelFrame
@@ -140,9 +139,8 @@ def get_driverstate_packet(model_output: np.ndarray, frame_id: int, location_ts:
def main():
gc.disable()
setproctitle(PROCESS_NAME)
set_realtime_priority(1)
config_realtime_process([0, 1, 2, 3], 5)
sentry.set_tag("daemon", PROCESS_NAME)
cloudlog.bind(daemon=PROCESS_NAME)
+11 -4
View File
@@ -112,10 +112,17 @@ def fill_model_msg(base_msg: capnp._DynamicStructBuilder, extended_msg: capnp._D
# temporal pose
temporal_pose = modelV2.temporalPose
temporal_pose.trans = net_output_data['plan'][0,0,Plan.VELOCITY].tolist()
temporal_pose.transStd = net_output_data['plan_stds'][0,0,Plan.VELOCITY].tolist()
temporal_pose.rot = net_output_data['plan'][0,0,Plan.ORIENTATION_RATE].tolist()
temporal_pose.rotStd = net_output_data['plan_stds'][0,0,Plan.ORIENTATION_RATE].tolist()
if 'sim_pose' in net_output_data:
temporal_pose.trans = net_output_data['sim_pose'][0,:ModelConstants.POSE_WIDTH//2].tolist()
temporal_pose.transStd = net_output_data['sim_pose_stds'][0,:ModelConstants.POSE_WIDTH//2].tolist()
temporal_pose.rot = net_output_data['sim_pose'][0,ModelConstants.POSE_WIDTH//2:].tolist()
temporal_pose.rotStd = net_output_data['sim_pose_stds'][0,ModelConstants.POSE_WIDTH//2:].tolist()
else:
temporal_pose.trans = net_output_data['plan'][0,0,Plan.VELOCITY].tolist()
temporal_pose.transStd = net_output_data['plan_stds'][0,0,Plan.VELOCITY].tolist()
temporal_pose.rot = net_output_data['plan'][0,0,Plan.ORIENTATION_RATE].tolist()
temporal_pose.rotStd = net_output_data['plan_stds'][0,0,Plan.ORIENTATION_RATE].tolist()
# poly path
fill_xyz_poly(driving_model_data.path, ModelConstants.POLY_PATH_DEGREE, *net_output_data['plan'][0,:,Plan.POSITION].T)
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:39786068cae1ed8c0dc34ef80c281dfcc67ed18a50e06b90765c49bcfdbf7db4
size 51453312
oid sha256:d21daa542227ecc5972da45df4e26f018ba113c0461f270e367d57e3ad89221a
size 51461700
+2
View File
@@ -91,6 +91,8 @@ class Parser:
self.parse_mdn('road_edges', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_ROAD_EDGES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH))
self.parse_mdn('pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
self.parse_mdn('road_transform', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
if 'sim_pose' in outs:
self.parse_mdn('sim_pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,))
self.parse_mdn('wide_from_device_euler', outs, in_N=0, out_N=0, out_shape=(ModelConstants.WIDE_FROM_DEVICE_WIDTH,))
self.parse_mdn('lead', outs, in_N=ModelConstants.LEAD_MHP_N, out_N=ModelConstants.LEAD_MHP_SELECTION,
out_shape=(ModelConstants.LEAD_TRAJ_LEN,ModelConstants.LEAD_WIDTH))
+2 -5
View File
@@ -1,15 +1,12 @@
#!/usr/bin/env python3
import gc
import cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.common.realtime import set_realtime_priority
from openpilot.common.realtime import config_realtime_process
from openpilot.selfdrive.monitoring.helpers import DriverMonitoring
def dmonitoringd_thread():
gc.disable()
set_realtime_priority(2)
config_realtime_process([0, 1, 2, 3], 5)
params = Params()
pm = messaging.PubMaster(['driverMonitoringState'])
-7
View File
@@ -2,10 +2,3 @@
from openpilot.selfdrive.pandad.pandad_api_impl import can_list_to_can_capnp, can_capnp_to_list
assert can_list_to_can_capnp
assert can_capnp_to_list
def can_capnp_to_can_list(can, src_filter=None):
ret = []
for msg in can:
if src_filter is None or msg.src in src_filter:
ret.append((msg.address, msg.dat, msg.src))
return ret
+1 -2
View File
@@ -1,8 +1,7 @@
#include "cereal/messaging/messaging.h"
#include "selfdrive/pandad/panda.h"
#include "opendbc/can/common.h"
void can_list_to_can_capnp_cpp(const std::vector<can_frame> &can_list, std::string &out, bool sendcan, bool valid) {
void can_list_to_can_capnp_cpp(const std::vector<CanFrame> &can_list, std::string &out, bool sendcan, bool valid) {
MessageBuilder msg;
auto event = msg.initEvent(valid);
+3 -9
View File
@@ -6,12 +6,6 @@ from libcpp.string cimport string
from libcpp cimport bool
from libc.stdint cimport uint8_t, uint32_t, uint64_t
cdef extern from "panda.h":
cdef struct can_frame:
long address
string dat
long src
cdef extern from "opendbc/can/common.h":
cdef struct CanFrame:
long src
@@ -23,12 +17,12 @@ cdef extern from "opendbc/can/common.h":
vector[CanFrame] frames
cdef extern from "can_list_to_can_capnp.cc":
void can_list_to_can_capnp_cpp(const vector[can_frame] &can_list, string &out, bool sendcan, bool valid)
void can_list_to_can_capnp_cpp(const vector[CanFrame] &can_list, string &out, bool sendcan, bool valid)
void can_capnp_to_can_list_cpp(const vector[string] &strings, vector[CanData] &can_data, bool sendcan)
def can_list_to_can_capnp(can_msgs, msgtype='can', valid=True):
cdef can_frame *f
cdef vector[can_frame] can_list
cdef CanFrame *f
cdef vector[CanFrame] can_list
can_list.reserve(len(can_msgs))
for can_msg in can_msgs:
+6 -3
View File
@@ -7,7 +7,7 @@ import cereal.messaging as messaging
from cereal import car, log, custom
from msgq.visionipc import VisionIpcClient, VisionStreamType
from panda import ALTERNATIVE_EXPERIENCE
from opendbc.safety import ALTERNATIVE_EXPERIENCE
from openpilot.common.params import Params
@@ -31,7 +31,6 @@ from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP
REPLAY = "REPLAY" in os.environ
SIMULATION = "SIMULATION" in os.environ
TESTING_CLOSET = "TESTING_CLOSET" in os.environ
IGNORE_PROCESSES = {"loggerd", "encoderd", "statsd"}
LONGITUDINAL_PERSONALITY_MAP = {v: k for k, v in log.LongitudinalPersonality.schema.enumerants.items()}
ThermalStatus = log.DeviceState.ThermalStatus
@@ -284,7 +283,7 @@ class SelfdriveD(CruiseHelper):
if not_running != self.not_running_prev:
cloudlog.event("process_not_running", not_running=not_running, error=True)
self.not_running_prev = not_running
if self.sm.recv_frame['managerState'] and (not_running - IGNORE_PROCESSES):
if self.sm.recv_frame['managerState'] and not_running:
self.events.add(EventName.processNotRunning)
else:
if not SIMULATION and not self.rk.lagging:
@@ -380,6 +379,10 @@ class SelfdriveD(CruiseHelper):
if self.sm['modelV2'].frameDropPerc > 20:
self.events.add(EventName.modeldLagging)
# mute canBusMissing event if in Park, as it sometimes may trigger a false alarm with MADS in Paused state
if CS.gearShifter == car.CarState.GearShifter.park and self.mads.enabled:
self.events.remove(EventName.canBusMissing)
CruiseHelper.update(self, CS, self.events_sp, self.experimental_mode)
# decrement personality on distance button press
@@ -66,7 +66,7 @@ class Maneuver:
print("Crashed!!!!")
valid = False
if self.ensure_start and log['v_rel'] > 0 and log['speeds'][-1] <= 0.1:
if self.ensure_start and log['v_rel'] > 0 and log['acceleration'] < 1e-3:
print('LongitudinalPlanner not starting!')
valid = False
@@ -30,8 +30,8 @@ class Plant:
self.distance = 0.
self.speed = speed
self.should_stop = False
self.acceleration = 0.0
self.speeds = []
# lead car
self.lead_relevancy = lead_relevancy
@@ -134,9 +134,9 @@ class Plant:
'liveParameters': lp.liveParameters,
'modelV2': model.modelV2}
self.planner.update(sm)
self.speed = self.planner.v_desired_filter.x
self.acceleration = self.planner.a_desired
self.speeds = self.planner.v_desired_trajectory.tolist()
self.acceleration = self.planner.output_a_target
self.speed = self.speed + self.acceleration * self.ts
self.should_stop = self.planner.output_should_stop
fcw = self.planner.fcw
self.distance_lead = self.distance_lead + v_lead * self.ts
@@ -168,7 +168,7 @@ class Plant:
"distance": self.distance,
"speed": self.speed,
"acceleration": self.acceleration,
"speeds": self.speeds,
"should_stop": self.should_stop,
"distance_lead": self.distance_lead,
"fcw": fcw,
}
@@ -150,10 +150,7 @@ def create_maneuvers(kwargs):
enabled=False,
**kwargs,
),
]
if not kwargs['e2e']:
# allow_throttle won't trigger with e2e
maneuvers.append(Maneuver(
Maneuver(
"slow to 5m/s with allow_throttle = False and pitch = +0.1",
duration=30.,
initial_speed=20.,
@@ -164,7 +161,7 @@ def create_maneuvers(kwargs):
breakpoints=[0.0, 2., 2.01],
ensure_slowdown=True,
**kwargs,
))
)]
if not kwargs['force_decel']:
# controls relies on planner commanding to move for stock-ACC resume spamming
maneuvers.append(Maneuver(
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:10b30201502cc65fa2b9aae2b8dc40cdbb3f546472bd6a00e0ab27b983cdfbad
size 356188
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a518e8ddeaf9998688e922c1e880c8ed87cd4d017ace099fb5d12b49495c0a60
size 356259
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ba147551edbc729a3bfc8c8e910584ef23ceaeb2a9092b8c07509b2dd913ee1a
size 256718
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d9d552eff00311b0e777a80a10d3fcd61fac4fc1f660ef5d915ad66c4478ffa5
size 256497
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:07527a8ccdeb5f67e20b6e67a538466910cbac6ad2120cdedead2f14cf8291c1
size 332427
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b554294ad2b5b4baed3679a003d62145affc1794e8fdba4ee08bf8062456314e
size 332430
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a432f535c7205b5226839229401fe766566f5a353102233afee330f6dc73aca9
size 268997
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bb44217a08fe15883c54910ce0d1d1cdf5c472121eda0e2d80314c33ae1ec000
size 269005
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b44e54fc9b5a6ea7f2059f249da82556ce29de0292f8bb5e168fae1dadc2ffb
size 436895
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2adcaa7886a8da13d84179f29564da2ac09c55c816a1f5f451ba1d1d55910364
size 436913
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc115d7e482da0ddf40ecb373223186eed8d2f0e891cf67093db0d0b529c494e
size 308571
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:985aed3994ae595864532241d9ce0fdf4eb4044ab6beaae4da742b3a2b90c2da
size 308576
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:470aeed5d3abc6fb21eecaadfde6b16bb86bbd2278801c52d2cc37fbef55c62a
size 392209
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:facf728f1536c7d00acafd257dad09c2ed1367148aa1b5164a07b2cdbe4dde9e
size 392223
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a67b104d4346028b5f5ad5e8855004bf44f474b93fff6ad6c50bcc148233d086
size 334360
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:690d8fe201590bbc90c37b7c380671cb690efe7da63600be6dfb022b305aa76d
size 334370
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28bc16380fcc42f1adf080debb22c7c9e6f3029570d35e50ffd0e43ae738eae3
size 470530
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:635726ad56629526a25eb8d83da083bf45873d7011e3b82fab5b286306daf03f
size 470468
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:853a2c5eb4cf8c20fc63521104d12fa91dbb19c43295de078190bb53db784ed9
size 260887
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6a672f9201b037026f1f9b35a381aa1eee3aadca8f57ee0a22e203af465fb100
size 260202
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:413c8d3858fa5305645ffb68c72656cb84c8b2c4b0a77b97b8daffe96dad1979
size 217456
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6be0f9379ea542e8031df14ed1335a887dd500705dcc501517b2c156d206d389
size 217490
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a76ada20f3e01b5ed78ea99dba471eea21df2b916448329985d6cd270ab2e5bb
size 293051
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:87f21c10d37eeb254843bb0f22ed366bdc7cdd064bc7b232fba615dd218cca7f
size 293058

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