mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-27 03:02:05 +08:00
Compare commits
370 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6741877fbd | |||
| 100ca65b39 | |||
| 519b666e37 | |||
| 35da93fa95 | |||
| ff4cce2677 | |||
| 87051803ab | |||
| f4e101c67d | |||
| 42f8875901 | |||
| f59a1bf003 | |||
| 0a1b6c705d | |||
| dae88e1ffb | |||
| fc425042ab | |||
| 629dcdcfca | |||
| 338b69be11 | |||
| 0a737d9a2e | |||
| f037d2216a | |||
| a51b83b4d8 | |||
| fea01767d9 | |||
| 282eae3c30 | |||
| b5958ebb60 | |||
| 40fb90a8a2 | |||
| 930fa18299 | |||
| 5bfad23442 | |||
| ac5cd06a3a | |||
| db5c0419ce | |||
| 2faa08c2d6 | |||
| 341e7a4384 | |||
| d7f4fbc1c2 | |||
| 2f71c94847 | |||
| 8b7e28d3a1 | |||
| 5fe1f5fa87 | |||
| 8aff0ce9c7 | |||
| 756d64e2c3 | |||
| 0af58e1820 | |||
| 0656521268 | |||
| 5d3f8bb04b | |||
| 4e2624783f | |||
| 39c64d44a1 | |||
| 1c19cbc437 | |||
| 48bceb2bbf | |||
| f37ee559fa | |||
| 6d392a2e7b | |||
| 431fd666fe | |||
| 8b074d3ed6 | |||
| 4bb00a042a | |||
| 4b70cc9286 | |||
| 44c3156fa4 | |||
| 73d9f6e05e | |||
| 95600b00c6 | |||
| 5cb7aed8ce | |||
| b87414c749 | |||
| 4d9ee68d16 | |||
| 7a6e686ec7 | |||
| 1a4ff8272b | |||
| 908aa525ec | |||
| cf355ecf20 | |||
| bdf9c90951 | |||
| 61abc05c8b | |||
| 63992fd164 | |||
| e2305d92e3 | |||
| 55446438ab | |||
| 13e58d33db | |||
| 7af3c6dfee | |||
| d8c9822421 | |||
| fe51a2fc62 | |||
| c013d8aa94 | |||
| be8485ca89 | |||
| b644555a1d | |||
| b14fca78e0 | |||
| 7b5f76ecf9 | |||
| 9b2cafe597 | |||
| 2a7c6bc8bd | |||
| 799539320d | |||
| 7a40c97068 | |||
| ee9977df2f | |||
| 08f64ae30a | |||
| ba098f509b | |||
| 542f3d1b44 | |||
| e735a7f379 | |||
| bf68eeb596 | |||
| 1eda5f4736 | |||
| 6a15c42143 | |||
| 51fae363e4 | |||
| 4baf6c1be9 | |||
| e6b2996478 | |||
| a255b8043a | |||
| c9f9eba614 | |||
| 6a5bbb261e | |||
| c2ab62c2b2 | |||
| 207c77ea93 | |||
| bce11e393f | |||
| f6780fca2f | |||
| b41f9f2dfe | |||
| 72b5c6f61a | |||
| d43bf89978 | |||
| 3e9b91a2ac | |||
| 424b657376 | |||
| 9d0180ca97 | |||
| 2ed567b0f5 | |||
| bcfb50d98c | |||
| f118d17659 | |||
| c61d504516 | |||
| 406939b9c0 | |||
| b9dec5e3b5 | |||
| 2bc5d2b635 | |||
| 585f362738 | |||
| 7248b00086 | |||
| cb61d0045c | |||
| 9f14c447db | |||
| 29882b4519 | |||
| 63a38dcd4d | |||
| d65e1d9500 | |||
| 1dcd660815 | |||
| 65fccbf756 | |||
| 9734015bbb | |||
| 96a658648d | |||
| cf39cc823a | |||
| 3d2fbe9aa3 | |||
| 37e4a32454 | |||
| 4cb1c665e0 | |||
| 90ce7781f4 | |||
| 4618e8c124 | |||
| 8515ac1764 | |||
| 5bc5b213a0 | |||
| 308000dd82 | |||
| 7ec9986340 | |||
| 4e122ed2d1 | |||
| 96a4877e9f | |||
| 093c09a737 | |||
| d330358728 | |||
| 2dab8b31f2 | |||
| 82c2ec7208 | |||
| 118932acd3 | |||
| 85d8d0eddd | |||
| ee62b9c88b | |||
| ea05474df2 | |||
| 4300f37cc4 | |||
| b9fe84f84d | |||
| c06d975ec4 | |||
| 1b554b488e | |||
| 4d0b54e80b | |||
| 2ff051ba53 | |||
| a8c0c158ad | |||
| 80653bfb59 | |||
| a604dcc524 | |||
| ad33cae40e | |||
| 9e648e428d | |||
| 9880b1393c | |||
| 87f183f43c | |||
| bd4f0cec18 | |||
| 40e54a3b4f | |||
| eb50f5cae8 | |||
| f8f6c39915 | |||
| 51bd368214 | |||
| 184519834c | |||
| ba7a60c5a2 | |||
| 3af774725f | |||
| 30467b44cd | |||
| 10f27a6a1b | |||
| 8d961a12e5 | |||
| a4de8739e9 | |||
| fb560e81ef | |||
| 16c36b0d8b | |||
| ec9149c20e | |||
| 1c770c4ed7 | |||
| 6c837332ea | |||
| 5909bcde62 | |||
| 3d02c03001 | |||
| e9e2e97831 | |||
| 33bf4bbb13 | |||
| d00a539830 | |||
| 5a1596a322 | |||
| d1140cc644 | |||
| 86aeb123bc | |||
| 04b636e3f2 | |||
| 87c6afccf7 | |||
| 5c1e111d8a | |||
| 06216d43bb | |||
| 29b58d4f2f | |||
| 44c7144e1c | |||
| c7cf6f6568 | |||
| 7a7200cbda | |||
| 12a7b7f7fb | |||
| 4706d9e2d1 | |||
| 3b3ffb7b2b | |||
| 8e0a4f2faf | |||
| c8d8db5947 | |||
| 3fd4b2f676 | |||
| e1a493e13b | |||
| 54cd2a6ed2 | |||
| 8f9b165de8 | |||
| 9474523add | |||
| cafca4f891 | |||
| 2cd9975e4f | |||
| c40d129f70 | |||
| 19dec54f65 | |||
| 8ab587d30b | |||
| ea5ee29ebd | |||
| 2189164d45 | |||
| 8f3fc699d4 | |||
| 13511e383c | |||
| 4b11c9e914 | |||
| 5b4b7a08fc | |||
| bfa8e0b2ec | |||
| d0671bda6d | |||
| 7ee9d2d1b9 | |||
| 7bf912f407 | |||
| 3e66827a85 | |||
| 16ea2ff270 | |||
| 3ccc63deec | |||
| 7de618a5cf | |||
| 7c112341c3 | |||
| ebff7cab1a | |||
| 1dd8bdc791 | |||
| bf003f2972 | |||
| ac130001cc | |||
| 0dddc97dca | |||
| 1b6ac2d876 | |||
| 80f9278a73 | |||
| 7824074aae | |||
| 42f2601416 | |||
| b6d124d268 | |||
| 661ef03a24 | |||
| 76fd5b00f1 | |||
| 0739d79a51 | |||
| 0fe143e4a7 | |||
| 086dcfe715 | |||
| 9536dd07c6 | |||
| 0b29db5c3e | |||
| 4e73b76a12 | |||
| dfd387520e | |||
| 86d8d1d996 | |||
| 11cb2d3a0b | |||
| 84cff4fc03 | |||
| 6e185f4eea | |||
| 43dcddc68b | |||
| ade13722cd | |||
| 7d6ff19dea | |||
| 2728c95b0d | |||
| 606890cba5 | |||
| 01c0756974 | |||
| 1ae3adbe13 | |||
| 5ebc65f254 | |||
| 691b948ad0 | |||
| 4fbac089f8 | |||
| 583e89d3a4 | |||
| c51f37f63e | |||
| 1b3b5ab758 | |||
| 4caecf2143 | |||
| 7dec7c39be | |||
| 6f1ea5a1fd | |||
| c8d5a3fe25 | |||
| d7159cd3c7 | |||
| db2a8e9506 | |||
| eab9cd751c | |||
| 6b5f88a533 | |||
| 00d9748d9a | |||
| a1d2e84212 | |||
| d24b80fca4 | |||
| a1dce6ef47 | |||
| e68bb26e14 | |||
| f39c5c22e8 | |||
| d128dbe27f | |||
| 8827067eae | |||
| 02e30ac140 | |||
| 3c192cbf88 | |||
| e5b803f28e | |||
| fb1ad1d26a | |||
| ccd369ee96 | |||
| 1989fbd4c4 | |||
| 173a633a75 | |||
| c8622c9553 | |||
| ed86910536 | |||
| cd8a603ad0 | |||
| 313a2826c2 | |||
| 2da4aef268 | |||
| 75f49f84f3 | |||
| edd8759f39 | |||
| 6cdf2a1499 | |||
| 4ac938a578 | |||
| 71ad5a8dee | |||
| add958bb08 | |||
| e38a1428aa | |||
| 31036771ee | |||
| 2221ffcf0e | |||
| 3446941107 | |||
| d49c5193c3 | |||
| 0fa6745a67 | |||
| bd8dd65ce0 | |||
| 18c310addf | |||
| 3382002cd0 | |||
| f60dfd4dbb | |||
| 1e9738131d | |||
| 3bc1b173d2 | |||
| fbbd4ee692 | |||
| 9b8c1693c9 | |||
| 29d0bfe1ab | |||
| ef5d6a0466 | |||
| e7ec1b8ff1 | |||
| d828ac4344 | |||
| 93eb7ee0cc | |||
| fb33366144 | |||
| bd00a9d800 | |||
| a654e5bd05 | |||
| 8d77cea3a5 | |||
| 5e0aff92ae | |||
| 1da71f5c3c | |||
| dcdac84f0c | |||
| 27faa8f82b | |||
| cefe00c964 | |||
| dc886e195f | |||
| 1aa467cb00 | |||
| 0907b30d7b | |||
| 07fcc4825f | |||
| 917ea5699f | |||
| c96dbd5a0b | |||
| fd5549bba1 | |||
| 560e37cd83 | |||
| f31ad97e92 | |||
| 3c48a6154b | |||
| 7f9cdf8e43 | |||
| 996bced674 | |||
| 4b794773b0 | |||
| aa8484093e | |||
| 00af33c6ed | |||
| c0739cd9ee | |||
| d684d8f0f6 | |||
| 35a4a773f1 | |||
| 83d4623590 | |||
| dd2787b7a1 | |||
| c759fe9002 | |||
| cbee4421da | |||
| 7ed3f62f0c | |||
| e7388c3743 | |||
| 75b07c042f | |||
| 953e5667b1 | |||
| 50f55684a2 | |||
| 0f34e6e3b6 | |||
| 32a5cfd84c | |||
| f1416f337c | |||
| 122a7f2f0f | |||
| 2156870df9 | |||
| e3e54fb28b | |||
| 71dd1e2ff6 | |||
| 11db7b683b | |||
| b247c3caaa | |||
| e36ff90996 | |||
| c17c34187b | |||
| fbc53a24a3 | |||
| 5efdaf2026 | |||
| 0c58e35b6c | |||
| 133f25eecb | |||
| 35df0a4fda | |||
| 481e5b28bd | |||
| 6745c66352 | |||
| 8c6c6e435f | |||
| f6189568ea | |||
| 15d3397ec6 | |||
| 4014109666 | |||
| 67038d5b59 | |||
| 36815cc6d5 | |||
| 31ff8eda9c | |||
| fa2f7a4dd4 | |||
| 12d729a0a0 | |||
| 76686e1976 | |||
| 012eb07466 | |||
| 4a696984f1 | |||
| 3c74ad145e | |||
| 241fb902af | |||
| 4445fa31f5 |
@@ -1,14 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Join the Discord
|
||||
url: https://discord.comma.ai
|
||||
about: The community Discord is for both openpilot development and experience discussion
|
||||
- name: Report model bugs
|
||||
url: https://github.com/commaai/openpilot/discussions/categories/model-feedback
|
||||
about: Provide feedback for the driving or driver monitoring models
|
||||
- name: Discussions
|
||||
url: https://github.com/commaai/openpilot/discussions
|
||||
about: For questions and general discussion about openpilot
|
||||
url: https://discord.com/channels/469524606043160576/1254834193066623017
|
||||
about: Feedback for the driving and driver monitoring models goes in the #driving-feedback in Discord
|
||||
- name: Community Wiki
|
||||
url: https://github.com/commaai/openpilot/wiki
|
||||
about: Check out our community wiki
|
||||
- name: Community Discord
|
||||
url: https://discord.comma.ai
|
||||
about: Check out our community discord
|
||||
|
||||
@@ -8,7 +8,7 @@ assignees: ''
|
||||
|
||||
**Checklist**
|
||||
|
||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
|
||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/opcar/docs.py` to generate new docs
|
||||
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
|
||||
- [ ] route with openpilot:
|
||||
- [ ] route with stock system:
|
||||
|
||||
+2
-54
@@ -4,59 +4,7 @@ CI / testing:
|
||||
|
||||
car:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/**'
|
||||
|
||||
body:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/body/*'
|
||||
|
||||
chrysler:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/chrysler/*'
|
||||
|
||||
ford:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/ford/*'
|
||||
|
||||
gm:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/gm/*'
|
||||
|
||||
honda:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/honda/*'
|
||||
|
||||
hyundai:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/hyundai/*'
|
||||
|
||||
mazda:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/mazda/*'
|
||||
|
||||
nissan:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/nissan/*'
|
||||
|
||||
subaru:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/subaru/*'
|
||||
|
||||
tesla:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/telsa/*'
|
||||
|
||||
toyota:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/toyota/*'
|
||||
|
||||
volkswagen:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/volkswagen/*'
|
||||
|
||||
fingerprint:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/car/*/fingerprints.py'
|
||||
- any-glob-to-all-files: '{selfdrive/car/**,opendbc_repo}'
|
||||
|
||||
simulation:
|
||||
- changed-files:
|
||||
@@ -74,6 +22,6 @@ multilanguage:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: 'selfdrive/ui/translations/**'
|
||||
|
||||
research:
|
||||
autonomy:
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit}"
|
||||
|
||||
@@ -44,7 +44,7 @@ Explain how you tested this bug fix.
|
||||
|
||||
**Checklist**
|
||||
|
||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
|
||||
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/opcar/docs.py` to generate new docs
|
||||
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
|
||||
- [ ] route with openpilot:
|
||||
- [ ] route with stock system:
|
||||
|
||||
@@ -35,11 +35,12 @@ jobs:
|
||||
already-exists-comment: "Your PR should be made against the `master` branch"
|
||||
|
||||
# Welcome comment
|
||||
- name: comment
|
||||
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6
|
||||
- name: "First timers PR"
|
||||
uses: actions/first-interaction@v1
|
||||
if: github.event.pull_request.head.repo.full_name != 'commaai/openpilot'
|
||||
with:
|
||||
message: |
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pr-message: |
|
||||
<!-- _(run_id **${{ github.run_id }}**)_ -->
|
||||
Thanks for contributing to openpilot! In order for us to review your PR as quickly as possible, check the following:
|
||||
* Convert your PR to a draft unless it's ready to review
|
||||
@@ -49,5 +50,4 @@ jobs:
|
||||
* all the tests are passing
|
||||
* the change is [something we merge](https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md#what-gets-merged)
|
||||
* include a route or your device' dongle ID if relevant
|
||||
comment_tag: run_id
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
env:
|
||||
BASE_IMAGE: openpilot-base
|
||||
DOCKER_REGISTRY: ghcr.io/commaai
|
||||
RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/bash -c
|
||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $DOCKER_REGISTRY/$BASE_IMAGE:latest /bin/bash -c
|
||||
|
||||
jobs:
|
||||
badges:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Push badges
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) && python selfdrive/ui/translations/create_badges.py"
|
||||
${{ env.RUN }} "scons -j$(nproc) && python3 selfdrive/ui/translations/create_badges.py"
|
||||
|
||||
rm .gitattributes
|
||||
|
||||
|
||||
@@ -10,38 +10,30 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
CI_RUNS: ${{ github.event.inputs.ci_runs || '50' }}
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
ci_runs: ${{ steps.ci_runs_setup.outputs.value }}
|
||||
ci_runs: ${{ steps.ci_runs_setup.outputs.matrix }}
|
||||
steps:
|
||||
- id: ci_runs_setup
|
||||
name: CI_RUNS=${{ env.CI_RUNS }}
|
||||
run: |
|
||||
CI_RUNS=${{ inputs.ci_runs || '50' }}
|
||||
mylist="value=["
|
||||
matrix=$(python3 -c "import json; print(json.dumps({ 'run_number' : list(range(${{ env.CI_RUNS }})) }))")
|
||||
echo "matrix=$matrix" >> $GITHUB_OUTPUT
|
||||
|
||||
for i in $(seq 1 $CI_RUNS);
|
||||
do
|
||||
if [ $i != $CI_RUNS ]; then
|
||||
mylist+="\"$i\", "
|
||||
else
|
||||
mylist+="\"$i\"]"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$mylist" >> $GITHUB_OUTPUT
|
||||
echo "Number of CI runs for report: $CI_RUNS"
|
||||
ci_matrix_run:
|
||||
needs: [ setup ]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
value: ${{fromJSON(needs.setup.outputs.ci_runs)}}
|
||||
matrix: ${{fromJSON(needs.setup.outputs.ci_runs)}}
|
||||
uses: commaai/openpilot/.github/workflows/ci_weekly_run.yaml@master
|
||||
with:
|
||||
run_number: ${{ matrix.value }}
|
||||
run_number: ${{ matrix.run_number }}
|
||||
|
||||
report:
|
||||
needs: [ci_matrix_run]
|
||||
@@ -62,62 +54,48 @@ jobs:
|
||||
})
|
||||
var report = {}
|
||||
jobs.slice(1, jobs.length-1).forEach(job => {
|
||||
const jobName = job.name.split('/')[2].trim();
|
||||
report[jobName] = report[jobName] || { successes: [], failures: [], cancelled: [] };
|
||||
if (job.conclusion === "skipped") return;
|
||||
const jobName = job.name.split(" / ")[2];
|
||||
const runRegex = /\((.*?)\)/;
|
||||
const run = job.name.match(runRegex)[1];
|
||||
report[jobName] = report[jobName] || { successes: [], failures: [], canceled: [] };
|
||||
switch (job.conclusion) {
|
||||
case "success":
|
||||
report[jobName].successes.push(job.html_url); break;
|
||||
report[jobName].successes.push({ "run_number": run, "link": job.html_url}); break;
|
||||
case "failure":
|
||||
report[jobName].failures.push(job.html_url); break;
|
||||
case "cancelled":
|
||||
report[jobName].cancelled.push(job.html_url); break;
|
||||
report[jobName].failures.push({ "run_number": run, "link": job.html_url }); break;
|
||||
case "canceled":
|
||||
report[jobName].canceled.push({ "run_number": run, "link": job.html_url }); break;
|
||||
}
|
||||
});
|
||||
return JSON.stringify(report);
|
||||
return JSON.stringify({"jobs": report});
|
||||
|
||||
- name: Add job results to summary
|
||||
env:
|
||||
JOB_RESULTS: ${{ fromJSON(steps.get-job-results.outputs.result) }}
|
||||
run: |
|
||||
echo $JOB_RESULTS > job_results.json
|
||||
generate_html_table() {
|
||||
echo "<table>"
|
||||
echo "<thead>"
|
||||
echo " <tr>"
|
||||
echo " <th>Job</th>"
|
||||
echo " <th>Succeeded ✅</th>"
|
||||
echo " <th>Failed ❌</th>"
|
||||
echo " <th>Cancelled (timed out) ⏰</th>"
|
||||
echo " </tr>"
|
||||
echo "</thead>"
|
||||
jq -r '
|
||||
"<tbody>",
|
||||
keys[] as $job |
|
||||
"<tr>",
|
||||
" <td>\($job)</td>",
|
||||
" <td>",
|
||||
" <details>",
|
||||
" <summary>(\(.[$job].successes | length))</summary>",
|
||||
" \(.[$job].successes[])<br>",
|
||||
" </details>",
|
||||
" </td>",
|
||||
" <td>",
|
||||
" <details>",
|
||||
" <summary>(\(.[$job].failures | length))</summary>",
|
||||
" \(.[$job].failures[])<br>",
|
||||
" </details>",
|
||||
" </td>",
|
||||
" <td>",
|
||||
" <details>",
|
||||
" <summary>(\(.[$job].cancelled | length))</summary>",
|
||||
" \(.[$job].cancelled[])<br>",
|
||||
" </details>",
|
||||
" </td>",
|
||||
"</tr>"
|
||||
' job_results.json
|
||||
echo "</tbody>"
|
||||
echo "</table>"
|
||||
}
|
||||
echo "# CI Job Summary" >> $GITHUB_STEP_SUMMARY
|
||||
generate_html_table >> $GITHUB_STEP_SUMMARY
|
||||
cat <<EOF >> template.html
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Job</th>
|
||||
<th>✅ Passing</th>
|
||||
<th>❌ Failure Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key in jobs.keys() %}<tr>
|
||||
<td>{% for i in range(5) %}{% if i+1 <= (5 * jobs[key]["successes"]|length // ${{ env.CI_RUNS }}) %}🟩{% else %}🟥{% endif %}{% endfor%}</td>
|
||||
<td>{{ key }}</td>
|
||||
<td>{{ 100 * jobs[key]["successes"]|length // ${{ env.CI_RUNS }} }}%</td>
|
||||
<td>{% if jobs[key]["failures"]|length > 0 %}<details>{% for failure in jobs[key]["failures"] %}<a href="{{ failure['link'] }}">Log for run #{{ failure['run_number'] }}</a><br>{% endfor %}</details>{% else %}{% endif %}</td>
|
||||
</td>
|
||||
</tr>{% endfor %}
|
||||
</table>
|
||||
EOF
|
||||
|
||||
pip install jinja2-cli
|
||||
echo $JOB_RESULTS | jinja2 template.html > report.html
|
||||
echo "# CI Test Report - ${{ env.CI_RUNS }} Runs" >> $GITHUB_STEP_SUMMARY
|
||||
cat report.html >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
+12
-18
@@ -15,31 +15,24 @@ concurrency:
|
||||
group: docs-tests-ci-run-${{ inputs.run_number }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.run_id || github.head_ref || github.ref }}-${{ github.workflow }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BASE_IMAGE: openpilot-base
|
||||
|
||||
BUILD: selfdrive/test/docker_build.sh base
|
||||
|
||||
RUN: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: build docs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
if: false # TODO: replace this with the new docs
|
||||
timeout-minutes: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Build openpilot
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc)"
|
||||
|
||||
# Build
|
||||
- name: Build docs
|
||||
run: |
|
||||
${{ env.RUN }} "apt update && apt install -y doxygen && cd docs && make -j$(nproc) html"
|
||||
# TODO: can we install just the "docs" dependency group without the normal deps?
|
||||
pip install mkdocs
|
||||
mkdocs build
|
||||
|
||||
# Push to docs.comma.ai
|
||||
- uses: actions/checkout@v4
|
||||
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
|
||||
with:
|
||||
@@ -54,16 +47,17 @@ jobs:
|
||||
source release/identity.sh
|
||||
|
||||
cd openpilot-docs
|
||||
|
||||
git checkout --orphan tmp
|
||||
git rm -rf .
|
||||
|
||||
cp -r ../build/docs/html/ docs/
|
||||
cp -r ../docs/README.md .
|
||||
# copy over docs
|
||||
cp -r ../docs_site/ docs/
|
||||
|
||||
# GitHub pages config
|
||||
touch docs/.nojekyll
|
||||
echo -n docs.comma.ai > docs/CNAME
|
||||
git add -f .
|
||||
|
||||
git add -f .
|
||||
git commit -m "build docs"
|
||||
|
||||
# docs live in different repo to not bloat openpilot's full clone size
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
name: jenkins scan
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
jobs:
|
||||
# TODO: gc old branches in a separate job in this workflow
|
||||
scan-comments:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
steps:
|
||||
- name: Check for trigger phrase
|
||||
id: check_comment
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const triggerPhrase = "trigger-jenkins";
|
||||
const comment = context.payload.comment.body;
|
||||
const commenter = context.payload.comment.user.login;
|
||||
|
||||
const { data: permissions } = await github.rest.repos.getCollaboratorPermissionLevel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
username: commenter
|
||||
});
|
||||
|
||||
const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin';
|
||||
|
||||
return (hasWriteAccess && comment.includes(triggerPhrase));
|
||||
result-encoding: json
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/pull/${{ github.event.issue.number }}/head
|
||||
|
||||
- name: Push to tmp-jenkins branch
|
||||
if: steps.check_comment.outputs.result == 'true'
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git checkout -b tmp-jenkins-${{ github.event.issue.number }}
|
||||
GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }}
|
||||
@@ -6,33 +6,6 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
bump_submodules:
|
||||
name: bump_submodules
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/commaai/openpilot-base:latest
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: bump submodules
|
||||
run: |
|
||||
git config --global --add safe.directory '*'
|
||||
git -c submodule."tinygrad".update=none submodule update --remote
|
||||
git add .
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
|
||||
with:
|
||||
author: Vehicle Researcher <user@comma.ai>
|
||||
token: ${{ secrets.ACTIONS_CREATE_PR_PAT }}
|
||||
commit-message: bump submodules
|
||||
title: '[bot] Bump submodules'
|
||||
branch: auto-bump-submodules
|
||||
base: master
|
||||
delete-branch: true
|
||||
body: 'Automatic PR from repo-maintenance -> bump_submodules'
|
||||
labels: bot
|
||||
package_updates:
|
||||
name: package_updates
|
||||
runs-on: ubuntu-latest
|
||||
@@ -41,22 +14,30 @@ jobs:
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: uv lock
|
||||
run: |
|
||||
python3 -m ensurepip --upgrade
|
||||
pip3 install uv
|
||||
uv lock --upgrade
|
||||
- name: pre-commit autoupdate
|
||||
- name: bump submodules
|
||||
run: |
|
||||
git config --global --add safe.directory '*'
|
||||
pre-commit autoupdate
|
||||
git -c submodule."tinygrad".update=none submodule update --remote
|
||||
git add .
|
||||
- name: update car docs
|
||||
run: |
|
||||
scons -j$(nproc) --minimal opendbc
|
||||
PYTHONPATH=. python selfdrive/car/docs.py
|
||||
git add docs/CARS.md
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
|
||||
with:
|
||||
author: Vehicle Researcher <user@comma.ai>
|
||||
token: ${{ secrets.ACTIONS_CREATE_PR_PAT }}
|
||||
commit-message: Update Python packages and pre-commit hooks
|
||||
title: '[bot] Update Python packages and pre-commit hooks'
|
||||
commit-message: Update Python packages
|
||||
title: '[bot] Update Python packages'
|
||||
branch: auto-package-updates
|
||||
base: master
|
||||
delete-branch: true
|
||||
|
||||
@@ -25,7 +25,7 @@ env:
|
||||
DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
|
||||
BUILD: selfdrive/test/docker_build.sh base
|
||||
|
||||
RUN: docker run --shm-size 1G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -e PRE_COMMIT_HOME=/tmp/pre-commit -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/pre-commit:/tmp/pre-commit -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
||||
RUN: docker run --shm-size 2G -v $PWD:/tmp/openpilot -w /tmp/openpilot -e CI=1 -e PYTHONWARNINGS=error -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
||||
|
||||
PYTEST: pytest --continue-on-collection-errors --cov --cov-report=xml --cov-append --durations=0 --durations-min=5 --hypothesis-seed 0 -n logical
|
||||
|
||||
@@ -45,7 +45,6 @@ jobs:
|
||||
- name: Build devel
|
||||
timeout-minutes: 1
|
||||
run: TARGET_DIR=$STRIPPED_DIR release/build_devel.sh
|
||||
- uses: ./.github/workflows/setup-pre-commit
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Check submodules
|
||||
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
|
||||
@@ -55,27 +54,29 @@ jobs:
|
||||
timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache
|
||||
run: |
|
||||
cd $STRIPPED_DIR
|
||||
${{ env.RUN }} "python system/manager/build.py"
|
||||
${{ env.RUN }} "python3 system/manager/build.py"
|
||||
- name: Run tests
|
||||
timeout-minutes: 3
|
||||
run: |
|
||||
cd $STRIPPED_DIR
|
||||
${{ env.RUN }} "release/check-dirty.sh && \
|
||||
MAX_EXAMPLES=5 $PYTEST -m 'not slow' selfdrive/car"
|
||||
- name: pre-commit
|
||||
timeout-minutes: 3
|
||||
- name: Static analysis
|
||||
timeout-minutes: 1
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
cp .pre-commit-config.yaml $STRIPPED_DIR
|
||||
cp pyproject.toml $STRIPPED_DIR
|
||||
cd $STRIPPED_DIR
|
||||
${{ env.RUN }} "unset PYTHONWARNINGS && SKIP=check-added-large-files,check-hooks-apply,check-useless-excludes pre-commit run --all && chmod -R 777 /tmp/pre-commit"
|
||||
${{ env.RUN }} "scripts/lint/lint.sh --skip check_added_large_files"
|
||||
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
arch: ${{ fromJson('["x86_64"]') }} # TODO: Re-add build test for aarch64 once we switched to ubuntu-2404
|
||||
runs-on: ubuntu-latest
|
||||
arch: ${{ fromJson(
|
||||
((github.repository == 'commaai/openpilot') &&
|
||||
((github.event_name != 'pull_request') ||
|
||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && '["x86_64", "aarch64"]' || '["x86_64"]' ) }}
|
||||
runs-on: ${{ (matrix.arch == 'aarch64') && 'namespace-profile-arm64-2x8' || 'ubuntu-latest' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -84,7 +85,7 @@ jobs:
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
|
||||
run: |
|
||||
echo "PUSH_IMAGE=true" >> "$GITHUB_ENV"
|
||||
: # (TODO: Re-add this once we test other archs) echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV"
|
||||
echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV"
|
||||
$DOCKER_LOGIN
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
with:
|
||||
@@ -93,7 +94,7 @@ jobs:
|
||||
timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 15 || 30) }} # allow more time when we missed the scons cache
|
||||
|
||||
build_mac:
|
||||
name: build macos
|
||||
name: build macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -103,28 +104,51 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: ./tools/mac_setup.sh
|
||||
env:
|
||||
SKIP_PROMPT: 1
|
||||
# package install has DeprecationWarnings
|
||||
PYTHONWARNINGS: default
|
||||
- name: Test openpilot environment
|
||||
run: . .venv/bin/activate && scons -h
|
||||
- run: echo "CACHE_COMMIT_DATE=$(git log -1 --pretty='format:%cd' --date=format:'%Y-%m-%d-%H:%M')" >> $GITHUB_ENV
|
||||
- name: Getting scons cache
|
||||
uses: 'actions/cache@v4'
|
||||
with:
|
||||
path: /tmp/scons_cache
|
||||
key: scons-${{ runner.arch }}-macos-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
scons-${{ runner.arch }}-macos-${{ env.CACHE_COMMIT_DATE }}
|
||||
scons-${{ runner.arch }}-macos
|
||||
- name: Building openpilot
|
||||
run: . .venv/bin/activate && scons -j$(nproc)
|
||||
|
||||
docker_push_multiarch:
|
||||
name: docker push multiarch tag
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
- name: Setup docker
|
||||
run: |
|
||||
$DOCKER_LOGIN
|
||||
- name: Merge x64 and arm64 tags
|
||||
run: |
|
||||
export PUSH_IMAGE=true
|
||||
scripts/retry.sh selfdrive/test/docker_tag_multiarch.sh base x86_64 aarch64
|
||||
|
||||
static_analysis:
|
||||
name: static analysis
|
||||
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
|
||||
((github.event_name != 'pull_request') ||
|
||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }}
|
||||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
|
||||
env:
|
||||
PYTHONWARNINGS: default
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- uses: ./.github/workflows/setup-pre-commit
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Build openpilot
|
||||
run: ${{ env.RUN }} "scons -j$(nproc)"
|
||||
- name: pre-commit
|
||||
timeout-minutes: 4
|
||||
run: ${{ env.RUN }} "unset PYTHONWARNINGS && pre-commit run --all && chmod -R 777 /tmp/pre-commit"
|
||||
- name: Setup
|
||||
run: tools/op.sh setup
|
||||
- name: Static analysis
|
||||
timeout-minutes: 1
|
||||
run: tools/op.sh lint
|
||||
|
||||
unit_tests:
|
||||
name: unit tests
|
||||
@@ -197,7 +221,7 @@ jobs:
|
||||
- name: Upload reference logs
|
||||
if: ${{ failure() && steps.print-diff.outcome == 'success' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
|
||||
run: |
|
||||
${{ env.RUN }} "unset PYTHONWARNINGS && AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
|
||||
${{ env.RUN }} "unset PYTHONWARNINGS && AZURE_TOKEN='$AZURE_TOKEN' python3 selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
|
||||
# PYTHONWARNINGS triggers a SyntaxError in onnxruntime
|
||||
- name: Run model replay with ONNX
|
||||
timeout-minutes: 4
|
||||
@@ -257,7 +281,8 @@ jobs:
|
||||
car_docs_diff:
|
||||
name: PR comments
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
#if: github.event_name == 'pull_request'
|
||||
if: false # TODO: run this in opendbc?
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -267,7 +292,7 @@ jobs:
|
||||
- uses: ./.github/workflows/setup-with-retry
|
||||
- name: Get base car info
|
||||
run: |
|
||||
${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs"
|
||||
${{ env.RUN }} "scons -j$(nproc) && python3 selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs"
|
||||
sudo chown -R $USER:$USER ${{ github.workspace }}
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -279,7 +304,7 @@ jobs:
|
||||
run: |
|
||||
cd current
|
||||
${{ env.RUN }} "scons -j$(nproc)"
|
||||
output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs")
|
||||
output=$(${{ env.RUN }} "python3 selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs")
|
||||
output="${output//$'\n'/'%0A'}"
|
||||
echo "::set-output name=diff::$output"
|
||||
- name: Find comment
|
||||
@@ -309,8 +334,10 @@ jobs:
|
||||
})
|
||||
|
||||
create_ui_report:
|
||||
# This job name needs to be the same as UI_JOB_NAME in ui_preview.yaml
|
||||
name: Create UI Report
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -322,59 +349,9 @@ jobs:
|
||||
run: >
|
||||
${{ env.RUN }} "PYTHONWARNINGS=ignore &&
|
||||
source selfdrive/test/setup_xvfb.sh &&
|
||||
python selfdrive/ui/tests/test_ui/run.py"
|
||||
python3 selfdrive/ui/tests/test_ui/run.py"
|
||||
- name: Upload Test Report
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: report-${{ inputs.run_number }}
|
||||
path: selfdrive/ui/tests/test_ui/report_${{ inputs.run_number }}
|
||||
- name: Get changes to selfdrive/ui
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v44
|
||||
with:
|
||||
files: |
|
||||
selfdrive/ui/**
|
||||
- name: Checkout ci-artifacts
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
ref: master
|
||||
- name: Push Screenshots
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||
run: |
|
||||
git checkout -b openpilot/pr-${{ github.event.pull_request.number }}
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
sudo mv ${{ github.workspace }}/selfdrive/ui/tests/test_ui/report/screenshots/* .
|
||||
git add .
|
||||
git commit -m "screenshots for PR #${{ github.event.pull_request.number }}"
|
||||
git push origin openpilot/pr-${{ github.event.pull_request.number }} --force
|
||||
- name: Comment Screenshots on PR
|
||||
if: ${{ github.event_name == 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
<!-- _(run_id_screenshots **${{ github.run_id }}**)_ -->
|
||||
## UI Screenshots
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/homescreen.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad_map.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/onroad_sidebar.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/settings_network.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.pull_request.number }}/settings_device.png"></td>
|
||||
</tr>
|
||||
</table>
|
||||
comment_tag: run_id_screenshots
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: report-${{ github.event.number }}
|
||||
path: selfdrive/ui/tests/test_ui/report_1/screenshots
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
name: 'set up pre-commit environment'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: ./.github/workflows/auto-cache
|
||||
with:
|
||||
path: .ci_cache/pre-commit
|
||||
key: pre-commit-${{ hashFiles('**/.pre-commit-config.yaml') }}
|
||||
restore-keys: |
|
||||
pre-commit-
|
||||
save: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot' }}
|
||||
@@ -5,8 +5,8 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DAYS_BEFORE_PR_CLOSE: 3
|
||||
DAYS_BEFORE_PR_STALE: 14
|
||||
DAYS_BEFORE_PR_CLOSE: 2
|
||||
DAYS_BEFORE_PR_STALE: 9
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
@@ -21,7 +21,7 @@ env:
|
||||
|
||||
BUILD: selfdrive/test/docker_build.sh base
|
||||
|
||||
RUN: docker run --shm-size 1G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
||||
RUN: docker run --shm-size 2G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
|
||||
|
||||
|
||||
jobs:
|
||||
@@ -73,12 +73,6 @@ jobs:
|
||||
scons-${{ runner.arch }}-ubuntu2004
|
||||
- name: Building openpilot
|
||||
run: uv run scons -u -j$(nproc)
|
||||
- name: Saving scons cache
|
||||
uses: actions/cache/save@v4
|
||||
if: github.ref == 'refs/heads/master'
|
||||
with:
|
||||
path: /tmp/scons_cache
|
||||
key: scons-${{ runner.arch }}-ubuntu2004-${{ env.CACHE_COMMIT_DATE }}-${{ github.sha }}
|
||||
|
||||
devcontainer:
|
||||
name: devcontainer
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
name: "ui preview"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [assigned, opened, synchronize, reopened, edited]
|
||||
branches:
|
||||
- 'master'
|
||||
paths:
|
||||
- 'selfdrive/ui/**'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UI_JOB_NAME: "Create UI Report"
|
||||
|
||||
jobs:
|
||||
preview:
|
||||
if: github.repository == 'commaai/openpilot'
|
||||
name: preview
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Waiting for ui test to start
|
||||
run: sleep 30
|
||||
|
||||
- name: Wait for ui report
|
||||
uses: lewagon/wait-on-check-action@v1.3.4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
check-name: ${{ env.UI_JOB_NAME }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
allowed-conclusions: success
|
||||
wait-interval: 20
|
||||
|
||||
- name: Get workflow run ID
|
||||
id: get_run_id
|
||||
run: |
|
||||
echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ github.event.pull_request.head.sha }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?<number>[0-9]+)") | .number')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout ci-artifacts
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
ref: master
|
||||
|
||||
- name: Download artifact
|
||||
id: download-artifact
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run_id: ${{ steps.get_run_id.outputs.run_id }}
|
||||
search_artifacts: true
|
||||
name: report-${{ github.event.number }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
|
||||
- name: Push Screenshots
|
||||
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||
run: |
|
||||
git checkout -b openpilot/pr-${{ github.event.number }}
|
||||
git config user.name "GitHub Actions Bot"
|
||||
git config user.email "<>"
|
||||
git add ${{ github.workspace }}/ci-artifacts/*
|
||||
git commit -m "screenshots for PR #${{ github.event.number }}"
|
||||
git push origin openpilot/pr-${{ github.event.number }} --force
|
||||
|
||||
- name: Comment Screenshots on PR
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
<!-- _(run_id_screenshots **${{ github.run_id }}**)_ -->
|
||||
## UI Screenshots
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/homescreen.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/settings_network.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_sidebar.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_wide.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_wide_sidebar.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/settings_device.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_alert_small.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_alert_mid.png"></td>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/onroad_alert_full.png"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://raw.githubusercontent.com/commaai/ci-artifacts/openpilot/pr-${{ github.event.number }}/driver_camera.png"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
comment_tag: run_id_screenshots
|
||||
pr_number: ${{ github.event.number }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+3
-1
@@ -14,6 +14,8 @@ model2.png
|
||||
a.out
|
||||
.hypothesis
|
||||
|
||||
/docs_site/
|
||||
|
||||
*.dylib
|
||||
*.DSYM
|
||||
*.d
|
||||
@@ -102,4 +104,4 @@ Pipfile
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
.ionide
|
||||
|
||||
+2
-5
@@ -2,7 +2,7 @@
|
||||
path = panda
|
||||
url = ../../commaai/panda.git
|
||||
[submodule "opendbc"]
|
||||
path = opendbc
|
||||
path = opendbc_repo
|
||||
url = ../../commaai/opendbc.git
|
||||
[submodule "msgq"]
|
||||
path = msgq_repo
|
||||
@@ -10,12 +10,9 @@
|
||||
[submodule "rednose_repo"]
|
||||
path = rednose_repo
|
||||
url = ../../commaai/rednose.git
|
||||
[submodule "body"]
|
||||
path = body
|
||||
url = ../../commaai/body.git
|
||||
[submodule "teleoprtc_repo"]
|
||||
path = teleoprtc_repo
|
||||
url = ../../commaai/teleoprtc
|
||||
[submodule "tinygrad"]
|
||||
path = tinygrad_repo
|
||||
url = https://github.com/geohot/tinygrad.git
|
||||
url = https://github.com/tinygrad/tinygrad.git
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
exclude: '^(tinygrad_repo)'
|
||||
repos:
|
||||
- repo: meta
|
||||
hooks:
|
||||
- id: check-hooks-apply
|
||||
- id: check-useless-excludes
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: check-ast
|
||||
exclude: '^(third_party)/'
|
||||
- id: check-json
|
||||
exclude: '.devcontainer/devcontainer.json|.vscode/' # these support JSON with comments
|
||||
- id: check-toml
|
||||
- id: check-xml
|
||||
- id: check-yaml
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-added-large-files
|
||||
exclude: '(docs/CARS.md)|(uv.lock)|(third_party/acados/include/blasfeo/include/blasfeo_d_kernel.h)'
|
||||
args:
|
||||
- --maxkb=120
|
||||
- --enforce-all
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
exclude: '^(third_party/)|(body/)|(msgq/)|(panda/)|(opendbc/)|(rednose/)|(rednose_repo/)|(teleoprtc/)|(teleoprtc_repo/)|(selfdrive/ui/translations/.*.ts)|(uv.lock)'
|
||||
args:
|
||||
# if you've got a short variable name that's getting flagged, add it here
|
||||
- -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn
|
||||
- --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.5.0
|
||||
hooks:
|
||||
- id: ruff
|
||||
exclude: '^(third_party/)|(msgq/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)'
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy
|
||||
entry: mypy
|
||||
language: system
|
||||
types: [python]
|
||||
args:
|
||||
- --local-partial-types
|
||||
- --explicit-package-bases
|
||||
exclude: '^(third_party/)|(body/)|(msgq/)|(opendbc/)|(panda/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(teleoprtc/)|(teleoprtc_repo/)'
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: cppcheck
|
||||
name: cppcheck
|
||||
entry: cppcheck
|
||||
language: system
|
||||
types: [c++]
|
||||
exclude: '^(third_party/)|(msgq/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)|(installer/)'
|
||||
args:
|
||||
- --error-exitcode=1
|
||||
- --language=c++
|
||||
- --quiet
|
||||
- --force
|
||||
- -j8
|
||||
- --library=qt
|
||||
- --include=third_party/kaitai/kaitaistream.h
|
||||
- repo: https://github.com/cpplint/cpplint
|
||||
rev: 1.6.1
|
||||
hooks:
|
||||
- id: cpplint
|
||||
exclude: '^(third_party/)|(msgq/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(generated/)'
|
||||
args:
|
||||
- --quiet
|
||||
- --counting=total
|
||||
- --linelength=240
|
||||
# https://google.github.io/styleguide/cppguide.html
|
||||
# relevant rules are whitelisted, see all options with: cpplint --filter=
|
||||
- --filter=-build,-legal,-readability,-runtime,-whitespace,+build/include_subdir,+build/forward_decl,+build/include_what_you_use,+build/deprecated,+whitespace/comma,+whitespace/line_length,+whitespace/empty_if_body,+whitespace/empty_loop_body,+whitespace/empty_conditional_body,+whitespace/forcolon,+whitespace/parens,+whitespace/semicolon,+whitespace/tab,+readability/braces
|
||||
- repo: https://github.com/MarcoGorelli/cython-lint
|
||||
rev: v0.16.2
|
||||
hooks:
|
||||
- id: cython-lint
|
||||
exclude: '^(third_party/)|(msgq/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(generated/)'
|
||||
args:
|
||||
- --max-line-length=240
|
||||
- --ignore=E111, E302, E305
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: test_translations
|
||||
name: test translations
|
||||
entry: pytest selfdrive/ui/tests/test_translations.py
|
||||
language: system
|
||||
pass_filenames: false
|
||||
files: '^selfdrive/ui/translations/'
|
||||
- repo: https://github.com/python-jsonschema/check-jsonschema
|
||||
rev: 0.28.6
|
||||
hooks:
|
||||
- id: check-github-workflows
|
||||
@@ -13,7 +13,7 @@ ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
COPY tools/install_ubuntu_dependencies.sh /tmp/tools/
|
||||
RUN INSTALL_EXTRA_PACKAGES=no /tmp/tools/install_ubuntu_dependencies.sh && \
|
||||
RUN /tmp/tools/install_ubuntu_dependencies.sh && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
cd /usr/lib/gcc/arm-none-eabi/* && \
|
||||
rm -rf arm/ thumb/nofp thumb/v6* thumb/v8* thumb/v7+fp thumb/v7-r+fp.sp
|
||||
|
||||
Vendored
+1
-37
@@ -82,7 +82,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
|
||||
|
||||
lock(resource: "", label: deviceType, inversePrecedence: true, variable: 'device_ip', quantity: 1, resourceSelectStrategy: 'random') {
|
||||
docker.image('ghcr.io/commaai/alpine-ssh').inside('--user=root') {
|
||||
timeout(time: 20, unit: 'MINUTES') {
|
||||
timeout(time: 35, unit: 'MINUTES') {
|
||||
retry (3) {
|
||||
device(device_ip, "git checkout", extra + "\n" + readFile("selfdrive/test/setup_device_ci.sh"))
|
||||
}
|
||||
@@ -95,42 +95,6 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
|
||||
}
|
||||
}
|
||||
|
||||
def pcStage(String stageName, Closure body) {
|
||||
node {
|
||||
stage(stageName) {
|
||||
if (currentBuild.result != null) {
|
||||
return
|
||||
}
|
||||
|
||||
checkout scm
|
||||
|
||||
def dockerArgs = "--user=batman -v /tmp/comma_download_cache:/tmp/comma_download_cache -v /tmp/scons_cache:/tmp/scons_cache -e PYTHONPATH=${env.WORKSPACE} --cpus=8 --memory 16g -e PYTEST_ADDOPTS='-n8'";
|
||||
|
||||
def openpilot_base = retryWithDelay (3, 15) {
|
||||
return docker.build("openpilot-base:build-${env.GIT_COMMIT}", "-f Dockerfile.openpilot_base .")
|
||||
}
|
||||
|
||||
lock(resource: "", label: 'pc', inversePrecedence: true, quantity: 1) {
|
||||
openpilot_base.inside(dockerArgs) {
|
||||
timeout(time: 20, unit: 'MINUTES') {
|
||||
try {
|
||||
retryWithDelay (3, 15) {
|
||||
sh "git config --global --add safe.directory '*'"
|
||||
sh "git submodule update --init --recursive"
|
||||
sh "git lfs pull"
|
||||
}
|
||||
body()
|
||||
} finally {
|
||||
sh "rm -rf ${env.WORKSPACE}/* || true"
|
||||
sh "rm -rf .* || true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def setupCredentials() {
|
||||
withCredentials([
|
||||
string(credentialsId: 'azure_token', variable: 'AZURE_TOKEN'),
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
[](https://comma.ai/shop/comma-3x)
|
||||
<div align="center" style="text-align: center;">
|
||||
|
||||
What is openpilot?
|
||||
------
|
||||
<h1>openpilot</h1>
|
||||
|
||||
[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](docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md).
|
||||
<p>
|
||||
<b>openpilot is an operating system for robotics.</b>
|
||||
<br>
|
||||
Currently, it upgrades the driver assistance system in 275+ supported cars.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="https://docs.comma.ai">Docs</a>
|
||||
<span> · </span>
|
||||
<a href="https://docs.comma.ai/contributing/roadmap/">Roadmap</a>
|
||||
<span> · </span>
|
||||
<a href="https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md">Contribute</a>
|
||||
<span> · </span>
|
||||
<a href="https://discord.comma.ai">Community</a>
|
||||
<span> · </span>
|
||||
<a href="https://comma.ai/shop">Try it on a comma 3X</a>
|
||||
</h3>
|
||||
|
||||
Quick start: `bash <(curl -fsSL openpilot.comma.ai)`
|
||||
|
||||

|
||||
[](https://codecov.io/gh/commaai/openpilot)
|
||||
[](LICENSE)
|
||||
[](https://x.com/comma_ai)
|
||||
[](https://discord.comma.ai)
|
||||
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -19,7 +44,7 @@ To start using openpilot in a car
|
||||
To use openpilot in a car, you need four things:
|
||||
1. **Supported Device:** a comma 3/3X, available at [comma.ai/shop](https://comma.ai/shop/comma-3x).
|
||||
2. **Software:** The setup procedure for the comma 3/3X allows users to enter a URL for custom software. Use the URL `openpilot.comma.ai` to install the release version.
|
||||
3. **Supported Car:** Ensure that you have one of [the 250+ supported cars](docs/CARS.md).
|
||||
3. **Supported Car:** Ensure that you have one of [the 275+ supported cars](docs/CARS.md).
|
||||
4. **Car Harness:** You will also need a [car harness](https://comma.ai/shop/car-harness) to connect your comma 3/3X to your car.
|
||||
|
||||
We have detailed instructions for [how to install the harness and device in a car](https://comma.ai/setup). Note that it's possible to run openpilot on [other hardware](https://blog.comma.ai/self-driving-car-for-free/), although it's not plug-and-play.
|
||||
@@ -36,7 +61,7 @@ openpilot is developed by [comma](https://comma.ai/) and by users like you. We w
|
||||
* Code documentation lives at https://docs.comma.ai
|
||||
* Information about running openpilot lives on the [community wiki](https://github.com/commaai/openpilot/wiki)
|
||||
|
||||
Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs#open-positions) and offers lots of [bounties](docs/BOUNTIES.md) for external contributors.
|
||||
Want to get paid to work on openpilot? [comma is hiring](https://comma.ai/jobs#open-positions) and offers lots of [bounties](https://comma.ai/bounties) for external contributors.
|
||||
|
||||
Safety and Testing
|
||||
----
|
||||
@@ -49,18 +74,6 @@ Safety and Testing
|
||||
* panda has additional hardware-in-the-loop [tests](https://github.com/commaai/panda/blob/master/Jenkinsfile).
|
||||
* We run the latest openpilot in a testing closet containing 10 comma devices continuously replaying routes.
|
||||
|
||||
User Data and comma Account
|
||||
------
|
||||
|
||||
By default, openpilot uploads the driving data to our servers. You can also access your data through [comma connect](https://connect.comma.ai/). 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.
|
||||
|
||||
openpilot logs the road-facing cameras, 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://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.
|
||||
|
||||
Licensing
|
||||
------
|
||||
|
||||
@@ -72,9 +85,14 @@ Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and i
|
||||
YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS.
|
||||
NO WARRANTY EXPRESSED OR IMPLIED.**
|
||||
|
||||
---
|
||||
User Data and comma Account
|
||||
------
|
||||
|
||||
<img src="https://d1qb2nb5cznatu.cloudfront.net/startups/i/1061157-bc7e9bf3b246ece7322e6ffe653f6af8-medium_jpg.jpg?buster=1458363130" width="75"></img> <img src="https://cdn-images-1.medium.com/max/1600/1*C87EjxGeMPrkTuVRVWVg4w.png" width="225"></img>
|
||||
By default, openpilot uploads the driving data to our servers. You can also access your data through [comma connect](https://connect.comma.ai/). We use your data to train better models and improve openpilot for everyone.
|
||||
|
||||

|
||||
[](https://codecov.io/gh/commaai/openpilot)
|
||||
openpilot is open source software: the user is free to disable data collection if they wish to do so.
|
||||
|
||||
openpilot logs the road-facing cameras, 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://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.
|
||||
|
||||
+14
-25
@@ -102,7 +102,6 @@ if arch == "larch64":
|
||||
|
||||
libpath = [
|
||||
"/usr/local/lib",
|
||||
"/usr/lib",
|
||||
"/system/vendor/lib64",
|
||||
f"#third_party/acados/{arch}/lib",
|
||||
]
|
||||
@@ -169,10 +168,6 @@ else:
|
||||
if arch != "Darwin":
|
||||
ldflags += ["-Wl,--as-needed", "-Wl,--no-undefined"]
|
||||
|
||||
# Enable swaglog include in submodules
|
||||
cflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
|
||||
cxxflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
|
||||
|
||||
ccflags_option = GetOption('ccflags')
|
||||
if ccflags_option:
|
||||
ccflags += ccflags_option.split(' ')
|
||||
@@ -187,12 +182,9 @@ env = Environment(
|
||||
"-Werror",
|
||||
"-Wshadow",
|
||||
"-Wno-unknown-warning-option",
|
||||
"-Wno-deprecated-register",
|
||||
"-Wno-register",
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Wno-c99-designator",
|
||||
"-Wno-reorder-init-list",
|
||||
"-Wno-error=unused-but-set-variable",
|
||||
"-Wno-vla-cxx-extension",
|
||||
] + cflags + ccflags,
|
||||
|
||||
@@ -206,11 +198,8 @@ env = Environment(
|
||||
"#third_party/json11",
|
||||
"#third_party/linux/include",
|
||||
"#third_party/snpe/include",
|
||||
"#third_party/qrcode",
|
||||
"#third_party",
|
||||
"#cereal",
|
||||
"#msgq",
|
||||
"#opendbc/can",
|
||||
],
|
||||
|
||||
CC='clang',
|
||||
@@ -232,7 +221,7 @@ env = Environment(
|
||||
COMPILATIONDB_USE_ABSPATH=True,
|
||||
REDNOSE_ROOT="#",
|
||||
tools=["default", "cython", "compilation_db", "rednose_filter"],
|
||||
toolpath=["#rednose_repo/site_scons/site_tools"],
|
||||
toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"],
|
||||
)
|
||||
|
||||
if arch == "Darwin":
|
||||
@@ -271,11 +260,12 @@ if arch == "Darwin":
|
||||
else:
|
||||
envCython["LINKFLAGS"] = ["-pthread", "-shared"]
|
||||
|
||||
Export('envCython')
|
||||
np_version = SCons.Script.Value(np.__version__)
|
||||
Export('envCython', 'np_version')
|
||||
|
||||
# Qt build environment
|
||||
qt_env = env.Clone()
|
||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "DBus", "Xml"]
|
||||
qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "DBus", "Xml"]
|
||||
|
||||
qt_libs = []
|
||||
if arch == "Darwin":
|
||||
@@ -315,15 +305,12 @@ try:
|
||||
except SCons.Errors.UserError:
|
||||
qt_env.Tool('qt')
|
||||
|
||||
qt_env['CPPPATH'] += qt_dirs# + ["#selfdrive/ui/qt/"]
|
||||
qt_env['CPPPATH'] += qt_dirs + ["#third_party/qrcode"]
|
||||
qt_flags = [
|
||||
"-D_REENTRANT",
|
||||
"-DQT_NO_DEBUG",
|
||||
"-DQT_WIDGETS_LIB",
|
||||
"-DQT_GUI_LIB",
|
||||
"-DQT_QUICK_LIB",
|
||||
"-DQT_QUICKWIDGETS_LIB",
|
||||
"-DQT_QML_LIB",
|
||||
"-DQT_CORE_LIB",
|
||||
"-DQT_MESSAGELOGCONTEXT",
|
||||
]
|
||||
@@ -348,25 +335,27 @@ Export('env', 'qt_env', 'arch', 'real_arch')
|
||||
SConscript(['common/SConscript'])
|
||||
Import('_common', '_gpucommon')
|
||||
|
||||
common = [_common, 'json11']
|
||||
common = [_common, 'json11', 'zmq']
|
||||
gpucommon = [_gpucommon]
|
||||
|
||||
Export('common', 'gpucommon')
|
||||
|
||||
# Build messaging (cereal + msgq + socketmaster + their dependencies)
|
||||
SConscript(['msgq_repo/SConscript'])
|
||||
# Enable swaglog include in submodules
|
||||
env_swaglog = env.Clone()
|
||||
env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""')
|
||||
SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog})
|
||||
SConscript(['opendbc/can/SConscript'], exports={'env': env_swaglog})
|
||||
|
||||
SConscript(['cereal/SConscript'])
|
||||
|
||||
Import('socketmaster', 'msgq')
|
||||
messaging = [socketmaster, msgq, 'zmq', 'capnp', 'kj',]
|
||||
Export('messaging')
|
||||
|
||||
|
||||
# Build other submodules
|
||||
SConscript([
|
||||
'body/board/SConscript',
|
||||
'opendbc/can/SConscript',
|
||||
'panda/SConscript',
|
||||
])
|
||||
SConscript(['panda/SConscript'])
|
||||
|
||||
# Build rednose library
|
||||
SConscript(['rednose/SConscript'])
|
||||
|
||||
-1
Submodule body deleted from 0e74db67ae
+4
-15
@@ -1,31 +1,20 @@
|
||||
Import('env', 'envCython', 'arch', 'common', 'msgq')
|
||||
|
||||
import shutil
|
||||
Import('env', 'common', 'msgq')
|
||||
|
||||
cereal_dir = Dir('.')
|
||||
gen_dir = Dir('gen')
|
||||
other_dir = Dir('#msgq')
|
||||
|
||||
# Build cereal
|
||||
schema_files = ['log.capnp', 'car.capnp', 'legacy.capnp', 'custom.capnp']
|
||||
env.Command(["gen/c/include/c++.capnp.h"], [], "mkdir -p " + gen_dir.path + "/c/include && touch $TARGETS")
|
||||
env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
|
||||
schema_files,
|
||||
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
|
||||
|
||||
# TODO: remove non shared cereal and messaging
|
||||
cereal_objects = env.SharedObject([f'gen/cpp/{s}.c++' for s in schema_files])
|
||||
|
||||
cereal = env.Library('cereal', cereal_objects)
|
||||
env.SharedLibrary('cereal_shared', cereal_objects)
|
||||
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
|
||||
|
||||
# Build messaging
|
||||
|
||||
services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
|
||||
env.Program('messaging/bridge', ['messaging/bridge.cc'], LIBS=[msgq, 'zmq', common])
|
||||
env.Program('messaging/bridge', ['messaging/bridge.cc', 'messaging/msgq_to_zmq.cc'], LIBS=[msgq, common, 'pthread'])
|
||||
|
||||
|
||||
socketmaster = env.SharedObject(['messaging/socketmaster.cc'])
|
||||
socketmaster = env.Library('socketmaster', socketmaster)
|
||||
socketmaster = env.Library('socketmaster', ['messaging/socketmaster.cc'])
|
||||
|
||||
Export('cereal', 'socketmaster')
|
||||
|
||||
@@ -117,6 +117,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
|
||||
paramsdPermanentError @119;
|
||||
actuatorsApiUnavailable @120;
|
||||
espActive @121;
|
||||
personalityChanged @122;
|
||||
|
||||
radarCanErrorDEPRECATED @15;
|
||||
communityFeatureDisallowedDEPRECATED @62;
|
||||
@@ -196,6 +197,7 @@ struct CarState {
|
||||
accFaulted @42 :Bool;
|
||||
carFaultedNonCritical @47 :Bool; # some ECU is faulted, but car remains controllable
|
||||
espActive @51 :Bool;
|
||||
vehicleSensorsInvalid @52 :Bool; # invalid steering angle readings, etc.
|
||||
|
||||
# cruise state
|
||||
cruiseState @10 :CruiseState;
|
||||
|
||||
+100
-42
@@ -137,8 +137,6 @@ struct FrameData {
|
||||
requestId @28 :UInt32;
|
||||
encodeId @1 :UInt32;
|
||||
|
||||
frameType @7 :FrameType;
|
||||
|
||||
# Timestamps
|
||||
timestampEof @2 :UInt64;
|
||||
timestampSof @8 :UInt64;
|
||||
@@ -158,7 +156,7 @@ struct FrameData {
|
||||
|
||||
temperaturesC @24 :List(Float32);
|
||||
|
||||
enum FrameType {
|
||||
enum FrameTypeDEPRECATED {
|
||||
unknown @0;
|
||||
neo @1;
|
||||
chffrAndroid @2;
|
||||
@@ -175,6 +173,7 @@ struct FrameData {
|
||||
|
||||
frameLengthDEPRECATED @3 :Int32;
|
||||
globalGainDEPRECATED @5 :Int32;
|
||||
frameTypeDEPRECATED @7 :FrameTypeDEPRECATED;
|
||||
androidCaptureResultDEPRECATED @9 :AndroidCaptureResult;
|
||||
lensPosDEPRECATED @11 :Int32;
|
||||
lensSagDEPRECATED @12 :Float32;
|
||||
@@ -337,9 +336,9 @@ enum LaneChangeDirection {
|
||||
|
||||
struct CanData {
|
||||
address @0 :UInt32;
|
||||
busTime @1 :UInt16;
|
||||
dat @2 :Data;
|
||||
src @3 :UInt8;
|
||||
busTimeDEPRECATED @1 :UInt16;
|
||||
}
|
||||
|
||||
struct DeviceState @0xa4d8b5af2aa492eb {
|
||||
@@ -685,18 +684,53 @@ struct LiveTracks {
|
||||
oncoming @9 :Bool;
|
||||
}
|
||||
|
||||
struct SelfdriveState {
|
||||
# high level system state
|
||||
state @0 :OpenpilotState;
|
||||
enabled @1 :Bool;
|
||||
active @2 :Bool;
|
||||
engageable @9 :Bool; # can OP be engaged?
|
||||
|
||||
# UI alerts
|
||||
alertText1 @3 :Text;
|
||||
alertText2 @4 :Text;
|
||||
alertStatus @5 :AlertStatus;
|
||||
alertSize @6 :AlertSize;
|
||||
alertType @7 :Text;
|
||||
alertSound @8 :Car.CarControl.HUDControl.AudibleAlert;
|
||||
|
||||
# configurable driving settings
|
||||
experimentalMode @10 :Bool;
|
||||
personality @11 :LongitudinalPersonality;
|
||||
|
||||
enum OpenpilotState @0xdbe58b96d2d1ac61 {
|
||||
disabled @0;
|
||||
preEnabled @1;
|
||||
enabled @2;
|
||||
softDisabling @3;
|
||||
overriding @4; # superset of overriding with steering or accelerator
|
||||
}
|
||||
|
||||
enum AlertStatus @0xa0d0dcd113193c62 {
|
||||
normal @0;
|
||||
userPrompt @1;
|
||||
critical @2;
|
||||
}
|
||||
|
||||
enum AlertSize @0xe98bb99d6e985f64 {
|
||||
none @0;
|
||||
small @1;
|
||||
mid @2;
|
||||
full @3;
|
||||
}
|
||||
}
|
||||
|
||||
struct ControlsState @0x97ff69c53601abf1 {
|
||||
cumLagMs @15 :Float32;
|
||||
startMonoTime @48 :UInt64;
|
||||
longitudinalPlanMonoTime @28 :UInt64;
|
||||
lateralPlanMonoTime @50 :UInt64;
|
||||
|
||||
state @31 :OpenpilotState;
|
||||
enabled @19 :Bool;
|
||||
active @36 :Bool;
|
||||
|
||||
experimentalMode @64 :Bool;
|
||||
personality @66 :LongitudinalPersonality;
|
||||
|
||||
longControlState @30 :Car.CarControl.Actuators.LongControlState;
|
||||
vTargetLead @3 :Float32;
|
||||
vCruise @22 :Float32; # actual set speed
|
||||
@@ -707,19 +741,21 @@ struct ControlsState @0x97ff69c53601abf1 {
|
||||
aTarget @35 :Float32;
|
||||
curvature @37 :Float32; # path curvature from vehicle model
|
||||
desiredCurvature @61 :Float32; # lag adjusted curvatures used by lateral controllers
|
||||
forceDecel @51 :Bool;
|
||||
|
||||
# UI alerts
|
||||
# TODO: remove these, they're now in selfdriveState
|
||||
alertText1 @24 :Text;
|
||||
alertText2 @25 :Text;
|
||||
alertStatus @38 :AlertStatus;
|
||||
alertSize @39 :AlertSize;
|
||||
alertBlinkingRate @42 :Float32;
|
||||
alertStatus @38 :SelfdriveState.AlertStatus;
|
||||
alertSize @39 :SelfdriveState.AlertSize;
|
||||
alertType @44 :Text;
|
||||
alertSound @56 :Car.CarControl.HUDControl.AudibleAlert;
|
||||
engageable @41 :Bool; # can OP be engaged?
|
||||
|
||||
cumLagMs @15 :Float32;
|
||||
forceDecel @51 :Bool;
|
||||
state @31 :SelfdriveState.OpenpilotState;
|
||||
enabled @19 :Bool;
|
||||
active @36 :Bool;
|
||||
experimentalMode @64 :Bool;
|
||||
personality @66 :LongitudinalPersonality;
|
||||
|
||||
lateralControlState :union {
|
||||
indiState @52 :LateralINDIState;
|
||||
@@ -732,27 +768,6 @@ struct ControlsState @0x97ff69c53601abf1 {
|
||||
lqrStateDEPRECATED @55 :LateralLQRState;
|
||||
}
|
||||
|
||||
enum OpenpilotState @0xdbe58b96d2d1ac61 {
|
||||
disabled @0;
|
||||
preEnabled @1;
|
||||
enabled @2;
|
||||
softDisabling @3;
|
||||
overriding @4; # superset of overriding with steering or accelerator
|
||||
}
|
||||
|
||||
enum AlertStatus {
|
||||
normal @0; # low priority alert for user's convenience
|
||||
userPrompt @1; # mid priority alert that might require user intervention
|
||||
critical @2; # high priority alert that needs immediate user intervention
|
||||
}
|
||||
|
||||
enum AlertSize {
|
||||
none @0; # don't display the alert
|
||||
small @1; # small box
|
||||
mid @2; # mid screen
|
||||
full @3; # full screen
|
||||
}
|
||||
|
||||
struct LateralINDIState {
|
||||
active @0 :Bool;
|
||||
steeringAngleDeg @1 :Float32;
|
||||
@@ -866,6 +881,7 @@ struct ControlsState @0x97ff69c53601abf1 {
|
||||
desiredCurvatureRateDEPRECATED @62 :Float32;
|
||||
canErrorCounterDEPRECATED @57 :UInt32;
|
||||
vPidDEPRECATED @2 :Float32;
|
||||
alertBlinkingRateDEPRECATED @42 :Float32;
|
||||
}
|
||||
|
||||
struct DrivingModelData {
|
||||
@@ -1011,6 +1027,8 @@ struct ModelDataV2 {
|
||||
brake3MetersPerSecondSquaredProbs @4 :List(Float32);
|
||||
brake4MetersPerSecondSquaredProbs @5 :List(Float32);
|
||||
brake5MetersPerSecondSquaredProbs @6 :List(Float32);
|
||||
gasPressProbs @7 :List(Float32);
|
||||
brakePressProbs @8 :List(Float32);
|
||||
}
|
||||
|
||||
struct Pose {
|
||||
@@ -1252,6 +1270,38 @@ struct LiveLocationKalman {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct LivePose {
|
||||
# More info on reference frames:
|
||||
# https://github.com/commaai/openpilot/tree/master/common/transformations
|
||||
orientationNED @0 :XYZMeasurement;
|
||||
velocityDevice @1 :XYZMeasurement;
|
||||
accelerationDevice @2 :XYZMeasurement;
|
||||
angularVelocityDevice @3 :XYZMeasurement;
|
||||
|
||||
inputsOK @4 :Bool = false;
|
||||
posenetOK @5 :Bool = false;
|
||||
sensorsOK @6 :Bool = false;
|
||||
|
||||
filterState @7 :FilterState;
|
||||
|
||||
struct XYZMeasurement {
|
||||
x @0 :Float32;
|
||||
y @1 :Float32;
|
||||
z @2 :Float32;
|
||||
xStd @3 :Float32;
|
||||
yStd @4 :Float32;
|
||||
zStd @5 :Float32;
|
||||
valid @6 :Bool;
|
||||
}
|
||||
|
||||
struct FilterState {
|
||||
value @0 : List(Float64);
|
||||
std @1 : List(Float64);
|
||||
valid @2 : Bool;
|
||||
}
|
||||
}
|
||||
|
||||
struct ProcLog {
|
||||
cpuTimes @0 :List(CPUTimes);
|
||||
mem @1 :Mem;
|
||||
@@ -2051,9 +2101,15 @@ struct LiveParametersData {
|
||||
stiffnessFactorStd @12 :Float32;
|
||||
steerRatioStd @13 :Float32;
|
||||
roll @14 :Float32;
|
||||
filterState @15 :LiveLocationKalman.Measurement;
|
||||
debugFilterState @16 :FilterState;
|
||||
|
||||
yawRateDEPRECATED @7 :Float32;
|
||||
filterStateDEPRECATED @15 :LiveLocationKalman.Measurement;
|
||||
|
||||
struct FilterState {
|
||||
value @0 : List(Float64);
|
||||
std @1 : List(Float64);
|
||||
}
|
||||
}
|
||||
|
||||
struct LiveTorqueParametersData {
|
||||
@@ -2261,6 +2317,7 @@ struct Event {
|
||||
gpsNMEA @3 :GPSNMEAData;
|
||||
can @5 :List(CanData);
|
||||
controlsState @7 :ControlsState;
|
||||
selfdriveState @130 :SelfdriveState;
|
||||
gyroscope @99 :SensorEventData;
|
||||
gyroscope2 @100 :SensorEventData;
|
||||
accelerometer @98 :SensorEventData;
|
||||
@@ -2292,7 +2349,7 @@ struct Event {
|
||||
onroadEvents @68: List(Car.CarEvent);
|
||||
carParams @69: Car.CarParams;
|
||||
driverMonitoringState @71: DriverMonitoringState;
|
||||
liveLocationKalman @72 :LiveLocationKalman;
|
||||
livePose @129 :LivePose;
|
||||
modelV2 @75 :ModelDataV2;
|
||||
drivingModelData @128 :DrivingModelData;
|
||||
driverStateV2 @92 :DriverStateV2;
|
||||
@@ -2364,7 +2421,7 @@ struct Event {
|
||||
model @9 :Legacy.ModelData; # TODO: rename modelV2 and mark this as deprecated
|
||||
liveMpcDEPRECATED @36 :LiveMpcData;
|
||||
liveLongitudinalMpcDEPRECATED @37 :LiveLongitudinalMpcData;
|
||||
liveLocationKalmanDEPRECATED @51 :Legacy.LiveLocationData;
|
||||
liveLocationKalmanLegacyDEPRECATED @51 :Legacy.LiveLocationData;
|
||||
orbslamCorrectionDEPRECATED @45 :Legacy.OrbslamCorrection;
|
||||
liveUIDEPRECATED @14 :Legacy.LiveUI;
|
||||
sensorEventDEPRECATED @4 :SensorEventData;
|
||||
@@ -2401,5 +2458,6 @@ struct Event {
|
||||
lateralPlanDEPRECATED @64 :LateralPlan;
|
||||
navModelDEPRECATED @104 :NavModelData;
|
||||
uiPlanDEPRECATED @106 :UiPlan;
|
||||
liveLocationKalmanDEPRECATED @72 :LiveLocationKalman;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
from msgq.ipc_pyx import Context, Poller, SubSocket, PubSocket, SocketEventHandle, toggle_fake_events, \
|
||||
set_fake_prefix, get_fake_prefix, delete_fake_prefix, wait_for_one_event
|
||||
from msgq.ipc_pyx import MultiplePublishersError, IpcError
|
||||
from msgq import fake_event_handle, pub_sock, sub_sock, drain_sock_raw, context
|
||||
from msgq import fake_event_handle, pub_sock, sub_sock, drain_sock_raw
|
||||
import msgq
|
||||
|
||||
import os
|
||||
import capnp
|
||||
@@ -17,8 +18,12 @@ from cereal.services import SERVICE_LIST
|
||||
NO_TRAVERSAL_LIMIT = 2**64-1
|
||||
|
||||
|
||||
def log_from_bytes(dat: bytes) -> capnp.lib.capnp._DynamicStructReader:
|
||||
with log.Event.from_bytes(dat, traversal_limit_in_words=NO_TRAVERSAL_LIMIT) as msg:
|
||||
def reset_context():
|
||||
msgq.context = Context()
|
||||
|
||||
|
||||
def log_from_bytes(dat: bytes, struct: capnp.lib.capnp._StructModule = log.Event) -> capnp.lib.capnp._DynamicStructReader:
|
||||
with struct.from_bytes(dat, traversal_limit_in_words=NO_TRAVERSAL_LIMIT) as msg:
|
||||
return msg
|
||||
|
||||
|
||||
@@ -87,26 +92,63 @@ def recv_one_retry(sock: SubSocket) -> capnp.lib.capnp._DynamicStructReader:
|
||||
return log_from_bytes(dat)
|
||||
|
||||
|
||||
class FrequencyTracker:
|
||||
def __init__(self, service_freq: float, update_freq: float, is_poll: bool):
|
||||
freq = max(min(service_freq, update_freq), 1.)
|
||||
if is_poll:
|
||||
min_freq = max_freq = freq
|
||||
else:
|
||||
max_freq = min(freq, update_freq)
|
||||
if service_freq >= 2 * update_freq:
|
||||
min_freq = update_freq
|
||||
elif update_freq >= 2* service_freq:
|
||||
min_freq = freq
|
||||
else:
|
||||
min_freq = min(freq, freq / 2.)
|
||||
|
||||
self.min_freq = min_freq * 0.8
|
||||
self.max_freq = max_freq * 1.2
|
||||
self.recv_dts: Deque[float] = deque(maxlen=int(10 * freq))
|
||||
self.prev_time = 0.0
|
||||
|
||||
def record_recv_time(self, cur_time: float) -> None:
|
||||
# TODO: Handle case where cur_time is less than prev_time
|
||||
if self.prev_time > 1e-5:
|
||||
self.recv_dts.append(cur_time - self.prev_time)
|
||||
self.prev_time = cur_time
|
||||
|
||||
@property
|
||||
def valid(self) -> bool:
|
||||
if not self.recv_dts:
|
||||
return False
|
||||
|
||||
avg_freq = len(self.recv_dts) / sum(self.recv_dts)
|
||||
if self.min_freq <= avg_freq <= self.max_freq:
|
||||
return True
|
||||
|
||||
recent_dts = list(self.recv_dts)[-int(self.recv_dts.maxlen / 10):]
|
||||
avg_freq_recent = len(recent_dts) / sum(recent_dts)
|
||||
return self.min_freq <= avg_freq_recent <= self.max_freq
|
||||
|
||||
|
||||
class SubMaster:
|
||||
def __init__(self, services: List[str], poll: Optional[str] = None,
|
||||
ignore_alive: Optional[List[str]] = None, ignore_avg_freq: Optional[List[str]] = None,
|
||||
ignore_valid: Optional[List[str]] = None, addr: str = "127.0.0.1", frequency: Optional[float] = None):
|
||||
self.frame = -1
|
||||
self.services = services
|
||||
self.seen = {s: False for s in services}
|
||||
self.updated = {s: False for s in services}
|
||||
self.recv_time = {s: 0. for s in services}
|
||||
self.recv_frame = {s: 0 for s in services}
|
||||
self.alive = {s: False for s in services}
|
||||
self.freq_ok = {s: False for s in services}
|
||||
self.recv_dts: Dict[str, Deque[float]] = {}
|
||||
self.sock = {}
|
||||
self.data = {}
|
||||
self.valid = {}
|
||||
self.logMonoTime = {}
|
||||
|
||||
self.max_freq = {}
|
||||
self.min_freq = {}
|
||||
|
||||
self.freq_tracker: Dict[str, FrequencyTracker] = {}
|
||||
self.poller = Poller()
|
||||
polled_services = set([poll, ] if poll is not None else services)
|
||||
self.non_polled_services = set(services) - polled_services
|
||||
@@ -133,22 +175,7 @@ class SubMaster:
|
||||
self.data[s] = getattr(data.as_reader(), s)
|
||||
self.logMonoTime[s] = 0
|
||||
self.valid[s] = True # FIXME: this should default to False
|
||||
|
||||
freq = max(min([SERVICE_LIST[s].frequency, self.update_freq]), 1.)
|
||||
if s == poll:
|
||||
max_freq = freq
|
||||
min_freq = freq
|
||||
else:
|
||||
max_freq = min(freq, self.update_freq)
|
||||
if SERVICE_LIST[s].frequency >= 2*self.update_freq:
|
||||
min_freq = self.update_freq
|
||||
elif self.update_freq >= 2*SERVICE_LIST[s].frequency:
|
||||
min_freq = freq
|
||||
else:
|
||||
min_freq = min(freq, freq / 2.)
|
||||
self.max_freq[s] = max_freq*1.2
|
||||
self.min_freq[s] = min_freq*0.8
|
||||
self.recv_dts[s] = deque(maxlen=int(10*freq))
|
||||
self.freq_tracker[s] = FrequencyTracker(SERVICE_LIST[s].frequency, self.update_freq, s == poll)
|
||||
|
||||
def __getitem__(self, s: str) -> capnp.lib.capnp._DynamicStructReader:
|
||||
return self.data[s]
|
||||
@@ -168,7 +195,7 @@ class SubMaster:
|
||||
|
||||
def update_msgs(self, cur_time: float, msgs: List[capnp.lib.capnp._DynamicStructReader]) -> None:
|
||||
self.frame += 1
|
||||
self.updated = dict.fromkeys(self.updated, False)
|
||||
self.updated = dict.fromkeys(self.services, False)
|
||||
for msg in msgs:
|
||||
if msg is None:
|
||||
continue
|
||||
@@ -177,54 +204,30 @@ class SubMaster:
|
||||
self.seen[s] = True
|
||||
self.updated[s] = True
|
||||
|
||||
if self.recv_time[s] > 1e-5:
|
||||
self.recv_dts[s].append(cur_time - self.recv_time[s])
|
||||
self.freq_tracker[s].record_recv_time(cur_time)
|
||||
self.recv_time[s] = cur_time
|
||||
self.recv_frame[s] = self.frame
|
||||
self.data[s] = getattr(msg, s)
|
||||
self.logMonoTime[s] = msg.logMonoTime
|
||||
self.valid[s] = msg.valid
|
||||
|
||||
for s in self.data:
|
||||
for s in self.services:
|
||||
if SERVICE_LIST[s].frequency > 1e-5 and not self.simulation:
|
||||
# alive if delay is within 10x the expected frequency
|
||||
self.alive[s] = (cur_time - self.recv_time[s]) < (10. / SERVICE_LIST[s].frequency)
|
||||
|
||||
# check average frequency; slow to fall, quick to recover
|
||||
dts = self.recv_dts[s]
|
||||
assert dts.maxlen is not None
|
||||
recent_dts = list(dts)[-int(dts.maxlen / 10):]
|
||||
try:
|
||||
avg_freq = 1 / (sum(dts) / len(dts))
|
||||
avg_freq_recent = 1 / (sum(recent_dts) / len(recent_dts))
|
||||
except ZeroDivisionError:
|
||||
avg_freq = 0
|
||||
avg_freq_recent = 0
|
||||
|
||||
avg_freq_ok = self.min_freq[s] <= avg_freq <= self.max_freq[s]
|
||||
recent_freq_ok = self.min_freq[s] <= avg_freq_recent <= self.max_freq[s]
|
||||
self.freq_ok[s] = avg_freq_ok or recent_freq_ok
|
||||
self.freq_ok[s] = self.freq_tracker[s].valid
|
||||
else:
|
||||
self.freq_ok[s] = True
|
||||
if self.simulation:
|
||||
self.alive[s] = self.seen[s] # alive is defined as seen when simulation flag set
|
||||
else:
|
||||
self.alive[s] = True
|
||||
self.alive[s] = self.seen[s] if self.simulation else True
|
||||
|
||||
def all_alive(self, service_list: Optional[List[str]] = None) -> bool:
|
||||
if service_list is None:
|
||||
service_list = list(self.sock.keys())
|
||||
return all(self.alive[s] for s in service_list if s not in self.ignore_alive)
|
||||
return all(self.alive[s] for s in (service_list or self.services) if s not in self.ignore_alive)
|
||||
|
||||
def all_freq_ok(self, service_list: Optional[List[str]] = None) -> bool:
|
||||
if service_list is None:
|
||||
service_list = list(self.sock.keys())
|
||||
return all(self.freq_ok[s] for s in service_list if self._check_avg_freq(s))
|
||||
return all(self.freq_ok[s] for s in (service_list or self.services) if self._check_avg_freq(s))
|
||||
|
||||
def all_valid(self, service_list: Optional[List[str]] = None) -> bool:
|
||||
if service_list is None:
|
||||
service_list = list(self.sock.keys())
|
||||
return all(self.valid[s] for s in service_list if s not in self.ignore_valid)
|
||||
return all(self.valid[s] for s in (service_list or self.services) if s not in self.ignore_valid)
|
||||
|
||||
def all_checks(self, service_list: Optional[List[str]] = None) -> bool:
|
||||
return self.all_alive(service_list) and self.all_freq_ok(service_list) and self.all_valid(service_list)
|
||||
|
||||
+40
-61
@@ -1,25 +1,10 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
typedef void (*sighandler_t)(int sig);
|
||||
|
||||
#include "cereal/messaging/msgq_to_zmq.h"
|
||||
#include "cereal/services.h"
|
||||
#include "msgq/impl_msgq.h"
|
||||
#include "msgq/impl_zmq.h"
|
||||
#include "common/util.h"
|
||||
|
||||
std::atomic<bool> do_exit = false;
|
||||
static void set_do_exit(int sig) {
|
||||
do_exit = true;
|
||||
}
|
||||
|
||||
void sigpipe_handler(int sig) {
|
||||
assert(sig == SIGPIPE);
|
||||
std::cout << "SIGPIPE received" << std::endl;
|
||||
}
|
||||
ExitHandler do_exit;
|
||||
|
||||
static std::vector<std::string> get_services(std::string whitelist_str, bool zmq_to_msgq) {
|
||||
std::vector<std::string> service_list;
|
||||
@@ -34,41 +19,22 @@ static std::vector<std::string> get_services(std::string whitelist_str, bool zmq
|
||||
return service_list;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
signal(SIGPIPE, (sighandler_t)sigpipe_handler);
|
||||
signal(SIGINT, (sighandler_t)set_do_exit);
|
||||
signal(SIGTERM, (sighandler_t)set_do_exit);
|
||||
void msgq_to_zmq(const std::vector<std::string> &endpoints, const std::string &ip) {
|
||||
MsgqToZmq bridge;
|
||||
bridge.run(endpoints, ip);
|
||||
}
|
||||
|
||||
bool zmq_to_msgq = argc > 2;
|
||||
std::string ip = zmq_to_msgq ? argv[1] : "127.0.0.1";
|
||||
std::string whitelist_str = zmq_to_msgq ? std::string(argv[2]) : "";
|
||||
void zmq_to_msgq(const std::vector<std::string> &endpoints, const std::string &ip) {
|
||||
auto poller = std::make_unique<ZMQPoller>();
|
||||
auto pub_context = std::make_unique<MSGQContext>();
|
||||
auto sub_context = std::make_unique<ZMQContext>();
|
||||
std::map<SubSocket *, PubSocket *> sub2pub;
|
||||
|
||||
Poller *poller;
|
||||
Context *pub_context;
|
||||
Context *sub_context;
|
||||
if (zmq_to_msgq) { // republishes zmq debugging messages as msgq
|
||||
poller = new ZMQPoller();
|
||||
pub_context = new MSGQContext();
|
||||
sub_context = new ZMQContext();
|
||||
} else {
|
||||
poller = new MSGQPoller();
|
||||
pub_context = new ZMQContext();
|
||||
sub_context = new MSGQContext();
|
||||
}
|
||||
|
||||
std::map<SubSocket*, PubSocket*> sub2pub;
|
||||
for (auto endpoint : get_services(whitelist_str, zmq_to_msgq)) {
|
||||
PubSocket * pub_sock;
|
||||
SubSocket * sub_sock;
|
||||
if (zmq_to_msgq) {
|
||||
pub_sock = new MSGQPubSocket();
|
||||
sub_sock = new ZMQSubSocket();
|
||||
} else {
|
||||
pub_sock = new ZMQPubSocket();
|
||||
sub_sock = new MSGQSubSocket();
|
||||
}
|
||||
pub_sock->connect(pub_context, endpoint);
|
||||
sub_sock->connect(sub_context, endpoint, ip, false);
|
||||
for (auto endpoint : endpoints) {
|
||||
auto pub_sock = new MSGQPubSocket();
|
||||
auto sub_sock = new ZMQSubSocket();
|
||||
pub_sock->connect(pub_context.get(), endpoint);
|
||||
sub_sock->connect(sub_context.get(), endpoint, ip, false);
|
||||
|
||||
poller->registerSocket(sub_sock);
|
||||
sub2pub[sub_sock] = pub_sock;
|
||||
@@ -76,17 +42,30 @@ int main(int argc, char** argv) {
|
||||
|
||||
while (!do_exit) {
|
||||
for (auto sub_sock : poller->poll(100)) {
|
||||
Message * msg = sub_sock->receive();
|
||||
if (msg == NULL) continue;
|
||||
int ret;
|
||||
do {
|
||||
ret = sub2pub[sub_sock]->sendMessage(msg);
|
||||
} while (ret == -1 && errno == EINTR && !do_exit);
|
||||
assert(ret >= 0 || do_exit);
|
||||
delete msg;
|
||||
|
||||
if (do_exit) break;
|
||||
std::unique_ptr<Message> msg(sub_sock->receive(true));
|
||||
if (msg) {
|
||||
sub2pub[sub_sock]->sendMessage(msg.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up allocated sockets
|
||||
for (auto &[sub_sock, pub_sock] : sub2pub) {
|
||||
delete sub_sock;
|
||||
delete pub_sock;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
bool is_zmq_to_msgq = argc > 2;
|
||||
std::string ip = is_zmq_to_msgq ? argv[1] : "127.0.0.1";
|
||||
std::string whitelist_str = is_zmq_to_msgq ? std::string(argv[2]) : "";
|
||||
std::vector<std::string> endpoints = get_services(whitelist_str, is_zmq_to_msgq);
|
||||
|
||||
if (is_zmq_to_msgq) {
|
||||
zmq_to_msgq(endpoints, ip);
|
||||
} else {
|
||||
msgq_to_zmq(endpoints, ip);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "cereal/messaging/msgq_to_zmq.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "common/util.h"
|
||||
|
||||
extern ExitHandler do_exit;
|
||||
|
||||
// Max messages to process per socket per poll
|
||||
constexpr int MAX_MESSAGES_PER_SOCKET = 50;
|
||||
|
||||
static std::string recv_zmq_msg(void *sock) {
|
||||
zmq_msg_t msg;
|
||||
zmq_msg_init(&msg);
|
||||
std::string ret;
|
||||
if (zmq_msg_recv(&msg, sock, 0) > 0) {
|
||||
ret.assign((char *)zmq_msg_data(&msg), zmq_msg_size(&msg));
|
||||
}
|
||||
zmq_msg_close(&msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MsgqToZmq::run(const std::vector<std::string> &endpoints, const std::string &ip) {
|
||||
zmq_context = std::make_unique<ZMQContext>();
|
||||
msgq_context = std::make_unique<MSGQContext>();
|
||||
|
||||
// Create ZMQPubSockets for each endpoint
|
||||
for (const auto &endpoint : endpoints) {
|
||||
auto &socket_pair = socket_pairs.emplace_back();
|
||||
socket_pair.endpoint = endpoint;
|
||||
socket_pair.pub_sock = std::make_unique<ZMQPubSocket>();
|
||||
int ret = socket_pair.pub_sock->connect(zmq_context.get(), endpoint);
|
||||
if (ret != 0) {
|
||||
printf("Failed to create ZMQ publisher for [%s]: %s\n", endpoint.c_str(), zmq_strerror(zmq_errno()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Start ZMQ monitoring thread to monitor socket events
|
||||
std::thread thread(&MsgqToZmq::zmqMonitorThread, this);
|
||||
|
||||
// Main loop for processing messages
|
||||
while (!do_exit) {
|
||||
{
|
||||
std::unique_lock lk(mutex);
|
||||
cv.wait(lk, [this]() { return do_exit || !sub2pub.empty(); });
|
||||
if (do_exit) break;
|
||||
|
||||
for (auto sub_sock : msgq_poller->poll(100)) {
|
||||
// Process messages for each socket
|
||||
for (int i = 0; i < MAX_MESSAGES_PER_SOCKET; ++i) {
|
||||
auto msg = std::unique_ptr<Message>(sub_sock->receive(true));
|
||||
if (!msg) break;
|
||||
|
||||
while (sub2pub[sub_sock]->sendMessage(msg.get()) == -1) {
|
||||
if (errno != EINTR) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
util::sleep_for(1); // Give zmqMonitorThread a chance to acquire the mutex
|
||||
}
|
||||
|
||||
thread.join();
|
||||
}
|
||||
|
||||
void MsgqToZmq::zmqMonitorThread() {
|
||||
std::vector<zmq_pollitem_t> pollitems;
|
||||
|
||||
// Set up ZMQ monitor for each pub socket
|
||||
for (int i = 0; i < socket_pairs.size(); ++i) {
|
||||
std::string addr = "inproc://op-bridge-monitor-" + std::to_string(i);
|
||||
zmq_socket_monitor(socket_pairs[i].pub_sock->sock, addr.c_str(), ZMQ_EVENT_ACCEPTED | ZMQ_EVENT_DISCONNECTED);
|
||||
|
||||
void *monitor_socket = zmq_socket(zmq_context->getRawContext(), ZMQ_PAIR);
|
||||
zmq_connect(monitor_socket, addr.c_str());
|
||||
pollitems.emplace_back(zmq_pollitem_t{.socket = monitor_socket, .events = ZMQ_POLLIN});
|
||||
}
|
||||
|
||||
while (!do_exit) {
|
||||
int ret = zmq_poll(pollitems.data(), pollitems.size(), 1000);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
// Due to frequent EINTR signals from msgq, introduce a brief delay (200 ms)
|
||||
// to reduce CPU usage during retry attempts.
|
||||
util::sleep_for(200);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pollitems.size(); ++i) {
|
||||
if (pollitems[i].revents & ZMQ_POLLIN) {
|
||||
// First frame in message contains event number and value
|
||||
std::string frame = recv_zmq_msg(pollitems[i].socket);
|
||||
if (frame.empty()) continue;
|
||||
|
||||
uint16_t event_type = *(uint16_t *)(frame.data());
|
||||
|
||||
// Second frame in message contains event address
|
||||
frame = recv_zmq_msg(pollitems[i].socket);
|
||||
if (frame.empty()) continue;
|
||||
|
||||
std::unique_lock lk(mutex);
|
||||
auto &pair = socket_pairs[i];
|
||||
if (event_type & ZMQ_EVENT_ACCEPTED) {
|
||||
printf("socket [%s] connected\n", pair.endpoint.c_str());
|
||||
if (++pair.connected_clients == 1) {
|
||||
// Create new MSGQ subscriber socket and map to ZMQ publisher
|
||||
pair.sub_sock = std::make_unique<MSGQSubSocket>();
|
||||
pair.sub_sock->connect(msgq_context.get(), pair.endpoint, "127.0.0.1");
|
||||
sub2pub[pair.sub_sock.get()] = pair.pub_sock.get();
|
||||
registerSockets();
|
||||
}
|
||||
} else if (event_type & ZMQ_EVENT_DISCONNECTED) {
|
||||
printf("socket [%s] disconnected\n", pair.endpoint.c_str());
|
||||
if (pair.connected_clients == 0 || --pair.connected_clients == 0) {
|
||||
// Remove MSGQ subscriber socket from mapping and reset it
|
||||
sub2pub.erase(pair.sub_sock.get());
|
||||
pair.sub_sock.reset(nullptr);
|
||||
registerSockets();
|
||||
}
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up monitor sockets
|
||||
for (int i = 0; i < pollitems.size(); ++i) {
|
||||
zmq_socket_monitor(socket_pairs[i].pub_sock->sock, nullptr, 0);
|
||||
zmq_close(pollitems[i].socket);
|
||||
}
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
void MsgqToZmq::registerSockets() {
|
||||
msgq_poller = std::make_unique<MSGQPoller>();
|
||||
for (const auto &socket_pair : socket_pairs) {
|
||||
if (socket_pair.sub_sock) {
|
||||
msgq_poller->registerSocket(socket_pair.sub_sock.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define private public
|
||||
#include "msgq/impl_msgq.h"
|
||||
#include "msgq/impl_zmq.h"
|
||||
|
||||
class MsgqToZmq {
|
||||
public:
|
||||
MsgqToZmq() {}
|
||||
void run(const std::vector<std::string> &endpoints, const std::string &ip);
|
||||
|
||||
protected:
|
||||
void registerSockets();
|
||||
void zmqMonitorThread();
|
||||
|
||||
struct SocketPair {
|
||||
std::string endpoint;
|
||||
std::unique_ptr<ZMQPubSocket> pub_sock;
|
||||
std::unique_ptr<MSGQSubSocket> sub_sock;
|
||||
int connected_clients = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<MSGQContext> msgq_context;
|
||||
std::unique_ptr<ZMQContext> zmq_context;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
std::unique_ptr<MSGQPoller> msgq_poller;
|
||||
std::map<SubSocket *, ZMQPubSocket *> sub2pub;
|
||||
std::vector<SocketPair> socket_pairs;
|
||||
};
|
||||
Executable → Regular
+21
-31
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import capnp
|
||||
import multiprocessing
|
||||
@@ -6,8 +5,8 @@ import numbers
|
||||
import random
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
from parameterized import parameterized
|
||||
import pytest
|
||||
|
||||
from cereal import log, car
|
||||
import cereal.messaging as messaging
|
||||
@@ -28,12 +27,6 @@ def zmq_sleep(t=1):
|
||||
if "ZMQ" in os.environ:
|
||||
time.sleep(t)
|
||||
|
||||
def zmq_expected_failure(func):
|
||||
if "ZMQ" in os.environ:
|
||||
return unittest.expectedFailure(func)
|
||||
else:
|
||||
return func
|
||||
|
||||
|
||||
# TODO: this should take any capnp struct and returrn a msg with random populated data
|
||||
def random_carstate():
|
||||
@@ -58,12 +51,12 @@ def delayed_send(delay, sock, dat):
|
||||
threading.Timer(delay, send_func).start()
|
||||
|
||||
|
||||
class TestMessaging(unittest.TestCase):
|
||||
class TestMessaging:
|
||||
def setUp(self):
|
||||
# TODO: ZMQ tests are too slow; all sleeps will need to be
|
||||
# replaced with logic to block on the necessary condition
|
||||
if "ZMQ" in os.environ:
|
||||
raise unittest.SkipTest
|
||||
pytest.skip()
|
||||
|
||||
# ZMQ pub socket takes too long to die
|
||||
# sleep to prevent multiple publishers error between tests
|
||||
@@ -75,9 +68,9 @@ class TestMessaging(unittest.TestCase):
|
||||
msg = messaging.new_message(evt)
|
||||
except capnp.lib.capnp.KjException:
|
||||
msg = messaging.new_message(evt, random.randrange(200))
|
||||
self.assertLess(time.monotonic() - msg.logMonoTime, 0.1)
|
||||
self.assertFalse(msg.valid)
|
||||
self.assertEqual(evt, msg.which())
|
||||
assert (time.monotonic() - msg.logMonoTime) < 0.1
|
||||
assert not msg.valid
|
||||
assert evt == msg.which()
|
||||
|
||||
@parameterized.expand(events)
|
||||
def test_pub_sock(self, evt):
|
||||
@@ -99,8 +92,8 @@ class TestMessaging(unittest.TestCase):
|
||||
|
||||
# no wait and no msgs in queue
|
||||
msgs = func(sub_sock)
|
||||
self.assertIsInstance(msgs, list)
|
||||
self.assertEqual(len(msgs), 0)
|
||||
assert isinstance(msgs, list)
|
||||
assert len(msgs) == 0
|
||||
|
||||
# no wait but msgs are queued up
|
||||
num_msgs = random.randrange(3, 10)
|
||||
@@ -108,9 +101,9 @@ class TestMessaging(unittest.TestCase):
|
||||
pub_sock.send(messaging.new_message(sock).to_bytes())
|
||||
time.sleep(0.1)
|
||||
msgs = func(sub_sock)
|
||||
self.assertIsInstance(msgs, list)
|
||||
self.assertTrue(all(isinstance(msg, expected_type) for msg in msgs))
|
||||
self.assertEqual(len(msgs), num_msgs)
|
||||
assert isinstance(msgs, list)
|
||||
assert all(isinstance(msg, expected_type) for msg in msgs)
|
||||
assert len(msgs) == num_msgs
|
||||
|
||||
def test_recv_sock(self):
|
||||
sock = "carState"
|
||||
@@ -120,14 +113,14 @@ class TestMessaging(unittest.TestCase):
|
||||
|
||||
# no wait and no msg in queue, socket should timeout
|
||||
recvd = messaging.recv_sock(sub_sock)
|
||||
self.assertTrue(recvd is None)
|
||||
assert recvd is None
|
||||
|
||||
# no wait and one msg in queue
|
||||
msg = random_carstate()
|
||||
pub_sock.send(msg.to_bytes())
|
||||
time.sleep(0.01)
|
||||
recvd = messaging.recv_sock(sub_sock)
|
||||
self.assertIsInstance(recvd, capnp._DynamicStructReader)
|
||||
assert isinstance(recvd, capnp._DynamicStructReader)
|
||||
# https://github.com/python/mypy/issues/13038
|
||||
assert_carstate(msg.carState, recvd.carState)
|
||||
|
||||
@@ -139,16 +132,16 @@ class TestMessaging(unittest.TestCase):
|
||||
|
||||
# no msg in queue, socket should timeout
|
||||
recvd = messaging.recv_one(sub_sock)
|
||||
self.assertTrue(recvd is None)
|
||||
assert recvd is None
|
||||
|
||||
# one msg in queue
|
||||
msg = random_carstate()
|
||||
pub_sock.send(msg.to_bytes())
|
||||
recvd = messaging.recv_one(sub_sock)
|
||||
self.assertIsInstance(recvd, capnp._DynamicStructReader)
|
||||
assert isinstance(recvd, capnp._DynamicStructReader)
|
||||
assert_carstate(msg.carState, recvd.carState)
|
||||
|
||||
@zmq_expected_failure
|
||||
@pytest.mark.xfail(condition="ZMQ" in os.environ, reason='ZMQ detected')
|
||||
def test_recv_one_or_none(self):
|
||||
sock = "carState"
|
||||
pub_sock = messaging.pub_sock(sock)
|
||||
@@ -157,13 +150,13 @@ class TestMessaging(unittest.TestCase):
|
||||
|
||||
# no msg in queue, socket shouldn't block
|
||||
recvd = messaging.recv_one_or_none(sub_sock)
|
||||
self.assertTrue(recvd is None)
|
||||
assert recvd is None
|
||||
|
||||
# one msg in queue
|
||||
msg = random_carstate()
|
||||
pub_sock.send(msg.to_bytes())
|
||||
recvd = messaging.recv_one_or_none(sub_sock)
|
||||
self.assertIsInstance(recvd, capnp._DynamicStructReader)
|
||||
assert isinstance(recvd, capnp._DynamicStructReader)
|
||||
assert_carstate(msg.carState, recvd.carState)
|
||||
|
||||
def test_recv_one_retry(self):
|
||||
@@ -179,7 +172,7 @@ class TestMessaging(unittest.TestCase):
|
||||
p = multiprocessing.Process(target=messaging.recv_one_retry, args=(sub_sock,))
|
||||
p.start()
|
||||
time.sleep(sock_timeout*15)
|
||||
self.assertTrue(p.is_alive())
|
||||
assert p.is_alive()
|
||||
p.terminate()
|
||||
|
||||
# wait 15 socket timeouts before sending
|
||||
@@ -187,9 +180,6 @@ class TestMessaging(unittest.TestCase):
|
||||
delayed_send(sock_timeout*15, pub_sock, msg.to_bytes())
|
||||
start_time = time.monotonic()
|
||||
recvd = messaging.recv_one_retry(sub_sock)
|
||||
self.assertGreaterEqual(time.monotonic() - start_time, sock_timeout*15)
|
||||
self.assertIsInstance(recvd, capnp._DynamicStructReader)
|
||||
assert (time.monotonic() - start_time) >= sock_timeout*15
|
||||
assert isinstance(recvd, capnp._DynamicStructReader)
|
||||
assert_carstate(msg.carState, recvd.carState)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Executable → Regular
+21
-27
@@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import random
|
||||
import time
|
||||
from typing import Sized, cast
|
||||
import unittest
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \
|
||||
@@ -10,9 +8,9 @@ from cereal.messaging.tests.test_messaging import events, random_sock, random_so
|
||||
zmq_sleep
|
||||
|
||||
|
||||
class TestSubMaster(unittest.TestCase):
|
||||
class TestSubMaster:
|
||||
|
||||
def setUp(self):
|
||||
def setup_method(self):
|
||||
# ZMQ pub socket takes too long to die
|
||||
# sleep to prevent multiple publishers error between tests
|
||||
zmq_sleep(3)
|
||||
@@ -21,21 +19,21 @@ class TestSubMaster(unittest.TestCase):
|
||||
sm = messaging.SubMaster(events)
|
||||
for p in [sm.updated, sm.recv_time, sm.recv_frame, sm.alive,
|
||||
sm.sock, sm.data, sm.logMonoTime, sm.valid]:
|
||||
self.assertEqual(len(cast(Sized, p)), len(events))
|
||||
assert len(cast(Sized, p)) == len(events)
|
||||
|
||||
def test_init_state(self):
|
||||
socks = random_socks()
|
||||
sm = messaging.SubMaster(socks)
|
||||
self.assertEqual(sm.frame, -1)
|
||||
self.assertFalse(any(sm.updated.values()))
|
||||
self.assertFalse(any(sm.alive.values()))
|
||||
self.assertTrue(all(t == 0. for t in sm.recv_time.values()))
|
||||
self.assertTrue(all(f == 0 for f in sm.recv_frame.values()))
|
||||
self.assertTrue(all(t == 0 for t in sm.logMonoTime.values()))
|
||||
assert sm.frame == -1
|
||||
assert not any(sm.updated.values())
|
||||
assert not any(sm.alive.values())
|
||||
assert all(t == 0. for t in sm.recv_time.values())
|
||||
assert all(f == 0 for f in sm.recv_frame.values())
|
||||
assert all(t == 0 for t in sm.logMonoTime.values())
|
||||
|
||||
for p in [sm.updated, sm.recv_time, sm.recv_frame, sm.alive,
|
||||
sm.sock, sm.data, sm.logMonoTime, sm.valid]:
|
||||
self.assertEqual(len(cast(Sized, p)), len(socks))
|
||||
assert len(cast(Sized, p)) == len(socks)
|
||||
|
||||
def test_getitem(self):
|
||||
sock = "carState"
|
||||
@@ -59,8 +57,8 @@ class TestSubMaster(unittest.TestCase):
|
||||
msg = messaging.new_message(sock)
|
||||
pub_sock.send(msg.to_bytes())
|
||||
sm.update(1000)
|
||||
self.assertEqual(sm.frame, i)
|
||||
self.assertTrue(all(sm.updated.values()))
|
||||
assert sm.frame == i
|
||||
assert all(sm.updated.values())
|
||||
|
||||
def test_update_timeout(self):
|
||||
sock = random_sock()
|
||||
@@ -70,9 +68,9 @@ class TestSubMaster(unittest.TestCase):
|
||||
start_time = time.monotonic()
|
||||
sm.update(timeout)
|
||||
t = time.monotonic() - start_time
|
||||
self.assertGreaterEqual(t, timeout/1000.)
|
||||
self.assertLess(t, 5)
|
||||
self.assertFalse(any(sm.updated.values()))
|
||||
assert t >= timeout/1000.
|
||||
assert t < 5
|
||||
assert not any(sm.updated.values())
|
||||
|
||||
def test_avg_frequency_checks(self):
|
||||
for poll in (True, False):
|
||||
@@ -91,8 +89,8 @@ class TestSubMaster(unittest.TestCase):
|
||||
for service, (max_freq, min_freq) in checks.items():
|
||||
if max_freq is not None:
|
||||
assert sm._check_avg_freq(service)
|
||||
assert sm.max_freq[service] == max_freq*1.2
|
||||
assert sm.min_freq[service] == min_freq*0.8
|
||||
assert sm.freq_tracker[service].max_freq == max_freq*1.2
|
||||
assert sm.freq_tracker[service].min_freq == min_freq*0.8
|
||||
else:
|
||||
assert not sm._check_avg_freq(service)
|
||||
|
||||
@@ -118,12 +116,12 @@ class TestSubMaster(unittest.TestCase):
|
||||
pub_sock.send(msg.to_bytes())
|
||||
time.sleep(0.01)
|
||||
sm.update(1000)
|
||||
self.assertEqual(sm[sock].vEgo, n)
|
||||
assert sm[sock].vEgo == n
|
||||
|
||||
|
||||
class TestPubMaster(unittest.TestCase):
|
||||
class TestPubMaster:
|
||||
|
||||
def setUp(self):
|
||||
def setup_method(self):
|
||||
# ZMQ pub socket takes too long to die
|
||||
# sleep to prevent multiple publishers error between tests
|
||||
zmq_sleep(3)
|
||||
@@ -156,8 +154,4 @@ class TestPubMaster(unittest.TestCase):
|
||||
if capnp:
|
||||
msg.clear_write_flag()
|
||||
msg = msg.to_bytes()
|
||||
self.assertEqual(msg, recvd, i)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
assert msg == recvd, i
|
||||
|
||||
Executable → Regular
+4
-9
@@ -1,26 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import tempfile
|
||||
from typing import Dict
|
||||
import unittest
|
||||
from parameterized import parameterized
|
||||
|
||||
import cereal.services as services
|
||||
from cereal.services import SERVICE_LIST
|
||||
|
||||
|
||||
class TestServices(unittest.TestCase):
|
||||
class TestServices:
|
||||
|
||||
@parameterized.expand(SERVICE_LIST.keys())
|
||||
def test_services(self, s):
|
||||
service = SERVICE_LIST[s]
|
||||
self.assertTrue(service.frequency <= 104)
|
||||
self.assertTrue(service.decimation != 0)
|
||||
assert service.frequency <= 104
|
||||
assert service.decimation != 0
|
||||
|
||||
def test_generated_header(self):
|
||||
with tempfile.NamedTemporaryFile(suffix=".h") as f:
|
||||
ret = os.system(f"python3 {services.__file__} > {f.name} && clang++ {f.name}")
|
||||
self.assertEqual(ret, 0, "generated services header is not valid C")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
assert ret == 0, "generated services header is not valid C"
|
||||
|
||||
+6
-5
@@ -16,14 +16,15 @@ _services: dict[str, tuple] = {
|
||||
"gyroscope2": (True, 100., 100),
|
||||
"accelerometer": (True, 104., 104),
|
||||
"accelerometer2": (True, 100., 100),
|
||||
"magnetometer": (True, 25., 25),
|
||||
"magnetometer": (True, 25.),
|
||||
"lightSensor": (True, 100., 100),
|
||||
"temperatureSensor": (True, 2., 200),
|
||||
"temperatureSensor2": (True, 2., 200),
|
||||
"gpsNMEA": (True, 9.),
|
||||
"deviceState": (True, 2., 1),
|
||||
"can": (True, 100., 1223), # decimation gives ~5 msgs in a full segment
|
||||
"can": (True, 100., 2053), # decimation gives ~3 msgs in a full segment
|
||||
"controlsState": (True, 100., 10),
|
||||
"selfdriveState": (True, 100., 10),
|
||||
"pandaStates": (True, 10., 1),
|
||||
"peripheralState": (True, 2., 1),
|
||||
"radarState": (True, 20., 5),
|
||||
@@ -38,7 +39,7 @@ _services: dict[str, tuple] = {
|
||||
"carState": (True, 100., 10),
|
||||
"carControl": (True, 100., 10),
|
||||
"carOutput": (True, 100., 10),
|
||||
"longitudinalPlan": (True, 20., 5),
|
||||
"longitudinalPlan": (True, 20., 10),
|
||||
"procLog": (True, 0.5, 15),
|
||||
"gpsLocationExternal": (True, 10., 10),
|
||||
"gpsLocation": (True, 1., 1),
|
||||
@@ -47,9 +48,9 @@ _services: dict[str, tuple] = {
|
||||
"gnssMeasurements": (True, 10., 10),
|
||||
"clocks": (True, 0.1, 1),
|
||||
"ubloxRaw": (True, 20.),
|
||||
"liveLocationKalman": (True, 20., 5),
|
||||
"livePose": (True, 20., 4),
|
||||
"liveParameters": (True, 20., 5),
|
||||
"cameraOdometry": (True, 20., 5),
|
||||
"cameraOdometry": (True, 20., 10),
|
||||
"thumbnail": (True, 0.2, 1),
|
||||
"onroadEvents": (True, 1., 1),
|
||||
"carParams": (True, 0.02, 1),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from openpilot.common.params import Params
|
||||
|
||||
|
||||
def get_gps_location_service(params: Params) -> str:
|
||||
if params.get_bool("UbloxAvailable"):
|
||||
return "gpsLocationExternal"
|
||||
else:
|
||||
return "gpsLocation"
|
||||
@@ -8,12 +8,12 @@ import functools
|
||||
import threading
|
||||
from cereal.messaging import PubMaster
|
||||
from cereal.services import SERVICE_LIST
|
||||
from openpilot.common.mock.generators import generate_liveLocationKalman
|
||||
from openpilot.common.mock.generators import generate_livePose
|
||||
from openpilot.common.realtime import Ratekeeper
|
||||
|
||||
|
||||
MOCK_GENERATOR = {
|
||||
"liveLocationKalman": generate_liveLocationKalman
|
||||
"livePose": generate_livePose
|
||||
}
|
||||
|
||||
|
||||
|
||||
+10
-16
@@ -1,20 +1,14 @@
|
||||
from cereal import messaging
|
||||
|
||||
|
||||
LOCATION1 = (32.7174, -117.16277)
|
||||
LOCATION2 = (32.7558, -117.2037)
|
||||
|
||||
LLK_DECIMATION = 10
|
||||
RENDER_FRAMES = 15
|
||||
DEFAULT_ITERATIONS = RENDER_FRAMES * LLK_DECIMATION
|
||||
|
||||
|
||||
def generate_liveLocationKalman(location=LOCATION1):
|
||||
msg = messaging.new_message('liveLocationKalman')
|
||||
msg.liveLocationKalman.positionGeodetic = {'value': [*location, 0], 'std': [0., 0., 0.], 'valid': True}
|
||||
msg.liveLocationKalman.positionECEF = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
|
||||
msg.liveLocationKalman.calibratedOrientationNED = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
|
||||
msg.liveLocationKalman.velocityCalibrated = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
|
||||
msg.liveLocationKalman.status = 'valid'
|
||||
msg.liveLocationKalman.gpsOK = True
|
||||
def generate_livePose():
|
||||
msg = messaging.new_message('livePose')
|
||||
meas = {'x': 0.0, 'y': 0.0, 'z': 0.0, 'xStd': 0.0, 'yStd': 0.0, 'zStd': 0.0, 'valid': True}
|
||||
msg.livePose.orientationNED = meas
|
||||
msg.livePose.velocityDevice = meas
|
||||
msg.livePose.angularVelocityDevice = meas
|
||||
msg.livePose.accelerationDevice = meas
|
||||
msg.livePose.inputsOK = True
|
||||
msg.livePose.posenetOK = True
|
||||
msg.livePose.sensorsOK = True
|
||||
return msg
|
||||
|
||||
+2
-3
@@ -24,8 +24,8 @@ int fsync_dir(const std::string &path) {
|
||||
int result = -1;
|
||||
int fd = HANDLE_EINTR(open(path.c_str(), O_RDONLY, 0755));
|
||||
if (fd >= 0) {
|
||||
result = fsync(fd);
|
||||
close(fd);
|
||||
result = HANDLE_EINTR(fsync(fd));
|
||||
HANDLE_EINTR(close(fd));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -104,7 +104,6 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"CarParamsCache", CLEAR_ON_MANAGER_START},
|
||||
{"CarParamsPersistent", PERSISTENT},
|
||||
{"CarParamsPrevRoute", PERSISTENT},
|
||||
{"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"CompletedTrainingVersion", PERSISTENT},
|
||||
{"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"CurrentBootlog", PERSISTENT},
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ import os
|
||||
import time
|
||||
from collections import deque
|
||||
|
||||
from openpilot.common.threadname import getthreadname
|
||||
from setproctitle import getproctitle
|
||||
|
||||
from openpilot.system.hardware import PC
|
||||
|
||||
@@ -52,7 +52,7 @@ class Ratekeeper:
|
||||
self._print_delay_threshold = print_delay_threshold
|
||||
self._frame = 0
|
||||
self._remaining = 0.0
|
||||
self._thread_name = getthreadname()
|
||||
self._process_name = getproctitle()
|
||||
self._dts = deque([self._interval], maxlen=100)
|
||||
self._last_monitor_time = time.monotonic()
|
||||
|
||||
@@ -87,7 +87,7 @@ class Ratekeeper:
|
||||
remaining = self._next_frame_time - time.monotonic()
|
||||
self._next_frame_time += self._interval
|
||||
if self._print_delay_threshold is not None and remaining < -self._print_delay_threshold:
|
||||
print(f"{self._thread_name} lagging by {-remaining * 1000:.2f} ms")
|
||||
print(f"{self._process_name} lagging by {-remaining * 1000:.2f} ms")
|
||||
lagged = True
|
||||
self._frame += 1
|
||||
self._remaining = remaining
|
||||
|
||||
@@ -104,6 +104,15 @@ class UnixDomainSocketHandler(logging.Handler):
|
||||
pass
|
||||
|
||||
|
||||
class ForwardingHandler(logging.Handler):
|
||||
def __init__(self, target_logger):
|
||||
super().__init__()
|
||||
self.target_logger = target_logger
|
||||
|
||||
def emit(self, record):
|
||||
self.target_logger.handle(record)
|
||||
|
||||
|
||||
def add_file_handler(log):
|
||||
"""
|
||||
Function to add the file log handler to swaglog.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
from openpilot.common.threadname import setthreadname, getthreadname, LINUX
|
||||
|
||||
class TestThreadName:
|
||||
def test_set_get_threadname(self):
|
||||
if LINUX:
|
||||
name = 'TESTING'
|
||||
setthreadname(name)
|
||||
assert name == getthreadname()
|
||||
@@ -1,19 +0,0 @@
|
||||
import ctypes
|
||||
import os
|
||||
|
||||
LINUX = os.name == 'posix' and os.uname().sysname == 'Linux'
|
||||
|
||||
if LINUX:
|
||||
libc = ctypes.CDLL('libc.so.6')
|
||||
|
||||
def setthreadname(name: str) -> None:
|
||||
if LINUX:
|
||||
name = name[-15:] + '\0'
|
||||
libc.prctl(15, str.encode(name), 0, 0, 0)
|
||||
|
||||
def getthreadname() -> str:
|
||||
if LINUX:
|
||||
name = ctypes.create_string_buffer(16)
|
||||
libc.prctl(16, name)
|
||||
return name.value.decode('utf-8')
|
||||
return ""
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
_MIN_DATE = datetime.datetime(year=2024, month=3, day=30)
|
||||
_MIN_DATE = datetime.datetime(year=2024, month=8, day=26)
|
||||
|
||||
def min_date():
|
||||
# on systemd systems, the default time is the systemd build time
|
||||
|
||||
@@ -47,9 +47,9 @@ class DeviceCameraConfig:
|
||||
yield cam, getattr(self, cam)
|
||||
|
||||
_ar_ox_fisheye = CameraConfig(1928, 1208, 567.0) # focal length probably wrong? magnification is not consistent across frame
|
||||
_os_fisheye = CameraConfig(2688, 1520, 567.0 / 2 * 3)
|
||||
_os_fisheye = CameraConfig(2688 // 2, 1520 // 2, 567.0 / 4 * 3)
|
||||
_ar_ox_config = DeviceCameraConfig(CameraConfig(1928, 1208, 2648.0), _ar_ox_fisheye, _ar_ox_fisheye)
|
||||
_os_config = DeviceCameraConfig(CameraConfig(2688, 1520, 2648.0 * 2 / 3), _os_fisheye, _os_fisheye)
|
||||
_os_config = DeviceCameraConfig(CameraConfig(2688 // 2, 1520 // 2, 1522.0 * 3 / 4), _os_fisheye, _os_fisheye)
|
||||
_neo_config = DeviceCameraConfig(CameraConfig(1164, 874, 910.0), CameraConfig(816, 612, 650.0), _NoneCameraConfig())
|
||||
|
||||
DEVICE_CAMERAS = {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
class Freezable:
|
||||
_frozen: bool = False
|
||||
|
||||
def freeze(self):
|
||||
if not self._frozen:
|
||||
self._frozen = True
|
||||
|
||||
def __setattr__(self, *args, **kwargs):
|
||||
if self._frozen:
|
||||
raise Exception("cannot modify frozen object")
|
||||
super().__setattr__(*args, **kwargs)
|
||||
@@ -1,62 +0,0 @@
|
||||
# [Bounties](https://github.com/orgs/commaai/projects/26/views/1)
|
||||
|
||||
Get paid to improve openpilot!
|
||||
|
||||
## Rules
|
||||
|
||||
* code must be merged into openpilot master
|
||||
* bounty eligibility is solely at our discretion
|
||||
* once you open a PR, the bounty is locked to you until you stop working on it
|
||||
* open a ticket at [comma.ai/support](https://comma.ai/support/shop-order) with links to your PRs to claim
|
||||
* get an extra 20% if you redeem your bounty in [comma shop](https://comma.ai/shop) credit (including refunds on previous orders)
|
||||
* for bounties >$100, the first PR gets a lock, which times out after a week of no progress
|
||||
|
||||
We put up each bounty with the intention that it'll get merged, but occasionally the right resolution is to close the bounty, which only becomes clear once some effort is put in.
|
||||
This is still valuable work, so we'll pay out $100 for getting any bounty closed with a good explanation.
|
||||
|
||||
## Issue bounties
|
||||
|
||||
We've tagged bounty-eligible issues across openpilot and the rest of our repos; check out all the open ones [here](https://github.com/orgs/commaai/projects/26/views/1). These bounties roughly work out like this:
|
||||
* **$100** - a few hours of work for an experienced openpilot developer; a good intro for someone new to openpilot
|
||||
* **$300** - a day of work for an experienced openpilot developer
|
||||
* **$500** - a few days of work for an experienced openpilot developer
|
||||
* **$1k+** - a week or two of work (could be less for the right person)
|
||||
|
||||
New bounties can be proposed in the [**#contributing**](https://discord.com/channels/469524606043160576/1183173332531687454) channel in Discord.
|
||||
|
||||
## Car bounties
|
||||
|
||||
The car bounties only apply to cars that have a path to ship in openpilot release, which excludes unsupportable cars (e.g. Fords with a steering lockout) or cars that require extra hardware (Honda Accord with serial steering).
|
||||
|
||||
#### Brand or platform port - $2000
|
||||
Example PR: [commaai/openpilot#23331](https://github.com/commaai/openpilot/pull/23331)
|
||||
|
||||
This is for adding support for an entirely new brand or a substantially new ADAS platform within a brand (e.g. the Volkswagen PQ platform).
|
||||
|
||||
#### Model port - $250
|
||||
Example PR: [commaai/openpilot#30245](https://github.com/commaai/openpilot/pull/30245)
|
||||
|
||||
This is for porting a new car model that runs on a platform openpilot already supports.
|
||||
In the average case, this is a few hours of work for an experienced software developer.
|
||||
|
||||
This bounty also covers getting openpilot supported on a previously unsupported trim of an already supported car, e.g. the Chevy Bolt without ACC.
|
||||
|
||||
#### Reverse Engineering a new Actuation Message - $300
|
||||
|
||||
This is for cars that are already supported, and it has three components:
|
||||
* reverse a new steering, adaptive cruise, or AEB message
|
||||
* merge the DBC definitions to [opendbc](http://github.com/commaai/opendbc)
|
||||
* merge the openpilot code to use it and post a demo route
|
||||
|
||||
The control doesn't have to be perfect, but it should generally do what it's supposed to do.
|
||||
|
||||
### Specific Cars
|
||||
|
||||
#### Rivian R1T or R1S - $3000
|
||||
|
||||
Get a Rivian driving with openpilot.
|
||||
Requires a merged port with lateral control and at least a POC of longitudinal control.
|
||||
|
||||
#### Chevy Bolt with SuperCruise - $2500
|
||||
|
||||
The Bolt is already supported on the trim with standard ACC. Get openpilot working on the trim with SuperCruise. It must be a normal install: no extra pandas or other hardware, no ECU reflashes, etc. The full bounty is for a port with lateral and longitudinal control. $1500 of the bounty can be claimed with a lateral-only port.
|
||||
+12
-13
@@ -4,12 +4,12 @@
|
||||
|
||||
A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
|
||||
|
||||
# 288 Supported Cars
|
||||
# 287 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br> |Video|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Acura&model=ILX 2016-19">Buy Here</a></sub></details>||
|
||||
|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Acura&model=RDX 2016-18">Buy Here</a></sub></details>||
|
||||
|Acura|ILX 2016-19|AcuraWatch Plus|openpilot|26 mph|25 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Acura&model=ILX 2016-19">Buy Here</a></sub></details>||
|
||||
|Acura|RDX 2016-18|AcuraWatch Plus|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Acura&model=RDX 2016-18">Buy Here</a></sub></details>||
|
||||
|Acura|RDX 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Acura&model=RDX 2019-22">Buy Here</a></sub></details>||
|
||||
|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Audi&model=A3 2014-19">Buy Here</a></sub></details>||
|
||||
|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Audi&model=A3 Sportback e-tron 2017-18">Buy Here</a></sub></details>||
|
||||
@@ -25,8 +25,7 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica 2017-18">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica 2019-20">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica 2021-23|All|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica 2021-23">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2017|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica Hybrid 2017">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2018|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica Hybrid 2018">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica Hybrid 2017-18">Buy Here</a></sub></details>||
|
||||
|Chrysler|Pacifica Hybrid 2019-24|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 FCA 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=Chrysler&model=Pacifica Hybrid 2019-24">Buy Here</a></sub></details>||
|
||||
|comma|body|All|openpilot|0 mph|0 mph|[](##)|[](##)|None||
|
||||
|CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=CUPRA&model=Ateca 2018-23">Buy Here</a></sub></details>||
|
||||
@@ -65,20 +64,20 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Honda|Civic 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B 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=Honda&model=Civic 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|Civic Hatchback 2017-21|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=Civic Hatchback 2017-21">Buy Here</a></sub></details>||
|
||||
|Honda|Civic Hatchback 2022-24|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B 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=Honda&model=Civic Hatchback 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|
||||
|Honda|CR-V 2015-16|Touring Trim|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=CR-V 2015-16">Buy Here</a></sub></details>||
|
||||
|Honda|CR-V 2015-16|Touring Trim|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=CR-V 2015-16">Buy Here</a></sub></details>||
|
||||
|Honda|CR-V 2017-22|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=CR-V 2017-22">Buy Here</a></sub></details>||
|
||||
|Honda|CR-V Hybrid 2017-21|Honda Sensing|openpilot available[<sup>1</sup>](#footnotes)|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=CR-V Hybrid 2017-21">Buy Here</a></sub></details>||
|
||||
|Honda|e 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=e 2020">Buy Here</a></sub></details>||
|
||||
|Honda|Fit 2018-20|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Fit 2018-20">Buy Here</a></sub></details>||
|
||||
|Honda|Freed 2020|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Freed 2020">Buy Here</a></sub></details>||
|
||||
|Honda|HR-V 2019-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=HR-V 2019-22">Buy Here</a></sub></details>||
|
||||
|Honda|Fit 2018-20|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Fit 2018-20">Buy Here</a></sub></details>||
|
||||
|Honda|Freed 2020|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Freed 2020">Buy Here</a></sub></details>||
|
||||
|Honda|HR-V 2019-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=HR-V 2019-22">Buy Here</a></sub></details>||
|
||||
|Honda|HR-V 2023|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B 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=Honda&model=HR-V 2023">Buy Here</a></sub></details>||
|
||||
|Honda|Insight 2019-22|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=Insight 2019-22">Buy Here</a></sub></details>||
|
||||
|Honda|Inspire 2018|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A 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=Honda&model=Inspire 2018">Buy Here</a></sub></details>||
|
||||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|25 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Odyssey 2018-20">Buy Here</a></sub></details>||
|
||||
|Honda|Passport 2019-23|All|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Passport 2019-23">Buy Here</a></sub></details>||
|
||||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Pilot 2016-22">Buy Here</a></sub></details>||
|
||||
|Honda|Ridgeline 2017-24|Honda Sensing|openpilot|25 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Ridgeline 2017-24">Buy Here</a></sub></details>||
|
||||
|Honda|Odyssey 2018-20|Honda Sensing|openpilot|26 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Odyssey 2018-20">Buy Here</a></sub></details>||
|
||||
|Honda|Passport 2019-23|All|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Passport 2019-23">Buy Here</a></sub></details>||
|
||||
|Honda|Pilot 2016-22|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Pilot 2016-22">Buy Here</a></sub></details>||
|
||||
|Honda|Ridgeline 2017-24|Honda Sensing|openpilot|26 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec 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=Honda&model=Ridgeline 2017-24">Buy Here</a></sub></details>||
|
||||
|Hyundai|Azera 2022|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K 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=Hyundai&model=Azera 2022">Buy Here</a></sub></details>||
|
||||
|Hyundai|Azera Hybrid 2019|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai C 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=Hyundai&model=Azera Hybrid 2019">Buy Here</a></sub></details>||
|
||||
|Hyundai|Azera Hybrid 2020|All|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai K 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=Hyundai&model=Azera Hybrid 2020">Buy Here</a></sub></details>||
|
||||
|
||||
+11
-11
@@ -1,6 +1,8 @@
|
||||
# How to contribute
|
||||
|
||||
Our software is open source so you can solve your own problems without needing help from others. And if you solve a problem and are so kind, you can upstream it for the rest of the world to use. Check out our [post about externalization](https://blog.comma.ai/a-2020-theme-externalization/). Development activity is coordinated through our GitHub Issues, [GitHub Discussions](https://github.com/commaai/openpilot/discussions), and [Discord](https://discord.comma.ai).
|
||||
Our software is open source so you can solve your own problems without needing help from others. And if you solve a problem and are so kind, you can upstream it for the rest of the world to use. Check out our [post about externalization](https://blog.comma.ai/a-2020-theme-externalization/).
|
||||
|
||||
Development is coordinated through [Discord](https://discord.comma.ai) and GitHub.
|
||||
|
||||
### Getting Started
|
||||
|
||||
@@ -11,7 +13,8 @@ Our software is open source so you can solve your own problems without needing h
|
||||
|
||||
## What contributions are we looking for?
|
||||
|
||||
**openpilot's priorities are [safety](SAFETY.md), stability, quality, and features, in that order.** openpilot is part of comma's mission to *solve self-driving cars while delivering shippable intermediaries*, and **all** development is towards that goal.
|
||||
**openpilot's priorities are [safety](SAFETY.md), stability, quality, and features, in that order.**
|
||||
openpilot is part of comma's mission to *solve self-driving cars while delivering shippable intermediaries*, and all development is towards that goal.
|
||||
|
||||
### What gets merged?
|
||||
|
||||
@@ -27,24 +30,21 @@ All of these are examples of good PRs:
|
||||
|
||||
### What doesn't get merged?
|
||||
|
||||
* **arbitrary style changes**: code is art, and it's up to the author to make it beautiful
|
||||
* **style changes**: code is art, and it's up to the author to make it beautiful
|
||||
* **500+ line PRs**: clean it up, break it up into smaller PRs, or both
|
||||
* **PRs without a clear goal**: every PR must have a singular and clear goal
|
||||
* **UI design changes**: we do not have a good review process for this yet
|
||||
* **UI design**: we do not have a good review process for this yet
|
||||
* **New features**: We believe openpilot is mostly feature-complete, and the rest is a matter of refinement and fixing bugs. As a result of this, most feature PRs will be immediately closed, however the beauty of open source is that forks can and do offer features that upstream openpilot doesn't.
|
||||
* **Negative expected value**: This a class of PRs that makes an improvement, but the risk or validation costs more than the improvement. The risk can be mitigated by first getting a failing test merged.
|
||||
|
||||
### First contribution
|
||||
|
||||
Check out any [good first issue](https://github.com/commaai/openpilot/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to get started.
|
||||
|
||||
### What do I need to contribute?
|
||||
|
||||
A lot of openpilot work requires only a PC, and some requires a comma device.
|
||||
Most car-related contributions require access to that car, plus a comma device installed in the car.
|
||||
[Bounties](https://comma.ai/bounties) are the best place to get started.
|
||||
There's lot of bounties that don't require a comma 3/3X or a car.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Pull requests should be against the master branch. If you're unsure about a contribution, feel free to open a discussion, issue, or draft PR to discuss the problem you're trying to solve.
|
||||
Pull requests should be against the master branch.
|
||||
|
||||
A good pull request has all of the following:
|
||||
* a clearly stated purpose
|
||||
|
||||
+25
-2
@@ -1,3 +1,26 @@
|
||||
# openpilot-docs
|
||||
# openpilot docs
|
||||
|
||||
These docs are autogenerated from [this folder](https://github.com/commaai/openpilot/tree/master/docs) in the main openpilot repository.
|
||||
This is the source for [docs.comma.ai](https://docs.comma.ai).
|
||||
The site is updated on pushes to master by this [workflow](../.github/workflows/docs.yaml).
|
||||
|
||||
## Development
|
||||
NOTE: Those commands must be run in the root directory of openpilot, **not /docs**
|
||||
|
||||
**1. Install the docs dependencies**
|
||||
``` bash
|
||||
pip install .[docs]
|
||||
```
|
||||
|
||||
**2. Build the new site**
|
||||
``` bash
|
||||
mkdocs build
|
||||
```
|
||||
|
||||
**3. Run the new site locally**
|
||||
``` bash
|
||||
mkdocs serve
|
||||
```
|
||||
|
||||
References:
|
||||
* https://www.mkdocs.org/getting-started/
|
||||
* https://github.com/ntno/mkdocs-terminal
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ pytest
|
||||
cd system/loggerd && pytest .
|
||||
|
||||
# run the linter
|
||||
pre-commit run --all
|
||||
op lint
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# What is a car port?
|
||||
|
||||
A car port enables openpilot support on a particular car. Each car model openpilot supports needs to be individually ported. All car ports live in `openpilot/selfdrive/car/car_specific.py` and `opendbc_repo/opendbc/car`.
|
||||
|
||||
The complexity of a car port varies depending on many factors including:
|
||||
* existing openpilot support for similar cars
|
||||
* architecture and APIs available in the car
|
||||
|
||||
|
||||
# Structure of a car port
|
||||
* `interface.py`: Interface for the car, defines the CarInterface class
|
||||
* `carstate.py`: Reads CAN from car and builds openpilot CarState message
|
||||
* `carcontroller.py`: Builds CAN messages to send to car
|
||||
* `values.py`: Limits for actuation, general constants for cars, and supported car documentation
|
||||
* `radar_interface.py`: Interface for parsing radar points from the car
|
||||
|
||||
|
||||
# Overiew
|
||||
|
||||
[Jason Young](https://github.com/jyoung8607) gave a talk at COMMA_CON with an overview of the car porting process. The talk is available on YouTube:
|
||||
|
||||
https://youtu.be/KcfzEHB6ms4?si=5szh1PX6TksOCKmM
|
||||
@@ -0,0 +1,8 @@
|
||||
# openpilot glossary
|
||||
|
||||
* **route**:
|
||||
* **segment**: routes are split into one minute chunks called segments.
|
||||
* **panda**: this is . See the repo.
|
||||
* **onroad**:
|
||||
* **offroad**:
|
||||
* **comma 3X**:
|
||||
@@ -1,10 +1,8 @@
|
||||
# loggerd
|
||||
# Logging
|
||||
|
||||
openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge.
|
||||
|
||||
Check out our [python library](https://github.com/commaai/openpilot/blob/master/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot.
|
||||
|
||||
## log types
|
||||
Check out our [Python library](https://github.com/commaai/openpilot/blob/master/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot.
|
||||
|
||||
For each segment, openpilot records the following log types:
|
||||
|
||||
@@ -15,9 +13,10 @@ rlogs contain all the messages passed amongst openpilot's processes. See [cereal
|
||||
## {f,e,d}camera.hevc
|
||||
|
||||
Each camera stream is H.265 encoded and written to its respective file.
|
||||
* fcamera.hevc is the road camera
|
||||
* ecamera.hevc is the wide road camera
|
||||
* dcamera.hevc is the driver camera
|
||||
|
||||
* `fcamera.hevc` is the road camera
|
||||
* `ecamera.hevc` is the wide road camera
|
||||
* `dcamera.hevc` is the driver camera
|
||||
|
||||
## qlog.bz2 & qcamera.ts
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../SAFETY.md
|
||||
@@ -0,0 +1 @@
|
||||
# Architecture
|
||||
@@ -0,0 +1,31 @@
|
||||
# Roadmap
|
||||
|
||||
This is the roadmap for the next major openpilot releases. Also check out
|
||||
|
||||
* [Milestones](https://github.com/commaai/openpilot/milestones) for minor releases
|
||||
* [Projects](https://github.com/commaai/openpilot/projects?query=is%3Aopen) for shorter-term projects not tied to releases
|
||||
* [Bounties](https://comma.ai/bounties) for paid individual issues
|
||||
* [#current-projects](https://discord.com/channels/469524606043160576/1249579909739708446) in Discord for discussion on work-in-progress projects
|
||||
|
||||
## openpilot 0.10
|
||||
|
||||
openpilot 0.10 will be the first release with a driving policy trained in
|
||||
a [learned simulator](https://youtu.be/EqQNZXqzFSI).
|
||||
|
||||
* Driving model trained in a learned simlator
|
||||
* Always-on driver monitoring (behind a toggle)
|
||||
* GPS removed from the driving stack
|
||||
* 100KB qlogs
|
||||
* `master-ci` pushed after 1000 hours of hardware-in-the-loop testing
|
||||
* Car interface code moved into [opendbc](https://github.com/commaai/opendbc)
|
||||
* openpilot on PC for Linux x86, Linux arm64, and Mac (Apple Silicon)
|
||||
|
||||
## openpilot 1.0
|
||||
|
||||
openpilot 1.0 will feature a fully end-to-end driving policy.
|
||||
|
||||
* End-to-end longitudinal control in Chill mode
|
||||
* Automatic Emergency Braking (AEB)
|
||||
* Driver monitoring with sleep detection
|
||||
* Rolling updates/releases pushed out by CI
|
||||
* [panda safety 1.0](https://github.com/orgs/commaai/projects/27)
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# 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), 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](docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](docs/INTEGRATION.md) and [limitations](docs/LIMITATIONS.md).
|
||||
[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](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). In addition, while openpilot is engaged, a camera-based Driver Monitoring (DM) feature alerts distracted and asleep drivers. See more about [the vehicle integration](https://github.com/commaai/openpilot/blob/master/docs/INTEGRATION.md) and [limitations](https://github.com/commaai/openpilot/blob/master/docs/LIMITATIONS.md).
|
||||
|
||||
|
||||
## How do I use it?
|
||||
@@ -1,39 +1,42 @@
|
||||
# SSH
|
||||
# connect to a comma 3/3X
|
||||
|
||||
## Quick Start
|
||||
A comma 3/3X is a normal [Linux](https://github.com/commaai/agnos-builder) computer that exposes [SSH](https://wiki.archlinux.org/title/Secure_Shell) and a [serial console](https://wiki.archlinux.org/title/Working_with_the_serial_console).
|
||||
|
||||
## Serial Console
|
||||
|
||||
On both the comma three and 3X, the serial console is accessible from the main OBD-C port.
|
||||
Connect the comma 3/3X to your computer with a normal USB C cable, or use a [comma serial](https://comma.ai/shop/comma-serial) for steady 12V power.
|
||||
|
||||
On the comma three, the serial console is exposed through a UART-to-USB chip, and `tools/scripts/serial.sh` can be used to connect.
|
||||
|
||||
On the comma 3X, the serial console is accessible through the [panda](https://github.com/commaai/panda) using the `panda/tests/som_debug.sh` script.
|
||||
|
||||
## SSH
|
||||
|
||||
In order to SSH into your device, you'll need a GitHub account with SSH keys. See this [GitHub article](https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh) for getting your account setup with SSH keys.
|
||||
|
||||
* Enable SSH in your device's settings
|
||||
* Enter your GitHub username in the device's settings
|
||||
* Connect to your device
|
||||
* Username: `comma`
|
||||
* Port: `22` or `8022`
|
||||
* Username: `comma`
|
||||
* Port: `22`
|
||||
|
||||
Here's an example command for connecting to your device using its tethered connection:<br />
|
||||
`ssh comma@192.168.43.1`
|
||||
|
||||
For doing development work on device, it's recommended to use [SSH agent forwarding](https://docs.github.com/en/developers/overview/using-ssh-agent-forwarding).
|
||||
|
||||
## Notes
|
||||
### Notes
|
||||
|
||||
The public keys are only fetched from your GitHub account once. In order to update your device's authorized keys, you'll need to re-enter your GitHub username.
|
||||
|
||||
The `id_rsa` key in this directory only works while your device is in the setup state with no software installed. After installation, that default key will be removed.
|
||||
|
||||
See the [community wiki](https://github.com/commaai/openpilot/wiki/SSH) for more detailed instructions and information.
|
||||
#### ssh.comma.ai proxy
|
||||
|
||||
# Connecting to ssh.comma.ai
|
||||
SSH into your comma device from anywhere with `ssh.comma.ai`. Requires a [comma prime subscription](https://comma.ai/connect).
|
||||
With a [comma prime subscription](https://comma.ai/connect), you can SSH into your comma device from anywhere.
|
||||
|
||||
## Setup
|
||||
|
||||
With software version 0.6.1 or newer, enter your GitHub username on your device under Developer Settings. Your GitHub authorized public keys will become your authorized SSH keys for `ssh.comma.ai`. You can add any additional keys in `/system/comma/home/.ssh/authorized_keys.persist`.
|
||||
|
||||
## Recommended .ssh/config
|
||||
|
||||
With the below SSH configuration, you can type `ssh comma-{dongleid}` to connect to your device through `ssh.comma.ai`.<br />
|
||||
For example: `ssh comma-ffffffffffffffff`
|
||||
With the below SSH configuration, you can type `ssh comma-{dongleid}` to connect to your device through `ssh.comma.ai`.
|
||||
|
||||
```
|
||||
Host comma-*
|
||||
@@ -41,20 +44,21 @@ Host comma-*
|
||||
User comma
|
||||
IdentityFile ~/.ssh/my_github_key
|
||||
ProxyCommand ssh %h@ssh.comma.ai -W %h:%p
|
||||
|
||||
Host ssh.comma.ai
|
||||
Hostname ssh.comma.ai
|
||||
Port 22
|
||||
IdentityFile ~/.ssh/my_github_key
|
||||
```
|
||||
|
||||
## One-off connection
|
||||
### One-off connection
|
||||
|
||||
```
|
||||
ssh -i ~/.ssh/my_github_key -o ProxyCommand="ssh -i ~/.ssh/my_github_key -W %h:%p -p %p %h@ssh.comma.ai" comma@ffffffffffffffff
|
||||
```
|
||||
(Replace `ffffffffffffffff` with your dongle_id)
|
||||
|
||||
## ssh.comma.ai host key fingerprint
|
||||
### ssh.comma.ai host key fingerprint
|
||||
|
||||
```
|
||||
Host key fingerprint is SHA256:X22GOmfjGb9J04IA2+egtdaJ7vW9Fbtmpz9/x8/W1X4
|
||||
@@ -0,0 +1,14 @@
|
||||
# Replay
|
||||
|
||||
Replaying is a critical tool for openpilot development and debugging.
|
||||
|
||||
## Replaying a route
|
||||
*Hardware required: none*
|
||||
|
||||
Just run `tools/replay/replay --demo`.
|
||||
|
||||
## Replaying CAN data
|
||||
*Hardware required: jungle and comma 3/3X*
|
||||
|
||||
1. Connect your PC to a jungle.
|
||||
2.
|
||||
@@ -0,0 +1,98 @@
|
||||
# Turn the speed blue
|
||||
*A getting started guide for openpilot development*
|
||||
|
||||
In 30 minutes, we'll get an openpilot development environment setup on your computer and make some changes to openpilot's UI.
|
||||
|
||||
And if you have a comma 3/3X, we'll deploy the change to your device for testing.
|
||||
|
||||
## 1. Setup your development environment
|
||||
|
||||
Run this to clone openpilot and install all the dependencies:
|
||||
```bash
|
||||
bash <(curl -fsSL openpilot.comma.ai)
|
||||
```
|
||||
|
||||
Navigate to openpilot folder & activate a Python virtual environment
|
||||
```bash
|
||||
cd openpilot
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Then, compile openpilot:
|
||||
```bash
|
||||
scons -j8
|
||||
```
|
||||
|
||||
## 2. Run replay
|
||||
|
||||
We'll run the `replay` tool with the demo route to get data streaming for testing our UI changes.
|
||||
```bash
|
||||
# in terminal 1
|
||||
tools/replay/replay --demo
|
||||
|
||||
# in terminal 2
|
||||
selfdrive/ui/ui
|
||||
```
|
||||
|
||||
The openpilot UI should launch and show a replay of the demo route.
|
||||
|
||||
If you have your own comma device, you can replace `--demo` with one of your own routes from comma connect.
|
||||
|
||||
## 3. Make the speed blue
|
||||
|
||||
Search for “mph” with git grep in the `ui` folder.
|
||||
```bash
|
||||
$ git grep "mph" selfdrive/ui/
|
||||
paint.cc: ui_draw_text(s, s->fb_w/2, 290, s->scene.is_metric ? "km/h" : "mph", 36 * 2.5, COLOR_WHITE_ALPHA(200), "sans-regular");
|
||||
```
|
||||
|
||||
The line right above contains the actual speed. Unfortunately, COLOR_BLUE isn’t defined, but a git grep of COLOR_WHITE shows it’s nvgRGBA(255, 255, 255, 255). Personally, I like a lighter blue, so I went with #8080FF.
|
||||
```bash
|
||||
$ git diff
|
||||
diff --git a/selfdrive/ui/paint.cc b/selfdrive/ui/paint.cc
|
||||
index 821d95115..cc996eaa1 100644
|
||||
--- a/selfdrive/ui/paint.cc
|
||||
+++ b/selfdrive/ui/paint.cc
|
||||
@@ -175,8 +175,8 @@ static void ui_draw_vision_speed(UIState *s) {
|
||||
const float speed = std::max(0.0, (*s->sm)["carState"].getCarState().getVEgo() * (s->scene.is_metric ? 3.6 : 2.2369363));
|
||||
const std::string speed_str = std::to_string((int)std::nearbyint(speed));
|
||||
nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BASELINE);
|
||||
- ui_draw_text(s, s->fb_w/2, 210, speed_str.c_str(), 96 * 2.5, COLOR_WHITE, "sans-bold");
|
||||
- ui_draw_text(s, s->fb_w/2, 290, s->scene.is_metric ? "km/h" : "mph", 36 * 2.5, COLOR_WHITE_ALPHA(200), "sans-regular");
|
||||
+ ui_draw_text(s, s->fb_w/2, 210, speed_str.c_str(), 96 * 2.5, nvgRGBA(128, 128, 255, 255), "sans-bold");
|
||||
+ ui_draw_text(s, s->fb_w/2, 290, s->scene.is_metric ? "km/h" : "mph", 36 * 2.5, nvgRGBA(128, 128, 255, 200), "sans-regular");
|
||||
}
|
||||
|
||||
static void ui_draw_vision_event(UIState *s) {
|
||||
```
|
||||
|
||||
|
||||
## 4. Rebuild UI, and admire your work
|
||||
|
||||
```
|
||||
scons -j8 && selfdrive/ui/ui
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 5. Push your fork to GitHub
|
||||
|
||||
Click fork on GitHub. Then, push with:
|
||||
```bash
|
||||
git remote rm origin
|
||||
git remote add origin git@github.com:<your-github-username>/openpilot.git
|
||||
git add .
|
||||
git commit -m "Make the speed blue."
|
||||
git push --set-upstream origin master
|
||||
```
|
||||
|
||||
## 6. Run your fork on device in your car!
|
||||
|
||||
Uninstall openpilot from your device through the settings. Then, enter the URL for your very own installer:
|
||||
```
|
||||
installer.comma.ai/<your-github-username>/master
|
||||
```
|
||||
|
||||
## 7. Admire your work IRL
|
||||
|
||||

|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
getting-started/what-is-openpilot.md
|
||||
@@ -1,12 +0,0 @@
|
||||
This is the source for a new https://docs.comma.ai. It's not hosted anywhere yet, but it's easy to run locally.
|
||||
|
||||
https://www.mkdocs.org/getting-started/
|
||||
|
||||
```
|
||||
pip install mkdocs mkdocs-terminal
|
||||
mkdocs serve
|
||||
```
|
||||
|
||||
inspiration:
|
||||
* https://rerun.io/docs/
|
||||
* https://docs.expo.dev/
|
||||
@@ -1,9 +0,0 @@
|
||||
# What is a car port?
|
||||
|
||||
All car ports live in `openpilot/selfdrive/car/`.
|
||||
|
||||
* interface.py: Interface for the car, defines the CarInterface class
|
||||
* carstate.py: Reads CAN from car and builds openpilot CarState message
|
||||
* carcontroller.py: Builds CAN messages to send to car
|
||||
* values.py: Limits for actuation, general constants for cars, and supported car documentation
|
||||
* radar_interface.py: Interface for parsing radar points from the car
|
||||
@@ -1,4 +0,0 @@
|
||||
This section is for how-to's on common workflows.
|
||||
|
||||
They'll be like this blog post we wrote:
|
||||
https://blog.comma.ai/turning-the-speed-blue/
|
||||
@@ -1,18 +0,0 @@
|
||||
site_name: openpilot docs
|
||||
docs_dir: docs
|
||||
repo_url: https://github.com/commaai/openpilot/
|
||||
|
||||
theme:
|
||||
name: terminal
|
||||
features:
|
||||
- navigation.side.toc.hide
|
||||
|
||||
nav:
|
||||
- Getting Started:
|
||||
- What is openpilot?: getting-started/what-is-openpilot.md
|
||||
- How-to:
|
||||
- Turn the speed blue: how-to/turning-the-speed-blue.md
|
||||
- Car Porting:
|
||||
- What is a car port?: car-porting/what-is-a-car-port.md
|
||||
- Porting a car brand: car-porting/brand-port.md
|
||||
- Porting a car model: car-porting/model-port.md
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$BASEDIR" ]; then
|
||||
BASEDIR="/data/openpilot"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
export OMP_NUM_THREADS=1
|
||||
export MKL_NUM_THREADS=1
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
exec ./launch_chffrplus.sh
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
site_name: openpilot docs
|
||||
repo_url: https://github.com/commaai/openpilot/
|
||||
site_url: https://docs.comma.ai
|
||||
|
||||
exclude_docs: README.md
|
||||
|
||||
strict: true
|
||||
docs_dir: docs
|
||||
site_dir: docs_site/
|
||||
|
||||
theme:
|
||||
name: readthedocs
|
||||
navigation_depth: 3
|
||||
|
||||
nav:
|
||||
- Getting Started:
|
||||
- What is openpilot?: getting-started/what-is-openpilot.md
|
||||
- How-to:
|
||||
- Turn the speed blue: how-to/turn-the-speed-blue.md
|
||||
- Connect to a comma 3/3X: how-to/connect-to-comma.md
|
||||
#- Replay a drive: how-to/replay-a-drive.md
|
||||
- Concepts:
|
||||
- Logs: concepts/logs.md
|
||||
- Safety: concepts/safety.md
|
||||
- Car Porting:
|
||||
- What is a car port?: car-porting/what-is-a-car-port.md
|
||||
- Porting a car brand: car-porting/brand-port.md
|
||||
- Porting a car model: car-porting/model-port.md
|
||||
- Contributing:
|
||||
- Roadmap: contributing/roadmap.md
|
||||
#- Architecture: contributing/architecture.md
|
||||
- Contributing Guide →: https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md
|
||||
- Links:
|
||||
- Blog →: https://blog.comma.ai
|
||||
- Bounties →: https://comma.ai/bounties
|
||||
- GitHub →: https://github.com/commaai
|
||||
- Discord →: https://discord.comma.ai
|
||||
- X →: https://x.com/comma_ai
|
||||
+1
-1
Submodule msgq_repo updated: 74074d650f...cdcf84f44a
-1
Submodule opendbc deleted from de39b143a3
Submodule
+1
Submodule opendbc_repo added at 81fcc40cc7
+1
-1
Submodule panda updated: 376408bb4f...866bd9c3bc
+37
-24
@@ -26,7 +26,7 @@ dependencies = [
|
||||
"pycapnp",
|
||||
"Cython",
|
||||
"setuptools",
|
||||
"numpy < 2.0.0", # control does not support numpy 2
|
||||
"numpy < 2.0.0",
|
||||
|
||||
# body / webrtcd
|
||||
"aiohttp",
|
||||
@@ -52,27 +52,29 @@ dependencies = [
|
||||
"websocket_client",
|
||||
|
||||
# acados deps
|
||||
"casadi",
|
||||
"casadi >=3.6.6", # 3.12 fixed in 3.6.6
|
||||
"future-fstrings",
|
||||
|
||||
# these should be removed
|
||||
"psutil",
|
||||
"pycryptodome", # used in updated/casync, panda, body, and a test
|
||||
"setproctitle",
|
||||
|
||||
#logreader
|
||||
"zstd",
|
||||
# logreader
|
||||
"zstandard",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
docs = [
|
||||
"Jinja2",
|
||||
"natsort",
|
||||
"mkdocs",
|
||||
]
|
||||
|
||||
testing = [
|
||||
"coverage",
|
||||
"hypothesis ==6.47.*",
|
||||
"mypy",
|
||||
"pre-commit",
|
||||
"pytest",
|
||||
"pytest-cov",
|
||||
"pytest-cpp",
|
||||
@@ -83,45 +85,37 @@ testing = [
|
||||
"pytest-asyncio",
|
||||
"pytest-mock",
|
||||
"pytest-repeat",
|
||||
"ruff"
|
||||
"ruff",
|
||||
"codespell",
|
||||
"pre-commit-hooks",
|
||||
]
|
||||
|
||||
dev = [
|
||||
"av",
|
||||
"azure-identity",
|
||||
"azure-storage-blob",
|
||||
"breathe",
|
||||
"control",
|
||||
"dictdiffer",
|
||||
"flaky",
|
||||
"inputs",
|
||||
"lru-dict",
|
||||
"matplotlib",
|
||||
"metadrive-simulator; platform_machine != 'aarch64'",
|
||||
"mpld3",
|
||||
"myst-parser",
|
||||
"natsort",
|
||||
"opencv-python-headless",
|
||||
"metadrive-simulator @ https://github.com/commaai/metadrive/releases/download/MetaDrive-minimal/metadrive_simulator-0.4.2.3-py3-none-any.whl ; (platform_machine != 'aarch64')",
|
||||
"parameterized >=0.8, <0.9",
|
||||
#pprofile = "*"
|
||||
#"pprofile",
|
||||
"pyautogui",
|
||||
"pygame",
|
||||
"pyopencl; platform_machine != 'aarch64'", # broken on arm64
|
||||
"pytools < 2024.1.11; platform_machine != 'aarch64'", # pyopencl use a broken version
|
||||
"pywinctl",
|
||||
"pyprof2calltree",
|
||||
"rerun-sdk",
|
||||
"rerun-sdk >= 0.18",
|
||||
"tabulate",
|
||||
"types-requests",
|
||||
"types-tabulate",
|
||||
|
||||
# this is only pinned since 5.15.11 is broken
|
||||
"pyqt5 ==5.15.2; platform_machine == 'x86_64'", # no aarch64 wheels for macOS/linux
|
||||
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
metadrive-simulator = { git = "https://github.com/commaai/metadrive.git", branch = "opencv_headless" }
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://comma.ai"
|
||||
|
||||
@@ -132,9 +126,12 @@ build-backend = "hatchling.build"
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = [ "." ]
|
||||
|
||||
[tool.hatch.metadata]
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
addopts = "--ignore=openpilot/ --ignore=cereal/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
|
||||
addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup"
|
||||
cpp_files = "test_*"
|
||||
cpp_harness = "selfdrive/test/cpp_harness.py"
|
||||
python_files = "test_*.py"
|
||||
@@ -147,6 +144,7 @@ testpaths = [
|
||||
"common",
|
||||
"selfdrive/pandad",
|
||||
"selfdrive/car",
|
||||
"selfdrive/opcar",
|
||||
"selfdrive/controls",
|
||||
"selfdrive/locationd",
|
||||
"selfdrive/monitoring",
|
||||
@@ -167,15 +165,24 @@ testpaths = [
|
||||
"cereal/messaging/tests",
|
||||
]
|
||||
|
||||
[tool.codespell]
|
||||
quiet-level = 3
|
||||
# if you've got a short variable name that's getting flagged, add it here
|
||||
ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead"
|
||||
builtin = "clear,rare,informal,code,names,en-GB_to_en-US"
|
||||
skip = "./third_party/*, ./tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.ts, uv.lock, *.onnx, ./cereal/gen/*, */c_generated_code/*"
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.11"
|
||||
plugins = [
|
||||
"numpy.typing.mypy_plugin",
|
||||
]
|
||||
exclude = [
|
||||
"body/",
|
||||
"cereal/",
|
||||
"msgq/",
|
||||
"msgq_repo/",
|
||||
"opendbc/",
|
||||
"opendbc_repo/",
|
||||
"panda/",
|
||||
"rednose/",
|
||||
"rednose_repo/",
|
||||
@@ -200,6 +207,10 @@ warn_return_any=true
|
||||
# allow implicit optionals for default args
|
||||
implicit_optional = true
|
||||
|
||||
local_partial_types=true
|
||||
explicit_package_bases=true
|
||||
disable_error_code = "annotation-unchecked"
|
||||
|
||||
# https://beta.ruff.rs/docs/configuration/#using-pyprojecttoml
|
||||
[tool.ruff]
|
||||
indent-width = 2
|
||||
@@ -223,7 +234,7 @@ lint.ignore = [
|
||||
"UP038", # (x, y) -> x|y for isinstance
|
||||
]
|
||||
line-length = 160
|
||||
target-version="py311"
|
||||
target-version ="py311"
|
||||
exclude = [
|
||||
"body",
|
||||
"cereal",
|
||||
@@ -235,7 +246,8 @@ exclude = [
|
||||
"teleoprtc_repo",
|
||||
"third_party",
|
||||
]
|
||||
lint.flake8-implicit-str-concat.allow-multiline=false
|
||||
lint.flake8-implicit-str-concat.allow-multiline = false
|
||||
|
||||
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
||||
"selfdrive".msg = "Use openpilot.selfdrive"
|
||||
"common".msg = "Use openpilot.common"
|
||||
@@ -247,5 +259,6 @@ lint.flake8-implicit-str-concat.allow-multiline=false
|
||||
|
||||
[tool.coverage.run]
|
||||
concurrency = ["multiprocessing", "thread"]
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
|
||||
+1
-1
Submodule rednose_repo updated: 72b3479bab...90c891fe89
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
while read hash submodule ref; do
|
||||
git -C $submodule fetch --depth 3000 origin master
|
||||
git -C $submodule fetch --depth 4000 origin master
|
||||
git -C $submodule branch -r --contains $hash | grep "origin/master"
|
||||
if [ "$?" -eq 0 ]; then
|
||||
echo "$submodule ok"
|
||||
|
||||
+47
-54
@@ -10,14 +10,12 @@ ROOT = HERE + "/.."
|
||||
# - minimizing release download size
|
||||
# - keeping the diff readable
|
||||
blacklist = [
|
||||
"body/STL/",
|
||||
|
||||
"panda/drivers/",
|
||||
"panda/examples/",
|
||||
"panda/tests/safety/",
|
||||
|
||||
"opendbc/.*.dbc$",
|
||||
"opendbc/generator/",
|
||||
"opendbc_repo/dbc/.*.dbc$",
|
||||
"opendbc_repo/dbc/generator/",
|
||||
|
||||
"cereal/.*test.*",
|
||||
"^common/tests/",
|
||||
@@ -28,7 +26,6 @@ blacklist = [
|
||||
"selfdrive/car/tests/test_models.*",
|
||||
|
||||
"^tools/",
|
||||
"^scripts/",
|
||||
"^tinygrad_repo/",
|
||||
|
||||
"matlab.*.md",
|
||||
@@ -76,55 +73,51 @@ whitelist = [
|
||||
"tinygrad_repo/tinygrad/.*.py",
|
||||
|
||||
# TODO: do this automatically
|
||||
"opendbc/comma_body.dbc",
|
||||
"opendbc/chrysler_ram_hd_generated.dbc",
|
||||
"opendbc/chrysler_ram_dt_generated.dbc",
|
||||
"opendbc/chrysler_pacifica_2017_hybrid_generated.dbc",
|
||||
"opendbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc",
|
||||
"opendbc/gm_global_a_powertrain_generated.dbc",
|
||||
"opendbc/gm_global_a_object.dbc",
|
||||
"opendbc/gm_global_a_chassis.dbc",
|
||||
"opendbc/FORD_CADS.dbc",
|
||||
"opendbc/ford_fusion_2018_adas.dbc",
|
||||
"opendbc/ford_lincoln_base_pt.dbc",
|
||||
"opendbc/honda_accord_2018_can_generated.dbc",
|
||||
"opendbc/acura_ilx_2016_can_generated.dbc",
|
||||
"opendbc/acura_rdx_2018_can_generated.dbc",
|
||||
"opendbc/acura_rdx_2020_can_generated.dbc",
|
||||
"opendbc/honda_civic_touring_2016_can_generated.dbc",
|
||||
"opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc",
|
||||
"opendbc/honda_crv_touring_2016_can_generated.dbc",
|
||||
"opendbc/honda_crv_ex_2017_can_generated.dbc",
|
||||
"opendbc/honda_crv_ex_2017_body_generated.dbc",
|
||||
"opendbc/honda_crv_executive_2016_can_generated.dbc",
|
||||
"opendbc/honda_fit_ex_2018_can_generated.dbc",
|
||||
"opendbc/honda_odyssey_exl_2018_generated.dbc",
|
||||
"opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc",
|
||||
"opendbc/honda_insight_ex_2019_can_generated.dbc",
|
||||
"opendbc/acura_ilx_2016_nidec.dbc",
|
||||
"opendbc/honda_civic_ex_2022_can_generated.dbc",
|
||||
"opendbc/hyundai_canfd.dbc",
|
||||
"opendbc/hyundai_kia_generic.dbc",
|
||||
"opendbc/hyundai_kia_mando_front_radar_generated.dbc",
|
||||
"opendbc/mazda_2017.dbc",
|
||||
"opendbc/nissan_x_trail_2017_generated.dbc",
|
||||
"opendbc/nissan_leaf_2018_generated.dbc",
|
||||
"opendbc/subaru_global_2017_generated.dbc",
|
||||
"opendbc/subaru_global_2020_hybrid_generated.dbc",
|
||||
"opendbc/subaru_outback_2015_generated.dbc",
|
||||
"opendbc/subaru_outback_2019_generated.dbc",
|
||||
"opendbc/subaru_forester_2017_generated.dbc",
|
||||
"opendbc/toyota_tnga_k_pt_generated.dbc",
|
||||
"opendbc/toyota_new_mc_pt_generated.dbc",
|
||||
"opendbc/toyota_nodsu_pt_generated.dbc",
|
||||
"opendbc/toyota_adas.dbc",
|
||||
"opendbc/toyota_tss2_adas.dbc",
|
||||
"opendbc/vw_golf_mk4.dbc",
|
||||
"opendbc/vw_mqb_2010.dbc",
|
||||
"opendbc/tesla_can.dbc",
|
||||
"opendbc/tesla_radar_bosch_generated.dbc",
|
||||
"opendbc/tesla_radar_continental_generated.dbc",
|
||||
"opendbc/tesla_powertrain.dbc",
|
||||
"opendbc_repo/dbc/comma_body.dbc",
|
||||
"opendbc_repo/dbc/chrysler_ram_hd_generated.dbc",
|
||||
"opendbc_repo/dbc/chrysler_ram_dt_generated.dbc",
|
||||
"opendbc_repo/dbc/chrysler_pacifica_2017_hybrid_generated.dbc",
|
||||
"opendbc_repo/dbc/chrysler_pacifica_2017_hybrid_private_fusion.dbc",
|
||||
"opendbc_repo/dbc/gm_global_a_powertrain_generated.dbc",
|
||||
"opendbc_repo/dbc/gm_global_a_object.dbc",
|
||||
"opendbc_repo/dbc/gm_global_a_chassis.dbc",
|
||||
"opendbc_repo/dbc/FORD_CADS.dbc",
|
||||
"opendbc_repo/dbc/ford_fusion_2018_adas.dbc",
|
||||
"opendbc_repo/dbc/ford_lincoln_base_pt.dbc",
|
||||
"opendbc_repo/dbc/honda_accord_2018_can_generated.dbc",
|
||||
"opendbc_repo/dbc/acura_ilx_2016_can_generated.dbc",
|
||||
"opendbc_repo/dbc/acura_rdx_2018_can_generated.dbc",
|
||||
"opendbc_repo/dbc/acura_rdx_2020_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_civic_touring_2016_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_civic_hatchback_ex_2017_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_crv_touring_2016_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_crv_ex_2017_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_crv_ex_2017_body_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_crv_executive_2016_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_fit_ex_2018_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_odyssey_exl_2018_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc",
|
||||
"opendbc_repo/dbc/honda_insight_ex_2019_can_generated.dbc",
|
||||
"opendbc_repo/dbc/acura_ilx_2016_nidec.dbc",
|
||||
"opendbc_repo/dbc/honda_civic_ex_2022_can_generated.dbc",
|
||||
"opendbc_repo/dbc/hyundai_canfd.dbc",
|
||||
"opendbc_repo/dbc/hyundai_kia_generic.dbc",
|
||||
"opendbc_repo/dbc/hyundai_kia_mando_front_radar_generated.dbc",
|
||||
"opendbc_repo/dbc/mazda_2017.dbc",
|
||||
"opendbc_repo/dbc/nissan_x_trail_2017_generated.dbc",
|
||||
"opendbc_repo/dbc/nissan_leaf_2018_generated.dbc",
|
||||
"opendbc_repo/dbc/subaru_global_2017_generated.dbc",
|
||||
"opendbc_repo/dbc/subaru_global_2020_hybrid_generated.dbc",
|
||||
"opendbc_repo/dbc/subaru_outback_2015_generated.dbc",
|
||||
"opendbc_repo/dbc/subaru_outback_2019_generated.dbc",
|
||||
"opendbc_repo/dbc/subaru_forester_2017_generated.dbc",
|
||||
"opendbc_repo/dbc/toyota_tnga_k_pt_generated.dbc",
|
||||
"opendbc_repo/dbc/toyota_new_mc_pt_generated.dbc",
|
||||
"opendbc_repo/dbc/toyota_nodsu_pt_generated.dbc",
|
||||
"opendbc_repo/dbc/toyota_adas.dbc",
|
||||
"opendbc_repo/dbc/toyota_tss2_adas.dbc",
|
||||
"opendbc_repo/dbc/vw_golf_mk4.dbc",
|
||||
"opendbc_repo/dbc/vw_mqb_2010.dbc",
|
||||
]
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "usage: $0 <pull-request-number>"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
nmcli connection modify --temporary esim ipv4.route-metric 1 ipv6.route-metric 1
|
||||
nmcli con up esim
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from collections import Counter
|
||||
from pprint import pprint
|
||||
|
||||
from openpilot.selfdrive.car.docs import get_all_car_docs
|
||||
from opendbc.car.docs import get_all_car_docs
|
||||
|
||||
if __name__ == "__main__":
|
||||
cars = get_all_car_docs()
|
||||
|
||||
Executable
+391
@@ -0,0 +1,391 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
SRC=/tmp/openpilot/
|
||||
SRC_CLONE=/tmp/openpilot-clone/
|
||||
OUT=/tmp/openpilot-tiny/
|
||||
|
||||
REWRITE_IGNORE_BRANCHES=(
|
||||
dashcam3
|
||||
devel
|
||||
master-ci
|
||||
nightly
|
||||
release2
|
||||
release3
|
||||
release3-staging
|
||||
)
|
||||
|
||||
VALIDATE_IGNORE_FILES=(
|
||||
".github/ISSUE_TEMPLATE/bug_report.md"
|
||||
".github/pull_request_template.md"
|
||||
)
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd $DIR
|
||||
|
||||
LOGS_DIR=$DIR/git-rewrite-$(date +"%Y-%m-%dT%H:%M:%S%z")
|
||||
mkdir -p $LOGS_DIR
|
||||
|
||||
GIT_REWRITE_LOG=$LOGS_DIR/git-rewrite-log.txt
|
||||
BRANCH_DIFF_LOG=$LOGS_DIR/branch-diff-log.txt
|
||||
COMMIT_DIFF_LOG=$LOGS_DIR/commit-diff-log.txt
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
exec > >(while IFS= read -r line; do
|
||||
CURRENT_TIME=$(date +%s)
|
||||
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
|
||||
echo "[${ELAPSED_TIME}s] $line"
|
||||
done | tee -a "$GIT_REWRITE_LOG") 2>&1
|
||||
|
||||
# INSTALL git-filter-repo
|
||||
if [ ! -f /tmp/git-filter-repo ]; then
|
||||
echo "Installing git-filter-repo..."
|
||||
curl -sSo /tmp/git-filter-repo https://raw.githubusercontent.com/newren/git-filter-repo/main/git-filter-repo
|
||||
chmod +x /tmp/git-filter-repo
|
||||
fi
|
||||
|
||||
# MIRROR openpilot
|
||||
if [ ! -d $SRC ]; then
|
||||
echo "Mirroring openpilot..."
|
||||
git clone --mirror https://github.com/commaai/openpilot.git $SRC # 4.18 GiB (488034 objects)
|
||||
|
||||
cd $SRC
|
||||
|
||||
echo "Starting size $(du -sh .)"
|
||||
|
||||
git remote update
|
||||
|
||||
# the git-filter-repo analysis is bliss - can be found in the repo root/filter-repo/analysis
|
||||
echo "Analyzing with git-filter-repo..."
|
||||
/tmp/git-filter-repo --force --analyze
|
||||
|
||||
echo "Pushing to openpilot-archive..."
|
||||
# push to archive repo - in smaller parts because the 2 GB push limit - https://docs.github.com/en/get-started/using-git/troubleshooting-the-2-gb-push-limit
|
||||
ARCHIVE_REPO=git@github.com:commaai/openpilot-archive.git
|
||||
git push --prune $ARCHIVE_REPO +refs/heads/master:refs/heads/master # push master first so it's the default branch (when openpilot-archive is an empty repo)
|
||||
git push --prune $ARCHIVE_REPO +refs/heads/*:refs/heads/* # 956.39 MiB (110725 objects)
|
||||
git push --prune $ARCHIVE_REPO +refs/tags/*:refs/tags/* # 1.75 GiB (21694 objects)
|
||||
# git push --mirror $ARCHIVE_REPO || true # fails to push refs/pull/* (deny updating a hidden ref) for pull requests
|
||||
# we fail and continue - more reading: https://stackoverflow.com/a/34266401/639708 and https://blog.plataformatec.com.br/2013/05/how-to-properly-mirror-a-git-repository/
|
||||
fi
|
||||
|
||||
# REWRITE master and tags
|
||||
if [ ! -d $SRC_CLONE ]; then
|
||||
echo "Cloning $SRC..."
|
||||
GIT_LFS_SKIP_SMUDGE=1 git clone $SRC $SRC_CLONE
|
||||
|
||||
cd $SRC_CLONE
|
||||
|
||||
echo "Checking out old history..."
|
||||
|
||||
git checkout tags/v0.7.1 > /dev/null 2>&1
|
||||
# checkout as main, since we need master ref later
|
||||
git checkout -b main
|
||||
|
||||
echo "Creating setup commits..."
|
||||
|
||||
# rm these so we don't get conflicts later
|
||||
git rm -r cereal opendbc panda selfdrive/ui/ui > /dev/null
|
||||
git commit -m "removed conflicting files" > /dev/null
|
||||
|
||||
# skip-smudge to get rid of some lfs errors that it can't find the reference of some lfs files
|
||||
# we don't care about fetching/pushing lfs right now
|
||||
git lfs install --skip-smudge --local
|
||||
|
||||
# squash initial setup commits
|
||||
git cherry-pick -n -X theirs 6c33a5c..59b3d06 > /dev/null
|
||||
git commit -m "switching to master" > /dev/null
|
||||
|
||||
# squash the two commits
|
||||
git reset --soft HEAD~2
|
||||
git commit -m "switching to master" -m "$(git log --reverse --format=%B 6c33a5c..59b3d06)" -m "removed conflicting files" > /dev/null
|
||||
|
||||
# get commits we want to cherry-pick
|
||||
# will start with the next commit after #59b3d06 tools is local now
|
||||
COMMITS=$(git rev-list --reverse 59b3d06..master)
|
||||
|
||||
# we need this for logging
|
||||
TOTAL_COMMITS=$(echo $COMMITS | wc -w | xargs)
|
||||
CURRENT_COMMIT_NUMBER=0
|
||||
|
||||
# empty this file
|
||||
> commit-map.txt
|
||||
|
||||
echo "Rewriting master commits..."
|
||||
|
||||
for COMMIT in $COMMITS; do
|
||||
CURRENT_COMMIT_NUMBER=$((CURRENT_COMMIT_NUMBER + 1))
|
||||
# echo -ne "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Cherry-picking commit: $COMMIT"\\r
|
||||
echo "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Cherry-picking commit: $COMMIT"
|
||||
|
||||
# set environment variables to preserve author/committer and dates
|
||||
export GIT_AUTHOR_NAME=$(git show -s --format='%an' $COMMIT)
|
||||
export GIT_AUTHOR_EMAIL=$(git show -s --format='%ae' $COMMIT)
|
||||
export GIT_COMMITTER_NAME=$(git show -s --format='%cn' $COMMIT)
|
||||
export GIT_COMMITTER_EMAIL=$(git show -s --format='%ce' $COMMIT)
|
||||
export GIT_AUTHOR_DATE=$(git show -s --format='%ad' $COMMIT)
|
||||
export GIT_COMMITTER_DATE=$(git show -s --format='%cd' $COMMIT)
|
||||
|
||||
# cherry-pick the commit
|
||||
if ! GIT_OUTPUT=$(git cherry-pick -m 1 -X theirs $COMMIT 2>&1); then
|
||||
# check if the failure is because of an empty commit
|
||||
if [[ "$GIT_OUTPUT" == *"The previous cherry-pick is now empty"* ]]; then
|
||||
echo "Empty commit detected. Skipping commit $COMMIT"
|
||||
git cherry-pick --skip
|
||||
# log it was empty to the mapping file
|
||||
echo "$COMMIT EMPTY" >> commit-map.txt
|
||||
else
|
||||
# handle other errors or conflicts
|
||||
echo "Cherry-pick failed. Handling error..."
|
||||
echo "$GIT_OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# capture the new commit hash
|
||||
NEW_COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
# save the old and new commit hashes to the mapping file
|
||||
echo "$COMMIT $NEW_COMMIT" >> commit-map.txt
|
||||
|
||||
# append the old commit ID to the commit message
|
||||
git commit --amend -m "$(git log -1 --pretty=%B)" -m "Former-commit-id: $COMMIT" > /dev/null
|
||||
fi
|
||||
|
||||
# prune every 3000 commits to avoid gc errors
|
||||
if [ $((CURRENT_COMMIT_NUMBER % 3000)) -eq 0 ]; then
|
||||
echo "Pruning repo..."
|
||||
git gc
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Rewriting tags..."
|
||||
|
||||
# remove all old tags
|
||||
git tag -l | xargs git tag -d
|
||||
|
||||
# read each line from the tag-commit-map.txt
|
||||
while IFS=' ' read -r TAG OLD_COMMIT; do
|
||||
# search for the new commit in commit-map.txt corresponding to the old commit
|
||||
NEW_COMMIT=$(grep "^$OLD_COMMIT " "commit-map.txt" | awk '{print $2}')
|
||||
|
||||
# check if this is a rebased commit
|
||||
if [ -z "$NEW_COMMIT" ]; then
|
||||
# if not, then just use old commit hash
|
||||
NEW_COMMIT=$OLD_COMMIT
|
||||
fi
|
||||
|
||||
echo "Rewriting tag $TAG from commit $NEW_COMMIT"
|
||||
git tag -f "$TAG" "$NEW_COMMIT"
|
||||
done < "$DIR/tag-commit-map.txt"
|
||||
|
||||
# uninstall lfs since we don't want to touch (push to) lfs right now
|
||||
# git push will also push lfs, if we don't uninstall (--local so just for this repo)
|
||||
git lfs uninstall --local
|
||||
|
||||
# force push new master
|
||||
git push --force origin main:master
|
||||
|
||||
# force push new tags
|
||||
git push --force --tags
|
||||
fi
|
||||
|
||||
# REWRITE branches based on master
|
||||
if [ ! -f "$SRC_CLONE/rewrite-branches-done" ]; then
|
||||
cd $SRC_CLONE
|
||||
> rewrite-branches-done
|
||||
|
||||
# empty file
|
||||
> $BRANCH_DIFF_LOG
|
||||
|
||||
echo "Rewriting branches based on master..."
|
||||
|
||||
# will store raw diffs here, if exist
|
||||
mkdir -p differences
|
||||
|
||||
# get a list of all branches except master and REWRITE_IGNORE_BRANCHES
|
||||
BRANCHES=$(git branch -r | grep -v ' -> ' | sed 's/.*origin\///' | grep -v '^master$' | grep -v -f <(echo "${REWRITE_IGNORE_BRANCHES[*]}" | tr ' ' '\n'))
|
||||
|
||||
for BRANCH in $BRANCHES; do
|
||||
# check if the branch is based on master history
|
||||
MERGE_BASE=$(git merge-base master origin/$BRANCH) || true
|
||||
if [ -n "$MERGE_BASE" ]; then
|
||||
echo "Rewriting branch: $BRANCH"
|
||||
|
||||
# create a new branch based on the new master
|
||||
NEW_MERGE_BASE=$(grep "^$MERGE_BASE " "commit-map.txt" | awk '{print $2}')
|
||||
if [ -z "$NEW_MERGE_BASE" ]; then
|
||||
echo "Error: could not find new merge base for branch $BRANCH" >> $BRANCH_DIFF_LOG
|
||||
continue
|
||||
fi
|
||||
git checkout -b ${BRANCH}_new $NEW_MERGE_BASE
|
||||
|
||||
# get the range of commits unique to this branch
|
||||
COMMITS=$(git rev-list --reverse $MERGE_BASE..origin/${BRANCH})
|
||||
|
||||
HAS_ERROR=0
|
||||
|
||||
# simple delimiter
|
||||
echo "BRANCH ${BRANCH}" >> commit-map.txt
|
||||
|
||||
for COMMIT in $COMMITS; do
|
||||
# set environment variables to preserve author/committer and dates
|
||||
export GIT_AUTHOR_NAME=$(git show -s --format='%an' $COMMIT)
|
||||
export GIT_AUTHOR_EMAIL=$(git show -s --format='%ae' $COMMIT)
|
||||
export GIT_COMMITTER_NAME=$(git show -s --format='%cn' $COMMIT)
|
||||
export GIT_COMMITTER_EMAIL=$(git show -s --format='%ce' $COMMIT)
|
||||
export GIT_AUTHOR_DATE=$(git show -s --format='%ad' $COMMIT)
|
||||
export GIT_COMMITTER_DATE=$(git show -s --format='%cd' $COMMIT)
|
||||
|
||||
# cherry-pick the commit
|
||||
if ! GIT_OUTPUT=$(git cherry-pick -m 1 -X theirs $COMMIT 2>&1); then
|
||||
# check if the failure is because of an empty commit
|
||||
if [[ "$GIT_OUTPUT" == *"The previous cherry-pick is now empty"* ]]; then
|
||||
echo "Empty commit detected. Skipping commit $COMMIT"
|
||||
git cherry-pick --skip
|
||||
# log it was empty to the mapping file
|
||||
echo "$COMMIT EMPTY" >> commit-map.txt
|
||||
else
|
||||
# handle other errors or conflicts
|
||||
echo "Cherry-pick of ${BRANCH} branch failed. Removing branch upstream..." >> $BRANCH_DIFF_LOG
|
||||
echo "$GIT_OUTPUT" > "$LOGS_DIR/branch-${BRANCH}"
|
||||
git cherry-pick --abort
|
||||
git push --delete origin ${BRANCH}
|
||||
HAS_ERROR=1
|
||||
break
|
||||
fi
|
||||
else
|
||||
# capture the new commit hash
|
||||
NEW_COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
# save the old and new commit hashes to the mapping file
|
||||
echo "$COMMIT $NEW_COMMIT" >> commit-map.txt
|
||||
|
||||
# append the old commit ID to the commit message
|
||||
git commit --amend -m "$(git log -1 --pretty=%B)" -m "Former-commit-id: $COMMIT" > /dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# force push the new branch
|
||||
if [ $HAS_ERROR -eq 0 ]; then
|
||||
# git lfs goes haywire here, so we need to install and uninstall
|
||||
# git lfs install --skip-smudge --local
|
||||
git lfs uninstall --local > /dev/null
|
||||
git push -f origin ${BRANCH}_new:${BRANCH}
|
||||
fi
|
||||
|
||||
# clean up local branch
|
||||
git checkout master > /dev/null
|
||||
git branch -D ${BRANCH}_new > /dev/null
|
||||
else
|
||||
echo "Deleting branch $BRANCH as it's not based on master history" >> $BRANCH_DIFF_LOG
|
||||
git push --delete origin ${BRANCH}
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# VALIDATE cherry-pick
|
||||
if [ ! -f "$SRC_CLONE/validation-done" ]; then
|
||||
cd $SRC_CLONE
|
||||
> validation-done
|
||||
|
||||
TOTAL_COMMITS=$(grep -cve '^\s*$' commit-map.txt)
|
||||
CURRENT_COMMIT_NUMBER=0
|
||||
COUNT_SAME=0
|
||||
COUNT_DIFF=0
|
||||
|
||||
# empty file
|
||||
> $COMMIT_DIFF_LOG
|
||||
|
||||
echo "Validating commits..."
|
||||
|
||||
# will store raw diffs here, if exist
|
||||
mkdir -p differences
|
||||
|
||||
# read each line from commit-map.txt
|
||||
while IFS=' ' read -r OLD_COMMIT NEW_COMMIT; do
|
||||
if [ "$NEW_COMMIT" == "EMPTY" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$OLD_COMMIT" == "BRANCH" ]; then
|
||||
echo "Branch ${NEW_COMMIT} below:" >> $COMMIT_DIFF_LOG
|
||||
continue
|
||||
fi
|
||||
CURRENT_COMMIT_NUMBER=$((CURRENT_COMMIT_NUMBER + 1))
|
||||
# retrieve short hashes and dates for the old and new commits
|
||||
OLD_COMMIT_SHORT=$(git rev-parse --short $OLD_COMMIT)
|
||||
NEW_COMMIT_SHORT=$(git rev-parse --short $NEW_COMMIT)
|
||||
OLD_DATE=$(git show -s --format='%cd' $OLD_COMMIT)
|
||||
NEW_DATE=$(git show -s --format='%cd' $NEW_COMMIT)
|
||||
|
||||
# echo -ne "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Comparing old commit $OLD_COMMIT_SHORT ($OLD_DATE) with new commit $NEW_COMMIT_SHORT ($NEW_DATE)"\\r
|
||||
echo "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Comparing old commit $OLD_COMMIT_SHORT ($OLD_DATE) with new commit $NEW_COMMIT_SHORT ($NEW_DATE)"
|
||||
|
||||
# generate lists of files and their hashes for the old and new commits, excluding ignored files
|
||||
OLD_FILES=$(git ls-tree -r $OLD_COMMIT | grep -vE "$(IFS='|'; echo "${VALIDATE_IGNORE_FILES[*]}")")
|
||||
NEW_FILES=$(git ls-tree -r $NEW_COMMIT | grep -vE "$(IFS='|'; echo "${VALIDATE_IGNORE_FILES[*]}")")
|
||||
|
||||
# Compare the diffs
|
||||
if diff <(echo "$OLD_FILES") <(echo "$NEW_FILES") > /dev/null; then
|
||||
# echo "Old commit $OLD_COMMIT_SHORT and new commit $NEW_COMMIT_SHORT are equivalent."
|
||||
COUNT_SAME=$((COUNT_SAME + 1))
|
||||
else
|
||||
echo "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Difference found between old commit $OLD_COMMIT_SHORT and new commit $NEW_COMMIT_SHORT" >> $COMMIT_DIFF_LOG
|
||||
COUNT_DIFF=$((COUNT_DIFF + 1))
|
||||
set +e
|
||||
diff -u <(echo "$OLD_FILES") <(echo "$NEW_FILES") > "$LOGS_DIR/commit-$CURRENT_COMMIT_NUMBER-$OLD_COMMIT_SHORT-$NEW_COMMIT_SHORT"
|
||||
set -e
|
||||
fi
|
||||
done < "commit-map.txt"
|
||||
|
||||
echo "Summary:" >> $COMMIT_DIFF_LOG
|
||||
echo "Equivalent commits: $COUNT_SAME" >> $COMMIT_DIFF_LOG
|
||||
echo "Different commits: $COUNT_DIFF" >> $COMMIT_DIFF_LOG
|
||||
fi
|
||||
|
||||
if [ ! -d $OUT ]; then
|
||||
cp -r $SRC $OUT
|
||||
|
||||
cd $OUT
|
||||
|
||||
# remove all non-master branches
|
||||
# git branch | grep -v "^ master$" | grep -v "\*" | xargs git branch -D
|
||||
|
||||
# echo "cleaning up refs"
|
||||
# delete pull request refs since we can't alter them anyway (https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally#error-failed-to-push-some-refs)
|
||||
# git for-each-ref --format='%(refname)' | grep '^refs/pull/' | xargs -I {} git update-ref -d {}
|
||||
|
||||
echo "importing new lfs files"
|
||||
# import "almost" everything to lfs
|
||||
BRANCHES=$(git for-each-ref --format='%(refname)' refs/heads/ | sed 's%refs/heads/%%g' | grep -v -f <(echo "${REWRITE_IGNORE_BRANCHES[*]}" | tr ' ' '\n') | tr '\n' ' ')
|
||||
git lfs migrate import --include="*.dlc,*.onnx,*.svg,*.png,*.gif,*.ttf,*.wav,selfdrive/car/tests/test_models_segs.txt,system/hardware/tici/updater,selfdrive/ui/qt/spinner_larch64,selfdrive/ui/qt/text_larch64,third_party/**/*.a,third_party/**/*.so,third_party/**/*.so.*,third_party/**/*.dylib,third_party/acados/*/t_renderer,third_party/qt5/larch64/bin/lrelease,third_party/qt5/larch64/bin/lupdate,third_party/catch2/include/catch2/catch.hpp,*.apk,*.apkpatch,*.jar,*.pdf,*.jpg,*.mp3,*.thneed,*.tar.gz,*.npy,*.csv,*.a,*.so*,*.dylib,*.o,*.b64,selfdrive/hardware/tici/updater,selfdrive/boardd/tests/test_boardd,selfdrive/ui/qt/spinner_aarch64,installer/updater/updater,selfdrive/debug/profiling/simpleperf/**/*,selfdrive/hardware/eon/updater,selfdrive/ui/qt/text_aarch64,selfdrive/debug/profiling/pyflame/**/*,installer/installers/installer_openpilot,installer/installers/installer_dashcam,selfdrive/ui/text/text,selfdrive/ui/android/text/text,selfdrive/ui/spinner/spinner,selfdrive/visiond/visiond,selfdrive/loggerd/loggerd,selfdrive/sensord/sensord,selfdrive/sensord/gpsd,selfdrive/ui/android/spinner/spinner,selfdrive/ui/qt/spinner,selfdrive/ui/qt/text,_stringdefs.py,dfu-util-aarch64-linux,dfu-util-aarch64,dfu-util-x86_64-linux,dfu-util-x86_64,stb_image.h,clpeak3,clwaste,apk/**/*,external/**/*,phonelibs/**/*,third_party/boringssl/**/*,flask/**/*,panda/**/*,board/**/*,messaging/**/*,opendbc/**/*,tools/cabana/chartswidget.cc,third_party/nanovg/**/*,selfdrive/controls/lib/lateral_mpc/lib_mpc_export/**/*,selfdrive/ui/paint.cc,werkzeug/**/*,pyextra/**/*,third_party/android_hardware_libhardware/**/*,selfdrive/controls/lib/lead_mpc_lib/lib_mpc_export/**/*,selfdrive/locationd/laikad.py,selfdrive/locationd/test/test_laikad.py,tools/gpstest/test_laikad.py,selfdrive/locationd/laikad_helpers.py,tools/nui/**/*,jsonrpc/**/*,selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/**/*,selfdrive/controls/lib/lateral_mpc/mpc_export/**/*,selfdrive/camerad/cameras/camera_qcom.cc,selfdrive/manager.py,selfdrive/modeld/models/driving.cc,third_party/curl/**/*,selfdrive/modeld/thneed/debug/**/*,selfdrive/modeld/thneed/include/**/*,third_party/openmax/**/*,selfdrive/controls/lib/longitudinal_mpc/mpc_export/**/*,selfdrive/controls/lib/longitudinal_mpc_model/lib_mpc_export/**/*,Pipfile,Pipfile.lock,gunicorn/**/*,*.qm,jinja2/**/*,click/**/*,dbcs/**/*,websocket/**/*" $BRANCHES
|
||||
|
||||
echo "reflog and gc"
|
||||
# this is needed after lfs import
|
||||
git reflog expire --expire=now --all
|
||||
git gc --prune=now --aggressive
|
||||
|
||||
# check the git-filter-repo analysis again - can be found in the repo root/filter-repo/analysis
|
||||
echo "Analyzing with git-filter-repo..."
|
||||
/tmp/git-filter-repo --force --analyze
|
||||
|
||||
echo "New size is $(du -sh .)"
|
||||
fi
|
||||
|
||||
cd $OUT
|
||||
|
||||
# fetch all lfs files from https://github.com/commaai/openpilot.git
|
||||
# some lfs files are missing on gitlab, but they can be found on github
|
||||
git config lfs.url https://github.com/commaai/openpilot.git/info/lfs
|
||||
git config lfs.pushurl ssh://git@github.com/commaai/openpilot.git
|
||||
git lfs fetch --all || true
|
||||
|
||||
# also fetch all lfs files from https://gitlab.com/commaai/openpilot-lfs.git
|
||||
git config lfs.url https://gitlab.com/commaai/openpilot-lfs.git/info/lfs
|
||||
git config lfs.pushurl ssh://git@gitlab.com/commaai/openpilot-lfs.git
|
||||
git lfs fetch --all || true
|
||||
|
||||
# final push - will also push lfs
|
||||
# TODO: switch to git@github.com:commaai/openpilot.git when ready
|
||||
# git push --mirror git@github.com:commaai/openpilot-tiny.git
|
||||
# using this instead to ignore refs/pull/* - since this is also what --mirror does - https://blog.plataformatec.com.br/2013/05/how-to-properly-mirror-a-git-repository/
|
||||
git push --prune git@github.com:commaai/openpilot-tiny.git +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd $DIR
|
||||
|
||||
git clone --bare https://github.com/commaai/openpilot
|
||||
cp -r openpilot.git openpilot_backup
|
||||
cd openpilot.git
|
||||
|
||||
# backup old repo
|
||||
git push git@github.com:maxime-desroches/openpilot_archive.git +refs/heads/master:refs/heads/master
|
||||
git push git@github.com:maxime-desroches/openpilot_archive.git +refs/heads/*:refs/heads/*
|
||||
git push git@github.com:maxime-desroches/openpilot_archive.git +refs/tags/*:refs/tags/*
|
||||
git push --mirror git@github.com:maxime-desroches/openpilot_archive.git
|
||||
|
||||
# ignore all release branches
|
||||
git for-each-ref --format='delete %(refname)' | grep 'dashcam3\|devel\|master-ci\|nightly\|release2\|release3\|release3-staging' | git update-ref --stdin
|
||||
|
||||
# re-tag old releases on master
|
||||
declare -A TAGS=( ["f8cb04e4a8b032b72a909f68b808a50936184bee"]="v0.9.7" ["0b4d08fab8e35a264bc7383e878538f8083c33e5"]="v0.9.6" ["3b1e9017c560499786d8a0e46aaaeea65037acac"]="v0.9.5" ["fa310d9e2542cf497d92f007baec8fd751ffa99c"]="v0.9.4" ["8704c1ff952b5c85a44f50143bbd1a4f7b4887e2"]="v0.9.3" ["c7d3b28b93faa6c955fb24bc64031512ee985ee9"]="v0.9.2" ["89f68bf0cbf53a81b0553d3816fdbe522f941fa1"]="v0.9.1" ["58b84fb401a804967aa0dd5ee66fafa90194fd30"]="v0.9.0" ["f41dc62a12cc0f3cb8c5453c0caa0ba21e1bd01e"]="v0.8.16" ["5a7c2f90361e72e9c35e88abd2e11acdc4aba354"]="v0.8.15" ["71901c94dbbaa2f9f156a80c14cc7ea65219fc7c"]="v0.8.14" ["95da47079510afc91665263619e5939126da637c"]="v0.8.13" ["472177e2a8a1d002e56f9096326fd2dff62e54f9"]="v0.8.12" ["08078acbd0b4f7da469c7dff6159000e358974a9"]="v0.8.11" ["687925c775c375495f9827946138a724bde00b9d"]="v0.8.10" ["204e5a090735a059d69c29145a4cee49450da07e"]="v0.8.9" ["4be956f8861ecbb521ef9503a3c87b07c9d36721"]="v0.8.8" ["589f82c76627d634761a31a34b2488403556eb0b"]="v0.8.7" ["507cfc8910f74ddb8810039d68b880b426ff9ff9"]="v0.8.6" ["d47b00b45a866bef088f51d1ff31de5885ab04e9"]="v0.8.5" ["553e7d1cce314e7eb0587186b1764c3ff43bed62"]="v0.8.4" ["9896438d1511602a1ff87f7c4eb3c7172b30104a"]="v0.8.3" ["280192ed1443f112463417c2d815ea8ee2762fbd"]="v0.8.2" ["8039361567e4659eae2a084e6f39f34acadf4cac"]="v0.8.1" ["d56e04c0d960c8d3d4ab88b578dc508a2b4e07dc"]="v0.8" ["3d456e5d0fbf0c9887d0499dee812f2b029edf6d"]="v0.7.10" ["81763a18b5d0e379b749e090ecce36a91fca7c43"]="v0.7.9" ["9bc0b350fd273bbb2deb3dcaef0312944e4f6cfd"]="v0.7.8" ["ede5b632b58c55e4ff003f948efae07fe03c2280"]="v0.7.7" ["775acd11ba2e0a8c2f5a5655338718d796491b36"]="v0.7.6.1" ["302417b4cf0dcf00d45e4995b5410e543ad121d1"]="v0.7.5" ["12ff088b42221dd17d9d97decb1fc61a7cb0a861"]="v0.7.4" ["9563f7730252451fdcba9bc3d9fe36dab9c86a26"]="v0.7.3" ["8321cf283abbc2ca3fda7e0c7a069a77a492fe0c"]="v0.7.2" ["1e1de64a1e59476b7b3d3558b92149246d5c3292"]="v0.7.1" ["a2ae18d1dbd1e59c38ce22fa25ddffbd1d3084e3"]="v0.7" ["d4eb5a6eafdd4803d09e6f3963918216cca5a81f"]="v0.6.6" ["70d17cd69b80e7627dcad8fd5b6438f2309ac307"]="v0.6.5" ["58f376002e0c654fbc2de127765fa297cf694a33"]="v0.6.4" ["d5f9caa82d80cdcc7f1b7748f2cf3ccbf94f82a3"]="v0.6.3" ["095ef5f9f60fca1b269aabcc3cfd322b17b9e674"]="v0.6.2" ["cf5c4aeacb1703d0ffd35bdb5297d3494fee9a22"]="v0.6.1" ["60a20537c5f3fcc7f11946d81aebc8f90c08c117"]="v0.6" ["dd34ccfe288ebda8e2568cf550994ae890379f45"]="v0.5.13" ["3f9059fea886f1fa3b0c19a62a981d891dcc84eb"]="v0.5.12" ["2f92d577f995ff6ae1945ef6b89df3cb69b92999"]="v0.5.11" ["5a9d89ed42ddcd209d001a10d7eb828ef0e6d9de"]="v0.5.10" ["0207a970400ee28d3e366f2e8f5c551281accf02"]="v0.5.9" ["b967da5fc1f7a07e3561db072dd714d325e857b0"]="v0.5.8" ["210db686bb89f8696aa040e6e16de65424b808c9"]="v0.5.7" ["860a48765d1016ba226fb2c64aea35a45fe40e4a"]="v0.5.6" ["8f3539a27b28851153454eb737da9624cccaed2d"]="v0.5.5" ["a422246dc30bce11e970514f13f7c110f4470cc3"]="v0.5.4" ["285c52eb693265a0a530543e9ca0aeb593a2a55e"]="v0.5.3" ["0129a8a4ff8da5314e8e4d4d3336e89667ff6d54"]="v0.5.2" ["6f3d10a4c475c4c4509f0b370805419acd13912d"]="v0.5.1" ["de33bc46452b1046387ee2b3a03191b2c71135fb"]="v0.5" ["ae5cb7a0dab8b1bed9d52292f9b4e8e66a0f8ec9"]="v0.4.7" ["c6df34f55ba8c5a911b60d3f9eb20e3fa45f68c1"]="v0.4.6" ["37285038d3f91fa1b49159c4a35a8383168e644f"]="v0.4.5" ["9a9ff839a9b70cb2601d7696af743f5652395389"]="v0.4.4" ["28c0797d30175043bbfa31307b63aab4197cf996"]="v0.4.2" ["4474b9b3718653aeb0aee26422caefb90460cc0e"]="v0.4.1" ["da52d065a4c4f52d6017a537f3a80326f5af8bdc"]="v0.4.0.2" ["9d3963559ae7b15193057937ff3e72481899f40d"]="v0.3.5" ["1b8c44b5067525a5d266b6e99799d8097da76a29"]="v0.3.4" ["5cf91d0496688fed4f2a6c7021349b1fc0e057a2"]="v0.3.3" ["7fe46f1e1df5dec08a940451ba0feefd5c039165"]="v0.3.2" ["41e3a0f699f5c39cb61a15c0eb7a4aa816d47c24"]="v0.3.1" ["c5d8aec28b5230d34ae4b677c2091cc3dec7e3e8"]="v0.3.0" ["693bcb0f83478f2651db6bac9be5ca5ad60d03f3"]="v0.2.9" ["95a349abcc050712c50d4d85a1c8a804eee7f6c2"]="v0.2.8" ["c6ba5dc5391d3ca6cda479bf1923b88ce45509a0"]="v0.2.7" ["6c3afeec0fb439070b2912978b8dbb659033b1d9"]="v0.2.6" ["29c58b45882ac79595356caf98580c1d2a626011"]="v0.2.5" ["ecc565aa3fdc4c7e719aadc000e1fdc4d80d4fe0"]="v0.2.4" ["adaa4ed350acda4067fc0b455ad15b54cdf4c768"]="v0.2.3" ["a64b9aa9b8cb5863c917b6926516291a63c02fe5"]="v0.2.2" ["17d9becd3c673091b22f09aa02559a9ed9230f50"]="v0.2.1" ["449b482cc3236ccf31829830b4f6a44b2dcc06c2"]="v0.2" ["e94a30bec07e719c5a7b037ca1f4db8312702cce"]="v0.1" )
|
||||
for tag in "${!TAGS[@]}"; do git tag -f "${TAGS[$tag]}" "$tag" ; done
|
||||
|
||||
# get master root commit
|
||||
ROOT_COMMIT=$(git rev-list --max-parents=0 HEAD | tail -n 1)
|
||||
|
||||
# link master and devel
|
||||
git replace --graft $ROOT_COMMIT v0.7.1
|
||||
git-filter-repo --prune-empty never --force --commit-callback 'h=commit.original_id.decode("utf-8");m=commit.message.decode("utf-8");commit.message=str.encode(m + "\n" + "old-commit-hash: " + h)'
|
||||
|
||||
# delete replace refs
|
||||
git for-each-ref --format='delete %(refname)' refs/replace | git update-ref --stdin
|
||||
|
||||
# validate
|
||||
tail -n +2 "filter-repo/commit-map" | tr ' ' '\n' | xargs -P $(nproc) -n 2 bash -c 'diff <(cd ../openpilot_backup && git ls-tree -r $0 | sha1sum) <(git ls-tree -r $1 | sha1sum) || exit 255'
|
||||
|
||||
# cleanup
|
||||
git reflog expire --expire=now --all
|
||||
git gc --prune=now --aggressive
|
||||
|
||||
# get all lfs files
|
||||
git config lfs.url https://github.com/commaai/openpilot.git/info/lfs
|
||||
git lfs fetch --all
|
||||
git config lfs.url https://gitlab.com/commaai/openpilot-lfs.git/info/lfs
|
||||
git lfs fetch --all
|
||||
|
||||
# add new files to lfs
|
||||
git lfs migrate import --everything --include="*.dlc,*.onnx,*.svg,*.png,*.gif,*.ttf,*.wav,selfdrive/car/tests/test_models_segs.txt,system/hardware/tici/updater,selfdrive/ui/qt/spinner_larch64,selfdrive/ui/qt/text_larch64,third_party/**/*.a,third_party/**/*.so,third_party/**/*.so.*,third_party/**/*.dylib,third_party/acados/*/t_renderer,third_party/qt5/larch64/bin/lrelease,third_party/qt5/larch64/bin/lupdate,third_party/catch2/include/catch2/catch.hpp,*.apk,*.apkpatch,*.jar,*.pdf,*.jpg,*.mp3,*.thneed,*.tar.gz,*.npy,*.csv,*.a,*.so*,*.dylib,*.o,*.b64,selfdrive/hardware/tici/updater,selfdrive/boardd/tests/test_boardd,selfdrive/ui/qt/spinner_aarch64,installer/updater/updater,selfdrive/debug/profiling/simpleperf/**/*,selfdrive/hardware/eon/updater,selfdrive/ui/qt/text_aarch64,selfdrive/debug/profiling/pyflame/**/*,installer/installers/installer_openpilot,installer/installers/installer_dashcam,selfdrive/ui/text/text,selfdrive/ui/android/text/text,selfdrive/ui/spinner/spinner,selfdrive/visiond/visiond,selfdrive/loggerd/loggerd,selfdrive/sensord/sensord,selfdrive/sensord/gpsd,selfdrive/ui/android/spinner/spinner,selfdrive/ui/qt/spinner,selfdrive/ui/qt/text,_stringdefs.py,dfu-util-aarch64-linux,dfu-util-aarch64,dfu-util-x86_64-linux,dfu-util-x86_64,stb_image.h,clpeak3,clwaste,apk/**/*,external/**/*,phonelibs/**/*,third_party/boringssl/**/*,flask/**/*,panda/**/*,board/**/*,messaging/**/*,opendbc/**/*,tools/cabana/chartswidget.cc,third_party/nanovg/**/*,selfdrive/controls/lib/lateral_mpc/lib_mpc_export/**/*,selfdrive/ui/paint.cc,werkzeug/**/*,pyextra/**/*,third_party/android_hardware_libhardware/**/*,selfdrive/controls/lib/lead_mpc_lib/lib_mpc_export/**/*,selfdrive/locationd/laikad.py,selfdrive/locationd/test/test_laikad.py,tools/gpstest/test_laikad.py,selfdrive/locationd/laikad_helpers.py,tools/nui/**/*,jsonrpc/**/*,selfdrive/controls/lib/longitudinal_mpc/lib_mpc_export/**/*,selfdrive/controls/lib/lateral_mpc/mpc_export/**/*,selfdrive/camerad/cameras/camera_qcom.cc,selfdrive/manager.py,selfdrive/modeld/models/driving.cc,third_party/curl/**/*,selfdrive/modeld/thneed/debug/**/*,selfdrive/modeld/thneed/include/**/*,third_party/openmax/**/*,selfdrive/controls/lib/longitudinal_mpc/mpc_export/**/*,selfdrive/controls/lib/longitudinal_mpc_model/lib_mpc_export/**/*,Pipfile,Pipfile.lock,poetry.lock,gunicorn/**/*,*.qm,jinja2/**/*,click/**/*,dbcs/**/*,websocket/**/*"
|
||||
|
||||
# set new lfs endpoint
|
||||
git config lfs.url https://gitlab.com/commaai/openpilot_rewrite_lfs.git/info/lfs
|
||||
git config lfs.pushurl ssh://git@gitlab.com/commaai/openpilot_rewrite_lfs.git
|
||||
|
||||
# push all branch+tag (scary stuff...)
|
||||
git push -f --set-upstream git@github.com:maxime-desroches/tinypilot.git +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*
|
||||
@@ -0,0 +1,82 @@
|
||||
v0.1 e94a30bec07e719c5a7b037ca1f4db8312702cce
|
||||
v0.2 449b482cc3236ccf31829830b4f6a44b2dcc06c2
|
||||
v0.2.1 17d9becd3c673091b22f09aa02559a9ed9230f50
|
||||
v0.2.2 a64b9aa9b8cb5863c917b6926516291a63c02fe5
|
||||
v0.2.3 adaa4ed350acda4067fc0b455ad15b54cdf4c768
|
||||
v0.2.4 ecc565aa3fdc4c7e719aadc000e1fdc4d80d4fe0
|
||||
v0.2.5 29c58b45882ac79595356caf98580c1d2a626011
|
||||
v0.2.6 6c3afeec0fb439070b2912978b8dbb659033b1d9
|
||||
v0.2.7 c6ba5dc5391d3ca6cda479bf1923b88ce45509a0
|
||||
v0.2.8 95a349abcc050712c50d4d85a1c8a804eee7f6c2
|
||||
v0.2.9 693bcb0f83478f2651db6bac9be5ca5ad60d03f3
|
||||
v0.3.0 c5d8aec28b5230d34ae4b677c2091cc3dec7e3e8
|
||||
v0.3.1 41e3a0f699f5c39cb61a15c0eb7a4aa816d47c24
|
||||
v0.3.2 7fe46f1e1df5dec08a940451ba0feefd5c039165
|
||||
v0.3.3 5cf91d0496688fed4f2a6c7021349b1fc0e057a2
|
||||
v0.3.4 1b8c44b5067525a5d266b6e99799d8097da76a29
|
||||
v0.3.5 b111277f464cf66fa34b67819a83ea683e0f64df
|
||||
v0.4.0.2 da52d065a4c4f52d6017a537f3a80326f5af8bdc
|
||||
v0.4.1 4474b9b3718653aeb0aee26422caefb90460cc0e
|
||||
v0.4.2 28c0797d30175043bbfa31307b63aab4197cf996
|
||||
v0.4.4 9a9ff839a9b70cb2601d7696af743f5652395389
|
||||
v0.4.5 37285038d3f91fa1b49159c4a35a8383168e644f
|
||||
v0.4.6 c6df34f55ba8c5a911b60d3f9eb20e3fa45f68c1
|
||||
v0.4.7 ae5cb7a0dab8b1bed9d52292f9b4e8e66a0f8ec9
|
||||
v0.5 de33bc46452b1046387ee2b3a03191b2c71135fb
|
||||
v0.5.1 8f22f52235c48eada586795ac57edb22688e4d08
|
||||
v0.5.2 0129a8a4ff8da5314e8e4d4d3336e89667ff6d54
|
||||
v0.5.3 285c52eb693265a0a530543e9ca0aeb593a2a55e
|
||||
v0.5.4 a422246dc30bce11e970514f13f7c110f4470cc3
|
||||
v0.5.5 8f3539a27b28851153454eb737da9624cccaed2d
|
||||
v0.5.6 860a48765d1016ba226fb2c64aea35a45fe40e4a
|
||||
v0.5.7 9ce3045f139ee29bf0eea5ec59dfe7df9c3d2c51
|
||||
v0.5.8 2cee2e05ba0f3824fdbb8b957958800fa99071a1
|
||||
v0.5.9 ad145da3bcded0fe75306df02061d07a633963c3
|
||||
v0.5.10 ff4c1557d8358f158f4358788ff18ef93d2470ef
|
||||
v0.5.11 d1866845df423c6855e2b365ff230cf7d89a420b
|
||||
v0.5.12 f6e8ef27546e9a406724841e75f8df71cc4c2c97
|
||||
v0.5.13 dd34ccfe288ebda8e2568cf550994ae890379f45
|
||||
v0.6 60a20537c5f3fcc7f11946d81aebc8f90c08c117
|
||||
v0.6.1 cf5c4aeacb1703d0ffd35bdb5297d3494fee9a22
|
||||
v0.6.2 095ef5f9f60fca1b269aabcc3cfd322b17b9e674
|
||||
v0.6.3 d5f9caa82d80cdcc7f1b7748f2cf3ccbf94f82a3
|
||||
v0.6.4 58f376002e0c654fbc2de127765fa297cf694a33
|
||||
v0.6.5 70d17cd69b80e7627dcad8fd5b6438f2309ac307
|
||||
v0.6.6 d4eb5a6eafdd4803d09e6f3963918216cca5a81f
|
||||
v0.7 a2ae18d1dbd1e59c38ce22fa25ddffbd1d3084e3
|
||||
v0.7.1 1e1de64a1e59476b7b3d3558b92149246d5c3292
|
||||
v0.7.2 59bd58c940673b4c4a6a86f299022614bcf42b22
|
||||
v0.7.3 d7acd8b68f8131e0e714400cf124a3e228638643
|
||||
v0.7.4 e93649882c5e914eec4a8b8b593dc0587e497033
|
||||
v0.7.5 8abc0afe464626a461d2c7e192c912eeebeccc65
|
||||
v0.7.6 69aacd9d179fe6dd3110253a099c38b34cff7899
|
||||
v0.7.7 f1caed7299cdba5e45635d8377da6cc1e5fd7072
|
||||
v0.7.8 2189fe8741b635d8394d55dee28959425cfd5ad0
|
||||
v0.7.9 86dc54b836a973f132ed26db9f5a60b29f9b25b2
|
||||
v0.7.10 47a42ff432db8a2494e922ca5e767e58020f0446
|
||||
v0.7.11 f46ed718ba8d6bb4d42cd7b0f0150c406017c373
|
||||
v0.8 d56e04c0d960c8d3d4ab88b578dc508a2b4e07dc
|
||||
v0.8.1 cd6f26664cb8d32a13847d6648567c47c580e248
|
||||
v0.8.2 7cc0999aebfe63b6bb6dd83c1dff62c3915c4820
|
||||
v0.8.3 986500fe2f10870018f1fba1e5465476b8915977
|
||||
v0.8.4 f0d0b82b8d6f5f450952113e234d0a5a49e80c48
|
||||
v0.8.5 f5d9ddc6c2a2802a61e5ce590c6b6688bf736a69
|
||||
v0.8.6 75904ed7452c6cbfb2a70cd379a899d8a75b97c2
|
||||
v0.8.7 4f9e568019492126e236da85b5ca0a059f292900
|
||||
v0.8.8 a949a49d5efaaf2d881143d23e9fb5ff9e28e88c
|
||||
v0.8.9 a034926264cd1025c69d6ceb3fe444965f960b75
|
||||
v0.8.10 59accdd814398b884167c0f41dbf46dcccf0c29c
|
||||
v0.8.11 d630ec9092f039cb5e51c5dd6d92fc47b91407e4
|
||||
v0.8.12 57871c99031cf597ffa0d819057ac1401e129f32
|
||||
v0.8.13 e43e6e876513450d235124fcb711f1724ed9814c
|
||||
v0.8.14 71901c94dbbaa2f9f156a80c14cc7ea65219fc7c
|
||||
v0.8.15 5a7c2f90361e72e9c35e88abd2e11acdc4aba354
|
||||
v0.8.16 f41dc62a12cc0f3cb8c5453c0caa0ba21e1bd01e
|
||||
v0.9.0 58b84fb401a804967aa0dd5ee66fafa90194fd30
|
||||
v0.9.1 89f68bf0cbf53a81b0553d3816fdbe522f941fa1
|
||||
v0.9.2 c7d3b28b93faa6c955fb24bc64031512ee985ee9
|
||||
v0.9.3 8704c1ff952b5c85a44f50143bbd1a4f7b4887e2
|
||||
v0.9.4 fa310d9e2542cf497d92f007baec8fd751ffa99c
|
||||
v0.9.5 3b1e9017c560499786d8a0e46aaaeea65037acac
|
||||
v0.9.6 0b4d08fab8e35a264bc7383e878538f8083c33e5
|
||||
v0.9.7 f8cb04e4a8b032b72a909f68b808a50936184bee
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
|
||||
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
FAIL=0
|
||||
|
||||
if grep '^#!.*python' $@ | grep -v '#!/usr/bin/env python3$'; then
|
||||
echo -e "Invalid shebang! Must use '#!/usr/bin/env python3'\n"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if grep '^#!.*bash' $@ | grep -v '#!/usr/bin/env bash$'; then
|
||||
echo -e "Invalid shebang! Must use '#!/usr/bin/env bash'"
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
exit $FAIL
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
UNDERLINE='\033[4m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
cd $DIR/../../
|
||||
|
||||
FAILED=0
|
||||
|
||||
IGNORED_FILES="uv\.lock|docs\/CARS.md"
|
||||
IGNORED_DIRS="^third_party.*|^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*"
|
||||
|
||||
function run() {
|
||||
shopt -s extglob
|
||||
case $1 in
|
||||
$SKIP | $RUN ) return 0 ;;
|
||||
esac
|
||||
|
||||
echo -en "$1"
|
||||
|
||||
for ((i=0; i<$((50 - ${#1})); i++)); do
|
||||
echo -n "."
|
||||
done
|
||||
|
||||
shift 1;
|
||||
CMD="$@"
|
||||
|
||||
set +e
|
||||
log="$((eval "$CMD" ) 2>&1)"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo -e "[${GREEN}✔${NC}]"
|
||||
else
|
||||
echo -e "[${RED}✗${NC}]"
|
||||
echo "$log"
|
||||
FAILED=1
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
function run_tests() {
|
||||
ALL_FILES=$1
|
||||
PYTHON_FILES=$2
|
||||
|
||||
run "ruff" ruff check $PYTHON_FILES --quiet
|
||||
run "check_added_large_files" python3 -m pre_commit_hooks.check_added_large_files --enforce-all $ALL_FILES --maxkb=120
|
||||
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
|
||||
|
||||
if [[ -z "$FAST" ]]; then
|
||||
run "mypy" mypy $PYTHON_FILES
|
||||
run "codespell" codespell $ALL_FILES
|
||||
fi
|
||||
|
||||
return $FAILED
|
||||
}
|
||||
|
||||
function help() {
|
||||
echo "A fast linter"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Usage:${NC} op lint [TESTS] [OPTIONS]"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Tests:${NC}"
|
||||
echo -e " ${BOLD}ruff${NC}"
|
||||
echo -e " ${BOLD}mypy${NC}"
|
||||
echo -e " ${BOLD}codespell${NC}"
|
||||
echo -e " ${BOLD}check_added_large_files${NC}"
|
||||
echo -e " ${BOLD}check_shebang_scripts_are_executable${NC}"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Options:${NC}"
|
||||
echo -e " ${BOLD}-f, --fast${NC}"
|
||||
echo " Skip slow tests"
|
||||
echo -e " ${BOLD}-s, --skip${NC}"
|
||||
echo " Specify tests to skip separated by spaces"
|
||||
echo ""
|
||||
echo -e "${BOLD}${UNDERLINE}Examples:${NC}"
|
||||
echo " op lint mypy ruff"
|
||||
echo " Only run the mypy and ruff tests"
|
||||
echo ""
|
||||
echo " op lint --skip mypy ruff"
|
||||
echo " Skip the mypy and ruff tests"
|
||||
echo ""
|
||||
echo " op lint"
|
||||
echo " Run all the tests"
|
||||
}
|
||||
|
||||
SKIP=""
|
||||
RUN=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-f | --fast ) shift 1; FAST="1" ;;
|
||||
-s | --skip ) shift 1; SKIP=" " ;;
|
||||
-h | --help | -help | --h ) help; exit 0 ;;
|
||||
* ) if [[ -n $SKIP ]]; then SKIP+="$1 "; else RUN+="$1 "; fi; shift 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
RUN=$([ -z "$RUN" ] && echo "" || echo "!($(echo $RUN | sed 's/ /|/g'))")
|
||||
SKIP="@($(echo $SKIP | sed 's/ /|/g'))"
|
||||
|
||||
GIT_FILES="$(git ls-files | sed -E "s/$IGNORED_FILES|$IGNORED_DIRS//g")"
|
||||
ALL_FILES=""
|
||||
for f in $GIT_FILES; do
|
||||
if [[ -f $f ]]; then
|
||||
ALL_FILES+="$f"$'\n'
|
||||
fi
|
||||
done
|
||||
PYTHON_FILES=$(echo "$ALL_FILES" | grep --color=never '.py$' || true)
|
||||
|
||||
run_tests "$ALL_FILES" "$PYTHON_FILES"
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
if [[ -f .git/hooks/post-commit.d/post-commit ]]; then
|
||||
.git/hooks/post-commit.d/post-commit
|
||||
fi
|
||||
tools/op.sh lint --fast
|
||||
echo ""
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
pip install --upgrade pyupgrade
|
||||
|
||||
git ls-files '*.py' | grep -v 'third_party/' | xargs pyupgrade --py311-plus
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function fail {
|
||||
echo $1 >&2
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ import os
|
||||
import time
|
||||
import numpy as np
|
||||
from multiprocessing import Process
|
||||
from openpilot.common.threadname import setthreadname
|
||||
from setproctitle import setproctitle
|
||||
|
||||
def waste(core):
|
||||
os.sched_setaffinity(0, [core,])
|
||||
@@ -16,7 +16,7 @@ def waste(core):
|
||||
j = 0
|
||||
while 1:
|
||||
if (i % 100) == 0:
|
||||
setthreadname("%3d: %8d" % (core, i))
|
||||
setproctitle("%3d: %8d" % (core, i))
|
||||
lt = time.monotonic()
|
||||
print("%3d: %8d %f %.2f" % (core, i, lt-st, j))
|
||||
st = lt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "compressing training guide images"
|
||||
optipng -o7 -strip all training/*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user