From fb3336614484553456bee6c2116b729177ecbc46 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 24 Jul 2024 00:27:10 +0800 Subject: [PATCH 01/22] Fix FutureWarning "Cython directive 'language_level' not set" (#33046) fix FutureWarning --- selfdrive/modeld/models/commonmodel_pyx.pyx | 2 +- selfdrive/modeld/runners/runmodel_pyx.pyx | 2 +- selfdrive/modeld/runners/snpemodel_pyx.pyx | 2 +- selfdrive/modeld/runners/thneedmodel_pyx.pyx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/selfdrive/modeld/models/commonmodel_pyx.pyx b/selfdrive/modeld/models/commonmodel_pyx.pyx index e292bb0d2d..ecbe644e09 100644 --- a/selfdrive/modeld/models/commonmodel_pyx.pyx +++ b/selfdrive/modeld/models/commonmodel_pyx.pyx @@ -1,5 +1,5 @@ # distutils: language = c++ -# cython: c_string_encoding=ascii +# cython: c_string_encoding=ascii, language_level=3 import numpy as np cimport numpy as cnp diff --git a/selfdrive/modeld/runners/runmodel_pyx.pyx b/selfdrive/modeld/runners/runmodel_pyx.pyx index e1b201a6a9..12b8ec10ff 100644 --- a/selfdrive/modeld/runners/runmodel_pyx.pyx +++ b/selfdrive/modeld/runners/runmodel_pyx.pyx @@ -1,5 +1,5 @@ # distutils: language = c++ -# cython: c_string_encoding=ascii +# cython: c_string_encoding=ascii, language_level=3 from libcpp.string cimport string diff --git a/selfdrive/modeld/runners/snpemodel_pyx.pyx b/selfdrive/modeld/runners/snpemodel_pyx.pyx index c3b2b7e9bd..f83b7c8cff 100644 --- a/selfdrive/modeld/runners/snpemodel_pyx.pyx +++ b/selfdrive/modeld/runners/snpemodel_pyx.pyx @@ -1,5 +1,5 @@ # distutils: language = c++ -# cython: c_string_encoding=ascii +# cython: c_string_encoding=ascii, language_level=3 import os from libcpp cimport bool diff --git a/selfdrive/modeld/runners/thneedmodel_pyx.pyx b/selfdrive/modeld/runners/thneedmodel_pyx.pyx index 53487afa1b..6f8fdd255f 100644 --- a/selfdrive/modeld/runners/thneedmodel_pyx.pyx +++ b/selfdrive/modeld/runners/thneedmodel_pyx.pyx @@ -1,5 +1,5 @@ # distutils: language = c++ -# cython: c_string_encoding=ascii +# cython: c_string_encoding=ascii, language_level=3 from libcpp cimport bool from libcpp.string cimport string From 93eb7ee0cc5af0d7c86248cbcafad86dd374976f Mon Sep 17 00:00:00 2001 From: Joseph Wagner <68037585+wjoseph0@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:35:19 -0500 Subject: [PATCH 02/22] README.md: 275+ cars (#33048) 275+ cars --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db74ee6a1a..5afaf6e7d6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,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. From d828ac43444dad2d25dafcd4ba7543230b1f156f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Jul 2024 11:11:31 -0700 Subject: [PATCH 03/22] CI: setup triggering jenkins for forks (#33049) --- .github/workflows/jenkins-pr-trigger.yaml | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/jenkins-pr-trigger.yaml diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml new file mode 100644 index 0000000000..42ef4a7391 --- /dev/null +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -0,0 +1,50 @@ +name: jenkins scan + +on: + issue_comment: + types: [created] + +jobs: + # TODO: gc old branches in a separate job in this workflow + scan-comments: + runs-on: ubuntu-latest + if: github.event.issue.pull_request != null + steps: + - name: Check if comment contains trigger phrase and is from someone with write access + id: check_comment + uses: actions/github-script@v6 + 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: boolean + + - name: Set PR number + id: set_pr_number + if: steps.check_comment.outputs.result == 'true' + run: echo "PR_NUMBER=$(echo ${{ github.event.issue.number }})" >> $GITHUB_ENV + + - name: Checkout repository + if: steps.check_comment.outputs.result == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.issue.pull_request.head.ref }} + + - 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-${{ env.PR_NUMBER }} + git push -f origin tmp-jenkins-${{ env.PR_NUMBER }} From e7ec1b8ff16feeb3d02200c95692aa4bcb402337 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Jul 2024 11:14:00 -0700 Subject: [PATCH 04/22] json encoding --- .github/workflows/jenkins-pr-trigger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index 42ef4a7391..10c601777d 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -28,7 +28,7 @@ jobs: const hasWriteAccess = permissions.permission === 'write' || permissions.permission === 'admin'; return (hasWriteAccess && comment.includes(triggerPhrase)); - result-encoding: boolean + result-encoding: json - name: Set PR number id: set_pr_number From ef5d6a0466dd2ebf0b5595150b68b3c59722f397 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Jul 2024 11:27:56 -0700 Subject: [PATCH 05/22] jenkins trigger fixups --- .github/workflows/jenkins-pr-trigger.yaml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index 10c601777d..acdf5feb86 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -2,17 +2,17 @@ name: jenkins scan on: issue_comment: - types: [created] + 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 != null + if: ${{ github.event.issue.pull_request }} steps: - - name: Check if comment contains trigger phrase and is from someone with write access + - name: Check for trigger phrase id: check_comment - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const triggerPhrase = "trigger-jenkins"; @@ -30,21 +30,16 @@ jobs: return (hasWriteAccess && comment.includes(triggerPhrase)); result-encoding: json - - name: Set PR number - id: set_pr_number - if: steps.check_comment.outputs.result == 'true' - run: echo "PR_NUMBER=$(echo ${{ github.event.issue.number }})" >> $GITHUB_ENV - - name: Checkout repository if: steps.check_comment.outputs.result == 'true' uses: actions/checkout@v4 with: - ref: ${{ github.event.issue.pull_request.head.ref }} + 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-${{ env.PR_NUMBER }} - git push -f origin tmp-jenkins-${{ env.PR_NUMBER }} + git checkout -b tmp-jenkins-${{ github.event.issue.number }} + git push -f origin tmp-jenkins-${{ github.event.issue.number }} From 29d0bfe1ab832832f027c899e337551fd8716a49 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Jul 2024 11:32:51 -0700 Subject: [PATCH 06/22] skip lfs --- .github/workflows/jenkins-pr-trigger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index acdf5feb86..eb2a7271be 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -42,4 +42,4 @@ jobs: 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 push -f origin tmp-jenkins-${{ github.event.issue.number }} + GIT_LFS_SKIP_SMUDGE=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }} From 9b8c1693c9c74bae87c44615e90fc372c551900c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 23 Jul 2024 11:41:27 -0700 Subject: [PATCH 07/22] skip push --- .github/workflows/jenkins-pr-trigger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index eb2a7271be..db1d524018 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -42,4 +42,4 @@ jobs: 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_SMUDGE=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }} + GIT_LFS_SKIP_PUSH=1 git push -f origin tmp-jenkins-${{ github.event.issue.number }} From fbbd4ee692d2f84b90bfaf93499c6360e5bdad2b Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Wed, 24 Jul 2024 02:53:40 +0800 Subject: [PATCH 08/22] Fix `/usr/bin/ld: skipping incompatible /usr/lib/libgcc_s.so.1` warnings (#33047) fix incompatible lib warning --- SConstruct | 1 - 1 file changed, 1 deletion(-) diff --git a/SConstruct b/SConstruct index 0c4dbee18e..1f83b1e43d 100644 --- a/SConstruct +++ b/SConstruct @@ -102,7 +102,6 @@ if arch == "larch64": libpath = [ "/usr/local/lib", - "/usr/lib", "/system/vendor/lib64", f"#third_party/acados/{arch}/lib", ] From 3bc1b173d2390a93b0c31090861bbc597eff4d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Tue, 23 Jul 2024 13:55:30 -0700 Subject: [PATCH 09/22] Longcontrol: engage into stopped state when needed (#33042) test stay stopped --- selfdrive/controls/lib/longcontrol.py | 14 +++-- selfdrive/controls/tests/test_longcontrol.py | 56 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 selfdrive/controls/tests/test_longcontrol.py diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index e4841c705f..efeb76c4a8 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -22,22 +22,26 @@ def long_control_state_trans(CP, active, long_control_state, v_ego, long_control_state = LongCtrlState.off else: - if long_control_state in (LongCtrlState.off, LongCtrlState.pid): - long_control_state = LongCtrlState.pid - if stopping_condition: + if long_control_state == LongCtrlState.off: + if not starting_condition: long_control_state = LongCtrlState.stopping + else: + if starting_condition and CP.startingState: + long_control_state = LongCtrlState.starting + else: + long_control_state = LongCtrlState.pid + elif long_control_state == LongCtrlState.stopping: if starting_condition and CP.startingState: long_control_state = LongCtrlState.starting elif starting_condition: long_control_state = LongCtrlState.pid - elif long_control_state == LongCtrlState.starting: + elif long_control_state in [LongCtrlState.starting, LongCtrlState.pid]: if stopping_condition: long_control_state = LongCtrlState.stopping elif started_condition: long_control_state = LongCtrlState.pid - return long_control_state class LongControl: diff --git a/selfdrive/controls/tests/test_longcontrol.py b/selfdrive/controls/tests/test_longcontrol.py new file mode 100644 index 0000000000..ab50810d89 --- /dev/null +++ b/selfdrive/controls/tests/test_longcontrol.py @@ -0,0 +1,56 @@ +from cereal import car +from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState, long_control_state_trans + + + + +class TestLongControlStateTransition: + + def test_stay_stopped(self): + CP = car.CarParams.new_message() + active = True + current_state = LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=True, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=True, cruise_standstill=False) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=False, cruise_standstill=True) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0, + should_stop=False, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.pid + active = False + next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0, + should_stop=False, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.off + +def test_engage(): + CP = car.CarParams.new_message() + active = True + current_state = LongCtrlState.off + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=True, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=True, cruise_standstill=False) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=False, cruise_standstill=True) + assert next_state == LongCtrlState.stopping + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.pid + +def test_starting(): + CP = car.CarParams.new_message(startingState=True, vEgoStarting=0.5) + active = True + current_state = LongCtrlState.starting + next_state = long_control_state_trans(CP, active, current_state, v_ego=0.1, + should_stop=False, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.starting + next_state = long_control_state_trans(CP, active, current_state, v_ego=1.0, + should_stop=False, brake_pressed=False, cruise_standstill=False) + assert next_state == LongCtrlState.pid From 1e9738131d7737cbc9af161cf829c83c67577970 Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Tue, 23 Jul 2024 14:52:08 -0700 Subject: [PATCH 10/22] don't lock when installing python packages (#33051) frozen --- tools/install_python_dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/install_python_dependencies.sh b/tools/install_python_dependencies.sh index 276de58db7..a90462888f 100755 --- a/tools/install_python_dependencies.sh +++ b/tools/install_python_dependencies.sh @@ -34,7 +34,7 @@ update_uv # TODO: remove --no-cache once this is fixed: https://github.com/astral-sh/uv/issues/4378 echo "installing python packages..." -uv --no-cache sync --all-extras +uv --no-cache sync --frozen --all-extras source .venv/bin/activate echo "PYTHONPATH=${PWD}" > $ROOT/.env From f60dfd4dbb5d33bb1ec36c550742d185e2c4bf78 Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Tue, 23 Jul 2024 21:47:07 -0700 Subject: [PATCH 11/22] op tool helper (#33053) * op * change this * juggler * options * fix * submodules * typo * venv * clean + install --- tools/op.sh | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100755 tools/op.sh diff --git a/tools/op.sh b/tools/op.sh new file mode 100755 index 0000000000..d8a3f4b809 --- /dev/null +++ b/tools/op.sh @@ -0,0 +1,262 @@ +#!/bin/bash + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +function op_first_install() { + (set -e + + echo "Installing op system-wide..." + RC_FILE="${HOME}/.$(basename ${SHELL})rc" + if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then + RC_FILE="$HOME/.bash_profile" + fi + printf "\nalias op='source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/op.sh" \"\$@\"'\n" >> $RC_FILE + echo -e " ↳ [${GREEN}✔${NC}] op installed successfully. Open a new shell to use it.\n" + + ) +} + +# be default, assume openpilot dir is in current directory +OPENPILOT_ROOT=$(pwd) +function op_check_openpilot_dir() { + (set -e + + if [ ! -f "$OPENPILOT_ROOT/launch_openpilot.sh" ]; then + echo "openpilot directory not found!" + return 1 + fi + + ) +} + +function op_check_git() { + (set -e + + cd $OPENPILOT_ROOT + + echo "Checking for git..." + if ! command -v "git" > /dev/null 2>&1; then + echo -e " ↳ [${RED}✗${NC}] git not found on your system!" + return 1 + else + echo -e " ↳ [${GREEN}✔${NC}] git found on your system.\n" + fi + + echo "Checking for git lfs files..." + if [[ $(file -b $(git lfs ls-files -n | grep "\.so" | head -n 1)) == "ASCII text" ]]; then + echo -e " ↳ [${RED}✗${NC}] git lfs files not found! Run git lfs pull" + return 1 + else + echo -e " ↳ [${GREEN}✔${NC}] git lfs files found on your system.\n" + fi + + echo "Checking for git submodules..." + if $(git submodule foreach --quiet --recursive 'return 1' 2&> /dev/null); then + echo -e " ↳ [${RED}✗${NC}] git submodules not found! Run 'git submodule update --init --recursive'" + return 1 + else + echo -e " ↳ [${GREEN}✔${NC}] git submodules found on your system.\n" + fi + + ) +} + +function op_check_os() { + (set -e + + echo "Checking for compatible os version..." + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + + if [ -f "/etc/os-release" ]; then + source /etc/os-release + case "$VERSION_CODENAME" in + "jammy" | "kinetic" | "noble" | "focal") + OS_VERSION="Ubuntu" + echo -e " ↳ [${GREEN}✔${NC}] Ubuntu $VERSION_CODENAME detected.\n" + ;; + * ) + echo -e " ↳ [${RED}✗${NC}] Incompatible Ubuntu version $VERSION_CODENAME detected!" + return 1 + ;; + esac + else + echo -e " ↳ [${RED}✗${NC}] No /etc/os-release on your system. Make sure you're running on Ubuntu, or similar!" + return 1 + fi + + elif [[ "$OSTYPE" == "darwin"* ]]; then + echo -e " ↳ [${GREEN}✔${NC}] macos detected.\n" + OS_VERSION="Darwin" + else + echo -e " ↳ [${RED}✗${NC}] OS type $OSTYPE not supported!" + return 1 + fi + + ) +} + +function op_check_python() { + (set -e + + echo "Checking for compatible python version..." + export REQUIRED_PYTHON_VERSION=$(grep "requires-python" pyproject.toml | cut -d= -f3- | tr -d '"' | tr -d ' ') + if ! command -v "python3" > /dev/null 2>&1; then + echo -e " ↳ [${RED}✗${NC}] python3 not found on your system. You need python version at least $REQUIRED_PYTHON_VERSION to continue!" + return 1 + else + if $(python3 -c "import sys; quit(not sys.version_info >= tuple(map(int, \"$REQUIRED_PYTHON_VERSION\".split('.'))))"); then + echo -e " ↳ [${GREEN}✔${NC}] $(python3 --version) detected.\n" + else + echo -e " ↳ [${RED}✗${NC}] You need python version at least $REQUIRED_PYTHON_VERSION to continue!" + return 1 + fi + fi + + ) +} + +# this must be run in the same shell as the user calling "op" +function op_venv() { + op_check_openpilot_dir || return 1 + source $OPENPILOT_ROOT/.venv/bin/activate || (echo -e "\nCan't activate venv. Have you ran 'op install' ?" && return 1) +} + +function op_check() { + (set -e + + op_check_openpilot_dir + cd $OPENPILOT_ROOT + op_check_git + op_check_os + op_check_python + + ) +} + +function op_run() { + (set -e + + op_venv + cd $OPENPILOT_ROOT + $OPENPILOT_ROOT/launch_openpilot.sh + + ) +} + +function op_install() { + (set -e + + op_check_openpilot_dir + cd $OPENPILOT_ROOT + + op_check_os + op_check_python + + case "$OS_VERSION" in + "Ubuntu") + $OPENPILOT_ROOT/tools/ubuntu_setup.sh + ;; + "Darwin") + $OPENPILOT_ROOT/tools/mac_setup.sh + ;; + esac + + git submodules update --init --recursive + git lfs pull + + ) +} + +function op_build() { + (set -e + + op_venv + cd $OPENPILOT_ROOT + + scons $@ || echo -e "\nBuild failed. Have you ran 'op install' ?" + + ) +} + +function op_juggle() { + (set -e + + op_venv + cd $OPENPILOT_ROOT + + $OPENPILOT_ROOT/tools/plotjuggler/juggle.py $@ + + ) +} + +function op_default() { + echo "An openpilot helper" + echo "" + echo -e "\e[4mUsage:\e[0m op [OPTIONS] " + echo "" + echo -e "\e[4mCommands:\e[0m" + echo " venv Activate the virtual environment" + echo " check Check system requirements (git, os, python) to start using openpilot" + echo " install Install requirements to use openpilot" + echo " build Build openpilot" + echo " run Run openpilot" + echo " juggle Run Plotjuggler" + echo " help Show this message" + echo " --install Install this tool system wide" + echo "" + echo -e "\e[4mOptions:\e[0m" + echo " -d, --dir" + echo " Specify the openpilot directory you want to use" + echo " Default to the current working directory" + echo "" + echo -e "\e[4mExamples:\e[0m" + echo " op --dir /tmp/openpilot check" + echo " Run the check command on openpilot located in /tmp/openpilot" + echo "" + echo " op juggle --install" + echo " Install plotjuggler in the openpilot located in your current" + echo " working directory" + echo "" + echo " op --dir /tmp/openpilot build -j4" + echo " Run the build command on openpilot located in /tmp/openpilot" + echo " on 4 cores" +} + + +function _op() { + # parse Options + case $1 in + -d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;; + esac + + # parse Commands + case $1 in + venv ) shift 1; op_venv "$@" ;; + check ) shift 1; op_check "$@" ;; + install ) shift 1; op_install "$@" ;; + build ) shift 1; op_build "$@" ;; + run ) shift 1; op_run "$@" ;; + juggle ) shift 1; op_juggle "$@" ;; + --install ) shift 1; op_first_install "$@" ;; + * ) op_default "$@" ;; + esac +} + +_op $@ + +# remove from env +unset -f _op +unset -f op_check +unset -f op_install +unset -f op_build +unset -f op_run +unset -f op_juggle +unset -f op_venv +unset -f op_check_openpilot_dir +unset -f op_check_git +unset -f op_check_python +unset -f op_check_os +unset -f op_first_install +unset -f op_default From 3382002cd03604710f39d01f19a37f4bb66b7cdf Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Tue, 23 Jul 2024 22:34:21 -0700 Subject: [PATCH 12/22] Update op.sh --- tools/op.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/op.sh b/tools/op.sh index d8a3f4b809..f7caa9d047 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -163,7 +163,7 @@ function op_install() { ;; esac - git submodules update --init --recursive + git submodule update --init --recursive git lfs pull ) From 18c310addf7e19688f6cfc4530026b281ac7e75f Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Tue, 23 Jul 2024 23:04:42 -0700 Subject: [PATCH 13/22] Update op.sh --- tools/op.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index f7caa9d047..bbc4ded445 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -73,7 +73,6 @@ function op_check_os() { source /etc/os-release case "$VERSION_CODENAME" in "jammy" | "kinetic" | "noble" | "focal") - OS_VERSION="Ubuntu" echo -e " ↳ [${GREEN}✔${NC}] Ubuntu $VERSION_CODENAME detected.\n" ;; * ) @@ -88,7 +87,6 @@ function op_check_os() { elif [[ "$OSTYPE" == "darwin"* ]]; then echo -e " ↳ [${GREEN}✔${NC}] macos detected.\n" - OS_VERSION="Darwin" else echo -e " ↳ [${RED}✗${NC}] OS type $OSTYPE not supported!" return 1 @@ -154,14 +152,11 @@ function op_install() { op_check_os op_check_python - case "$OS_VERSION" in - "Ubuntu") - $OPENPILOT_ROOT/tools/ubuntu_setup.sh - ;; - "Darwin") - $OPENPILOT_ROOT/tools/mac_setup.sh - ;; - esac + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + $OPENPILOT_ROOT/tools/ubuntu_setup.sh + elif [[ "$OSTYPE" == "darwin"* ]]; then + $OPENPILOT_ROOT/tools/mac_setup.sh + fi git submodule update --init --recursive git lfs pull From bd8dd65ce0e5477100e07f33d2b237111e922c62 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 25 Jul 2024 00:42:31 +0800 Subject: [PATCH 14/22] ui: fix wayland requestActivate warning on device (#33054) fix wayland requestActivate warning in fullscreen mode --- selfdrive/ui/qt/qt_window.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/qt_window.cc b/selfdrive/ui/qt/qt_window.cc index f71cea04e9..8d3d7cf72e 100644 --- a/selfdrive/ui/qt/qt_window.cc +++ b/selfdrive/ui/qt/qt_window.cc @@ -18,7 +18,9 @@ void setMainWindow(QWidget *w) { wl_surface *s = reinterpret_cast(native->nativeResourceForWindow("surface", w->windowHandle())); wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270); wl_surface_commit(s); - w->showFullScreen(); + + w->setWindowState(Qt::WindowFullScreen); + w->setVisible(true); // ensure we have a valid eglDisplay, otherwise the ui will silently fail void *egl = native->nativeResourceForWindow("egldisplay", w->windowHandle()); From 0fa6745a67b60a572cfa4060d8155ac50f4e4e06 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Thu, 25 Jul 2024 01:07:10 +0800 Subject: [PATCH 15/22] camerad: refactor camera_open() into separate functions for clarity (#33056) split function --- system/camerad/cameras/camera_qcom2.cc | 32 +++++++++++++++++++------- system/camerad/cameras/camera_qcom2.h | 5 ++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 47ea5ded4d..7c1f8e44e7 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -469,6 +469,16 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num enabled = enabled_; if (!enabled) return; + if (!openSensor()) { + return; + } + + configISP(); + configCSIPHY(); + linkDevices(); +} + +bool CameraState::openSensor() { sensor_fd = open_v4l_by_name_and_index("cam-sensor-driver", camera_num); assert(sensor_fd >= 0); LOGD("opened sensor for %d", camera_num); @@ -493,7 +503,7 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num !init_sensor_lambda(new OS04C10)) { LOGE("** sensor %d FAILED bringup, disabling", camera_num); enabled = false; - return; + return false; } LOGD("-- Probing sensor %d success", camera_num); @@ -512,7 +522,10 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num LOG("-- Configuring sensor"); sensors_i2c(ci->init_reg_array.data(), ci->init_reg_array.size(), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, ci->data_word); + return true; +} +void CameraState::configISP() { // NOTE: to be able to disable road and wide road, we still have to configure the sensor over i2c // If you don't do this, the strobe GPIO is an output (even in reset it seems!) if (!enabled) return; @@ -570,6 +583,13 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num isp_dev_handle = *isp_dev_handle_; LOGD("acquire isp dev"); + // config ISP + alloc_w_mmu_hdl(multi_cam_state->video0_fd, 984480, (uint32_t*)&buf0_handle, 0x20, CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | + CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE, multi_cam_state->device_iommu, multi_cam_state->cdm_iommu); + config_isp(0, 0, 1, buf0_handle, 0); +} + +void CameraState::configCSIPHY() { csiphy_fd = open_v4l_by_name_and_index("cam-csiphy-driver", camera_num); assert(csiphy_fd >= 0); LOGD("opened csiphy for %d", camera_num); @@ -580,11 +600,6 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num csiphy_dev_handle = *csiphy_dev_handle_; LOGD("acquire csiphy dev"); - // config ISP - alloc_w_mmu_hdl(multi_cam_state->video0_fd, 984480, (uint32_t*)&buf0_handle, 0x20, CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | - CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE, multi_cam_state->device_iommu, multi_cam_state->cdm_iommu); - config_isp(0, 0, 1, buf0_handle, 0); - // config csiphy LOG("-- Config CSI PHY"); { @@ -612,15 +627,16 @@ void CameraState::camera_open(MultiCameraState *multi_cam_state_, int camera_num int ret_ = device_config(csiphy_fd, session_handle, csiphy_dev_handle, cam_packet_handle); assert(ret_ == 0); } +} - // link devices +void CameraState::linkDevices() { LOG("-- Link devices"); struct cam_req_mgr_link_info req_mgr_link_info = {0}; req_mgr_link_info.session_hdl = session_handle; req_mgr_link_info.num_devices = 2; req_mgr_link_info.dev_hdls[0] = isp_dev_handle; req_mgr_link_info.dev_hdls[1] = sensor_dev_handle; - ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_LINK, &req_mgr_link_info, sizeof(req_mgr_link_info)); + int ret = do_cam_control(multi_cam_state->video0_fd, CAM_REQ_MGR_LINK, &req_mgr_link_info, sizeof(req_mgr_link_info)); link_handle = req_mgr_link_info.link_hdl; LOGD("link: %d session: 0x%X isp: 0x%X sensors: 0x%X link: 0x%X", ret, session_handle, isp_dev_handle, sensor_dev_handle, link_handle); diff --git a/system/camerad/cameras/camera_qcom2.h b/system/camerad/cameras/camera_qcom2.h index 0b15c9c3f0..b702d1bb69 100644 --- a/system/camerad/cameras/camera_qcom2.h +++ b/system/camerad/cameras/camera_qcom2.h @@ -86,6 +86,11 @@ public: void sensors_i2c(const struct i2c_random_wr_payload* dat, int len, int op_code, bool data_word); private: + bool openSensor(); + void configISP(); + void configCSIPHY(); + void linkDevices(); + // for debugging Params params; }; From d49c5193c33a41447d1d5748a069972893b7c6ec Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Wed, 24 Jul 2024 10:31:27 -0700 Subject: [PATCH 16/22] ci: fix ui preview (#33002) * use pull_request_target * env for name --- .github/workflows/selfdrive_tests.yaml | 55 +--------------- .github/workflows/ui_preview.yaml | 91 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/ui_preview.yaml diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 42c1dbb5eb..1154948ace 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -338,6 +338,7 @@ 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 steps: @@ -355,55 +356,5 @@ jobs: - name: Upload Test Report uses: actions/upload-artifact@v4 with: - name: report-${{ inputs.run_number || '1' }} - path: selfdrive/ui/tests/test_ui/report_${{ inputs.run_number || '1' }} - - 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_1/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: | - - ## UI Screenshots - - - - - - - - - - - - - -
- 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 diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml new file mode 100644 index 0000000000..c05c01f3e3 --- /dev/null +++ b/.github/workflows/ui_preview.yaml @@ -0,0 +1,91 @@ +name: "ui preview" +on: + pull_request_target: + types: [assigned, opened, synchronize, reopened, edited] + branches: + - 'master' + paths: + - 'selfdrive/ui/**' + +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: $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 == "$UI_JOB_NAME") | .html_url | capture("(?[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: | + + ## UI Screenshots + + + + + + + + + + + + + +
+ comment_tag: run_id_screenshots + pr_number: ${{ github.event.number }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 344694110751b8282eabe0b8b1e4de38646e4623 Mon Sep 17 00:00:00 2001 From: Hoang Bui <47828508+bongbui321@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:36:28 -0700 Subject: [PATCH 17/22] CI: remove redundant save cache step (#33052) remove --- .github/workflows/tools_tests.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index b64963fb60..9085556392 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -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 From 2221ffcf0ea0d0631d92e016d5c1bd98116b9aba Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Wed, 24 Jul 2024 11:03:24 -0700 Subject: [PATCH 18/22] ci: use github env for ui preview job name (#33060) fix this --- .github/workflows/ui_preview.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index c05c01f3e3..bc19e23778 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -28,7 +28,7 @@ jobs: uses: lewagon/wait-on-check-action@v1.3.4 with: ref: ${{ github.event.pull_request.head.sha }} - check-name: $UI_JOB_NAME + check-name: ${{ env.UI_JOB_NAME }} repo-token: ${{ secrets.GITHUB_TOKEN }} allowed-conclusions: success wait-interval: 20 @@ -36,7 +36,7 @@ jobs: - 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 == "$UI_JOB_NAME") | .html_url | capture("(?[0-9]+)") | .number')" >> $GITHUB_OUTPUT + 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("(?[0-9]+)") | .number')" >> $GITHUB_OUTPUT - name: Checkout ci-artifacts uses: actions/checkout@v4 From 31036771ee8ba71e3fbe7c7f08aad3b5be0127e6 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 24 Jul 2024 12:11:20 -0700 Subject: [PATCH 19/22] rerun: link to upstream issues --- tools/rerun/run.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/rerun/run.py b/tools/rerun/run.py index 421785a2d5..6d9554038c 100755 --- a/tools/rerun/run.py +++ b/tools/rerun/run.py @@ -18,6 +18,12 @@ RR_TIMELINE_NAME = "Timeline" RR_WIN = "rerun_test" +""" +Relevant upstream Rerun issues: +- large time series: https://github.com/rerun-io/rerun/issues/5967 +- loading videos directly: https://github.com/rerun-io/rerun/issues/6532 +""" + class Rerunner: def __init__(self, route, segment_range, camera_config, enabled_services): self.enabled_services = [s.lower() for s in enabled_services] From e38a1428aa20aad134b4ad9fd1abab33a1de70b9 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 24 Jul 2024 14:47:33 -0700 Subject: [PATCH 20/22] LogReader: support multiple log extensions in route (#33066) * support rlog.zst * TODO --- tools/lib/logreader.py | 1 + tools/lib/route.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index 6ad77bf823..07a4b2003e 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -140,6 +140,7 @@ def internal_source(sr: SegmentRange, mode: ReadMode, file_ext: str = "bz2") -> def get_internal_url(sr: SegmentRange, seg, file): return f"cd:/{sr.dongle_id}/{sr.log_id}/{seg}/{file}.{file_ext}" + # TODO: list instead of using static URLs to support routes with multiple file extensions rlog_paths = [get_internal_url(sr, seg, "rlog") for seg in sr.seg_idxs] qlog_paths = [get_internal_url(sr, seg, "qlog") for seg in sr.seg_idxs] diff --git a/tools/lib/route.py b/tools/lib/route.py index 6ff5d19208..ddb8b0486e 100644 --- a/tools/lib/route.py +++ b/tools/lib/route.py @@ -11,7 +11,7 @@ from openpilot.tools.lib.helpers import RE QLOG_FILENAMES = ['qlog', 'qlog.bz2', 'qlog.zst'] QCAMERA_FILENAMES = ['qcamera.ts'] -LOG_FILENAMES = ['rlog', 'rlog.bz2', 'raw_log.bz2'] +LOG_FILENAMES = ['rlog', 'rlog.bz2', 'raw_log.bz2', 'rlog.zst'] CAMERA_FILENAMES = ['fcamera.hevc', 'video.hevc'] DCAMERA_FILENAMES = ['dcamera.hevc'] ECAMERA_FILENAMES = ['ecamera.hevc'] From add958bb08890c653be89999701cb3d794c5c717 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 24 Jul 2024 14:48:33 -0700 Subject: [PATCH 21/22] athenad: log failed upload items --- system/athena/athenad.py | 1 + 1 file changed, 1 insertion(+) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 9769f065f6..b4f9b8b6a7 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -401,6 +401,7 @@ def uploadFilesToUrls(files_data: list[UploadFileDict]) -> UploadFilesToUrlRespo resp: UploadFilesToUrlResponse = {"enqueued": len(items), "items": items} if failed: + cloudlog.event("athena.uploadFilesToUrls.failed", failed=failed, error=True) resp["failed"] = failed return resp From 71ad5a8deef595d3e0cb01d3e8a4d8ced1ae5085 Mon Sep 17 00:00:00 2001 From: Maxime Desroches Date: Wed, 24 Jul 2024 14:49:35 -0700 Subject: [PATCH 22/22] op.sh: general improvements (#33062) * color * format * dry * unset * venv * search for openpilot * linter * replay --- tools/op.sh | 106 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 25 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index bbc4ded445..111a06e81c 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -2,6 +2,8 @@ RED='\033[0;31m' GREEN='\033[0;32m' +UNDERLINE='\033[4m' +BOLD='\033[1m' NC='\033[0m' function op_first_install() { @@ -12,7 +14,7 @@ function op_first_install() { if [ "$(uname)" == "Darwin" ] && [ $SHELL == "/bin/bash" ]; then RC_FILE="$HOME/.bash_profile" fi - printf "\nalias op='source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/op.sh" \"\$@\"'\n" >> $RC_FILE + op_run_command printf "\nalias op='source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/op.sh" \"\$@\"'\n" >> $RC_FILE echo -e " ↳ [${GREEN}✔${NC}] op installed successfully. Open a new shell to use it.\n" ) @@ -21,14 +23,25 @@ function op_first_install() { # be default, assume openpilot dir is in current directory OPENPILOT_ROOT=$(pwd) function op_check_openpilot_dir() { - (set -e + while [[ "$OPENPILOT_ROOT" != '/' ]]; + do + if find "$OPENPILOT_ROOT/launch_openpilot.sh" -maxdepth 1 -mindepth 1 &> /dev/null; then + return 0 + fi + OPENPILOT_ROOT="$(readlink -f "$OPENPILOT_ROOT/"..)" + done - if [ ! -f "$OPENPILOT_ROOT/launch_openpilot.sh" ]; then - echo "openpilot directory not found!" - return 1 - fi + echo "openpilot directory not found! Make sure that you are inside openpilot" + echo "directory or specify one with the --dir option!" + return 1 +} - ) +function op_run_command() { + CMD="$@" + echo -e "${BOLD}Running:${NC} $CMD" + if [[ -z "$DRY" ]]; then + $CMD + fi } function op_check_git() { @@ -118,7 +131,7 @@ function op_check_python() { # this must be run in the same shell as the user calling "op" function op_venv() { op_check_openpilot_dir || return 1 - source $OPENPILOT_ROOT/.venv/bin/activate || (echo -e "\nCan't activate venv. Have you ran 'op install' ?" && return 1) + op_run_command source $OPENPILOT_ROOT/.venv/bin/activate || (echo -e "\nCan't activate venv. Have you ran 'op install' ?" && return 1) } function op_check() { @@ -138,7 +151,8 @@ function op_run() { op_venv cd $OPENPILOT_ROOT - $OPENPILOT_ROOT/launch_openpilot.sh + + op_run_command $OPENPILOT_ROOT/launch_openpilot.sh ) } @@ -170,7 +184,7 @@ function op_build() { op_venv cd $OPENPILOT_ROOT - scons $@ || echo -e "\nBuild failed. Have you ran 'op install' ?" + op_run_command scons $@ ) } @@ -181,7 +195,28 @@ function op_juggle() { op_venv cd $OPENPILOT_ROOT - $OPENPILOT_ROOT/tools/plotjuggler/juggle.py $@ + op_run_command $OPENPILOT_ROOT/tools/plotjuggler/juggle.py $@ + + ) +} + +function op_linter() { + (set -e + + op_venv + cd $OPENPILOT_ROOT + + op_run_command pre-commit run --all $@ + + ) +} + +function op_replay() { + (set -e + op_check_openpilot_dir + cd $OPENPILOT_ROOT + + op_run_command $OPENPILOT_ROOT/tools/replay/replay $@ ) } @@ -189,24 +224,37 @@ function op_juggle() { function op_default() { echo "An openpilot helper" echo "" - echo -e "\e[4mUsage:\e[0m op [OPTIONS] " + echo -e "${BOLD}${UNDERLINE}Description:${NC}" + echo " op is your entry point for all things related to openpilot development." + echo " op is only a wrapper for scripts, tools and commands already existing." + echo " op will always show you what it will run on your system." + echo "" + echo " op will try to find your openpilot directory in the following order:" + echo " 1: use the directory specified with the --dir option" + echo " 2: use the current working directory" + echo " 3: go up the file tree non-recursively" + echo "" + echo -e "${BOLD}${UNDERLINE}Usage:${NC} op [OPTIONS] " echo "" - echo -e "\e[4mCommands:\e[0m" - echo " venv Activate the virtual environment" - echo " check Check system requirements (git, os, python) to start using openpilot" - echo " install Install requirements to use openpilot" - echo " build Build openpilot" - echo " run Run openpilot" - echo " juggle Run Plotjuggler" - echo " help Show this message" - echo " --install Install this tool system wide" + echo -e "${BOLD}${UNDERLINE}Commands:${NC}" + echo -e " ${BOLD}venv${NC} Activate the virtual environment" + echo -e " ${BOLD}check${NC} Check system requirements (git, os, python) to start using openpilot" + echo -e " ${BOLD}install${NC} Install requirements to use openpilot" + echo -e " ${BOLD}build${NC} Build openpilot" + echo -e " ${BOLD}run${NC} Run openpilot" + echo -e " ${BOLD}juggle${NC} Run Plotjuggler" + echo -e " ${BOLD}replay${NC} Run replay" + echo -e " ${BOLD}linter${NC} Run all the pre-commit checks" + echo -e " ${BOLD}help${NC} Show this message" + echo -e " ${BOLD}--install${NC} Install this tool system wide" echo "" - echo -e "\e[4mOptions:\e[0m" - echo " -d, --dir" + echo -e "${BOLD}${UNDERLINE}Options:${NC}" + echo -e " ${BOLD}-d, --dir${NC}" echo " Specify the openpilot directory you want to use" - echo " Default to the current working directory" + echo -e " ${BOLD}--dry${NC}" + echo " Don't actually run anything, just print what would be" echo "" - echo -e "\e[4mExamples:\e[0m" + echo -e "${BOLD}${UNDERLINE}Examples:${NC}" echo " op --dir /tmp/openpilot check" echo " Run the check command on openpilot located in /tmp/openpilot" echo "" @@ -224,6 +272,7 @@ function _op() { # parse Options case $1 in -d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;; + --dry ) shift 1; DRY="1" ;; esac # parse Commands @@ -234,6 +283,8 @@ function _op() { build ) shift 1; op_build "$@" ;; run ) shift 1; op_run "$@" ;; juggle ) shift 1; op_juggle "$@" ;; + linter ) shift 1; op_linter "$@" ;; + replay ) shift 1; op_replay "$@" ;; --install ) shift 1; op_first_install "$@" ;; * ) op_default "$@" ;; esac @@ -255,3 +306,8 @@ unset -f op_check_python unset -f op_check_os unset -f op_first_install unset -f op_default +unset -f op_run_command +unset -f op_linter +unset -f op_replay +unset DRY +unset OPENPILOT_ROOT