FrogPilot 0.9.7

This commit is contained in:
James 2025-11-01 12:00:00 -07:00
parent 0fb01b95a7
commit 2d115c7882
2728 changed files with 844217 additions and 29129 deletions

277
.github/workflows/compile_frogpilot.yaml vendored Normal file
View File

@ -0,0 +1,277 @@
name: Compile FrogPilot
on:
workflow_dispatch:
inputs:
runner:
description: "Select the runner"
required: true
default: "c3"
type: choice
options:
- c3
- c3x
not_vetted:
description: "This branch is not vetted"
required: false
default: "false"
type: boolean
publish_frogpilot:
description: "Push to FrogPilot"
required: false
default: "false"
type: boolean
publish_staging:
description: "Push to FrogPilot-Staging"
required: false
default: "false"
type: boolean
publish_testing:
description: "Push to FrogPilot-Testing"
required: false
default: "false"
type: boolean
publish_custom_branch:
description: "Push to custom branch:"
required: false
default: ""
type: string
update_translations:
description: "Update missing/outdated translations"
required: false
default: "false"
type: boolean
vet_existing_translations:
description: "Vet existing translations"
required: false
default: "false"
type: boolean
env:
BASEDIR: "${{ github.workspace }}"
BUILD_DIR: /data/openpilot
OPENAI_API_KEY: "${{ secrets.OPENAI_API_KEY }}"
jobs:
get_branch:
runs-on:
- self-hosted
- ${{ github.event.inputs.runner }}
outputs:
branch: ${{ steps.get_branch.outputs.branch }}
python_version: ${{ steps.get_python_version.outputs.python_version }}
steps:
- name: Determine Current Branch on Runner
id: get_branch
run: |
cd $BUILD_DIR
BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
- name: Get Python Version from Runner
id: get_python_version
run: |
PYTHON_VERSION=$(tr -d '[:space:]' < "$BUILD_DIR/.python-version")
echo "python_version=$PYTHON_VERSION" >> $GITHUB_OUTPUT
translate:
if: inputs.update_translations
needs: get_branch
runs-on: ubuntu-latest
steps:
- name: Configure Git Identity
run: |
git config --global user.name "James"
git config --global user.email "91348155+FrogAi@users.noreply.github.com"
- name: Checkout Required Files
uses: actions/checkout@v4
with:
ref: ${{ needs.get_branch.outputs.branch }}
sparse-checkout: |
frogpilot/ui/
selfdrive/controls/lib/alerts_offroad.json
selfdrive/ui/
selfdrive/ui/update_translations.py
selfdrive/ui/translations/
selfdrive/ui/translations/auto_translate.py
- name: Set Up Python
uses: actions/setup-python@v4
with:
python-version: "${{ needs.get_branch.outputs.python_version }}"
- name: Install Dependencies
run: pip install requests
- name: Install Qt5 Tools
run: sudo apt update && sudo apt install -y qttools5-dev-tools
- name: Update Translations
run: python selfdrive/ui/update_translations.py --vanish
- name: Update Missing Translations
continue-on-error: true
run: python selfdrive/ui/translations/auto_translate.py --all-files
timeout-minutes: 300
- name: Vet Existing Translations
if: github.event.inputs.vet_existing_translations == 'true'
continue-on-error: true
run: python selfdrive/ui/translations/auto_translate.py --all-files --vet-translations
timeout-minutes: 300
- name: Commit and Push Translation Updates
run: |
if git diff --quiet selfdrive/ui/translations/*.ts; then
echo "No translation updates detected."
exit 0
fi
git fetch --unshallow origin ${{ needs.get_branch.outputs.branch }}
git checkout ${{ needs.get_branch.outputs.branch }}
git add selfdrive/ui/translations/*.ts
git commit --amend --no-edit
git push --force origin ${{ needs.get_branch.outputs.branch }}
build_and_push:
needs:
- get_branch
- translate
if: always()
runs-on:
- self-hosted
- ${{ github.event.inputs.runner }}
permissions:
contents: write
defaults:
run:
working-directory: ${{ env.BUILD_DIR }}
steps:
- name: Configure Git Identity
run: |
git config --global http.postBuffer 104857600
git config --global user.name "James"
git config --global user.email "91348155+FrogAi@users.noreply.github.com"
- name: Update Repository
run: |
git remote set-url origin https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/FrogAi/FrogPilot.git
if [ "${{ github.event.inputs.update_translations }}" = "true" ]; then
git fetch origin ${{ needs.get_branch.outputs.branch }}
git reset --hard FETCH_HEAD
fi
- name: Take Ownership of Build
run: |
sudo chown -R $(whoami):$(whoami) .
- name: Finalize Build
run: |
rm -f .clang-tidy
rm -f .dockerignore
rm -f .editorconfig
rm -f .gitattributes
rm -f .gitmodules
rm -f .lfsconfig
rm -f .overlay_init
rm -f .pre-commit-config.yaml
rm -f .sconsign.dblite
rm -f codecov.yml
rm -f conftest.py
rm -f poetry.lock
rm -f pyproject.toml
rm -f teleoprtc
rm -f Dockerfile.openpilot
rm -f Dockerfile.openpilot_base
rm -f Jenkinsfile
rm -f panda/board/obj/.placeholder
rm -f panda/board/obj/bootstub.panda.elf
rm -f panda/board/obj/bootstub.panda_h7.elf
rm -f panda/board/obj/panda.bin
rm -f panda/board/obj/panda.elf
rm -f panda/board/obj/panda_h7.bin
rm -f panda/board/obj/panda_h7.elf
rm -f panda/board/obj/version
find . -name '*.a' -delete
find . -name '*.o' -delete
find . -name '*.onnx' -delete
find . -name '*.os' -delete
find . -name '*.pyc' -delete
find . -name 'moc_*' -delete
rm -rf .devcontainer/
rm -rf .vscode/
rm -rf body/
rm -rf opendbc/generator/
rm -rf release/
rm -rf scripts/
rm -rf site_scons/
rm -rf teleoprtc_repo/
find .github -mindepth 1 -maxdepth 1 ! -name 'workflows' -exec rm -rf {} +
find .github/workflows -mindepth 1 ! \( \
-type f \( \
-name 'compile_frogpilot.yaml' -o \
-name 'review_pull_request.yaml' -o \
-name 'schedule_update.yaml' -o \
-name 'update_pr_branch.yaml' -o \
-name 'update_release_branch.yaml' -o \
-name 'update_tinygrad.yaml' \
\) \
\) -exec rm -rf {} +
find panda/board/jungle -type f ! -name '__init__.py' -delete
find panda/board/jungle -type d -empty -delete
find third_party/ -name '*x86*' -exec rm -rf {} +
find third_party/ -name '*Darwin*' -exec rm -rf {} +
find tools/ -mindepth 1 -maxdepth 1 ! \( -name '__init__.py' -o -name 'bodyteleop' -o -name 'lib' -o -name 'scripts' \) -exec rm -rf {} +
find . -name 'SConstruct' -delete
find . -name 'SConscript' -delete
find . -type d \( -iname "debug" -o -iname "test" -o -iname "tests" \) -exec rm -rf {} +
find . -type d -empty ! -path "./.git*" -delete
find . -type d -name '__pycache__' -exec rm -rf {} +
find . -type f -regex '.*matlab.*\.md' -delete
touch prebuilt
if [ "${{ github.event.inputs.not_vetted }}" = "true" ]; then
touch not_vetted
fi
- name: Add the update_date file
if: github.event.inputs.publish_staging == 'true'
run: |
curl -fLsS https://raw.githubusercontent.com/FrogAi/FrogPilot/FrogPilot-Staging/.github/update_date -o .github/update_date || echo "No update_date found, skipping."
- name: Commit Build
run: |
git add -f .
git commit -m "Compile FrogPilot"
git push --force origin HEAD
if [ "${{ github.event.inputs.publish_frogpilot }}" = "true" ]; then
git push --force origin HEAD:"FrogPilot"
fi
if [ "${{ github.event.inputs.publish_staging }}" = "true" ]; then
git push --force origin HEAD:"FrogPilot-Staging"
fi
if [ "${{ github.event.inputs.publish_testing }}" = "true" ]; then
git push --force origin HEAD:"FrogPilot-Testing"
fi
if [ -n "${{ github.event.inputs.publish_custom_branch }}" ]; then
git push --force origin HEAD:"${{ github.event.inputs.publish_custom_branch }}"
fi

View File

@ -0,0 +1,34 @@
name: Review Pull Request
on:
pull_request_target:
types: [opened, reopened]
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
jobs:
pr_check:
runs-on: ubuntu-latest
steps:
- name: Exit If PR Opened by FrogAi
if: ${{ github.actor == 'FrogAi' }}
run: |
echo PR opened or reopened by FrogAi. No action needed.
exit 0
- name: Close PR for Invalid Target Branch
if: ${{ github.base_ref != 'MAKE-PRS-HERE' }}
run: |
gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
-f body="Please submit your pull request to the \"MAKE-PRS-HERE\" branch."
gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} \
-X PATCH \
-f state="closed"
- name: Acknowledge PR for Valid Target Branch
if: ${{ github.base_ref == 'MAKE-PRS-HERE' }}
run: |
gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
-f body="Thank you for your PR! If you're not already in the FrogPilot Discord, [feel free to join](https://discord.FrogPilot.download) and let me know you've opened a PR!"

57
.github/workflows/schedule_update.yaml vendored Normal file
View File

@ -0,0 +1,57 @@
name: Schedule FrogPilot Update
on:
workflow_dispatch:
inputs:
scheduled_date:
description: "Enter the date to update the \"FrogPilot\" branch (YYYY-MM-DD)"
required: true
env:
BRANCH: FrogPilot-Staging
jobs:
schedule-update:
runs-on: ubuntu-latest
steps:
- name: Configure Git Identity
run: |
git config --global user.name "James"
git config --global user.email "91348155+FrogAi@users.noreply.github.com"
- name: Checkout ${{ env.BRANCH }}
uses: actions/checkout@v3
with:
ref: ${{ env.BRANCH }}
fetch-depth: 3
- name: Schedule Update for ${{ github.event.inputs.scheduled_date }}
run: |
echo "${{ github.event.inputs.scheduled_date }}" > .github/update_date
git add .github/update_date
- name: Get Target Commit (Second Most Recent)
id: get_target
run: |
TARGET_COMMIT=$(git rev-parse HEAD~1)
AUTHOR_DATE=$(git show -s --format=%aD "$TARGET_COMMIT")
COMMITTER_DATE=$(git show -s --format=%cD "$TARGET_COMMIT")
echo "AUTHOR_DATE=$AUTHOR_DATE" >> $GITHUB_ENV
echo "COMMITTER_DATE=$COMMITTER_DATE" >> $GITHUB_ENV
echo "TARGET_COMMIT=$TARGET_COMMIT" >> $GITHUB_ENV
- name: Create Fixup Commit for ${{ env.TARGET_COMMIT }}
run: git commit --fixup="${{ env.TARGET_COMMIT }}"
- name: Autosquash Fixup into Target Commit
run: |
GIT_SEQUENCE_EDITOR=: git rebase --autosquash -i HEAD~3
- name: Restore Timestamps on Final Two Commits
run: |
git rebase --exec "GIT_COMMITTER_DATE='${{ env.COMMITTER_DATE }}' git commit --amend --no-edit --date='${{ env.AUTHOR_DATE }}'" HEAD~2
- name: Push Updated ${{ env.BRANCH }} Branch
run: git push origin "${{ env.BRANCH }}" --force-with-lease

88
.github/workflows/update_pr_branch.yaml vendored Normal file
View File

@ -0,0 +1,88 @@
name: Update MAKE-PRS-HERE
on:
push:
branches:
- FrogPilot-Staging
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
SOURCE_BRANCH: FrogPilot-Staging
TARGET_BRANCH: MAKE-PRS-HERE
jobs:
update_branch:
runs-on: ubuntu-latest
steps:
- name: Configure Git Identity
run: |
git config --global user.name "James"
git config --global user.email "91348155+FrogAi@users.noreply.github.com"
- name: Checkout ${{ env.SOURCE_BRANCH }}
uses: actions/checkout@v3
with:
persist-credentials: false
fetch-depth: 0
ref: ${{ env.SOURCE_BRANCH }}
- name: Find "Compile FrogPilot" Commit in ${{ env.SOURCE_BRANCH }}
id: find_parent
run: |
COMMIT=$(git rev-list HEAD -n 1 --grep="Compile FrogPilot")
[ -z "$COMMIT" ] && echo "Compile commit not found." >&2 && exit 1
PARENT=$(git rev-list --parents -n 1 "$COMMIT" | awk '{print $2}')
[ -z "$PARENT" ] && echo "Parent commit not found." >&2 && exit 1
echo "parent_commit=$PARENT" >> "$GITHUB_OUTPUT"
echo "compile_commit=$COMMIT" >> "$GITHUB_OUTPUT"
- name: Fetch and Checkout ${{ env.TARGET_BRANCH }}
run: |
git fetch origin "${{ env.TARGET_BRANCH }}"
git checkout "${{ env.TARGET_BRANCH }}"
- name: Clean ${{ env.TARGET_BRANCH }} and Apply Updates from ${{ env.SOURCE_BRANCH }}
run: |
git rm -r --ignore-unmatch .
git clean -fdx
git checkout "${{ steps.find_parent.outputs.parent_commit }}" -- .
COMPILE_COMMIT="${{ steps.find_parent.outputs.compile_commit }}"
SOURCE_HEAD=$(git rev-parse "origin/${{ env.SOURCE_BRANCH }}")
[ "$COMPILE_COMMIT" != "$SOURCE_HEAD" ] && git cherry-pick --no-commit "${COMPILE_COMMIT}".."$SOURCE_HEAD"
rm -f .github/update_date
git add --all
- name: Commit and Push to ${{ env.TARGET_BRANCH }}
run: |
if git diff --staged --quiet; then
echo "Working tree is clean. No changes to commit."
exit 0
fi
TZ_VALUE="America/Phoenix"
day=$(TZ="$TZ_VALUE" date +"%-d")
month=$(TZ="$TZ_VALUE" date +"%B")
year=$(TZ="$TZ_VALUE" date +"%Y")
case $day in
11|12|13) s=th ;;
*) case $((day % 10)) in 1) s=st ;; 2) s=nd ;; 3) s=rd ;; *) s=th ;; esac ;;
esac
commit_message="${month} ${day}${s}, ${year} Update"
if git log -1 --pretty=%s | grep -q "$commit_message"; then
git commit --amend --no-edit
else
git commit -m "$commit_message"
fi
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}
git push origin "${{ env.TARGET_BRANCH }}" --force

View File

@ -0,0 +1,131 @@
name: Update FrogPilot Branch
on:
schedule:
- cron: "0 18 * * 6"
env:
GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
BRANCH_FROGPILOT: FrogPilot
BRANCH_PREVIOUS: FrogPilot-Previous
BRANCH_STAGING: FrogPilot-Staging
TZ: America/Phoenix
UPDATE_FILE: .github/update_date
jobs:
check_update:
runs-on: ubuntu-latest
outputs:
update_due: ${{ steps.check_update.outputs.update_due }}
scheduled_date: ${{ steps.check_update.outputs.scheduled_date }}
steps:
- name: Download the "update_date" File
id: download_update
run: |
curl -fLsS "https://raw.githubusercontent.com/FrogAi/FrogPilot/${{ env.BRANCH_STAGING }}/${{ env.UPDATE_FILE }}" -o update_date || touch update_date_missing
- name: Check If Update Is Due
id: check_update
run: |
if [ -f update_date_missing ]; then
echo "update_due=false" >> "$GITHUB_OUTPUT"
exit 0
fi
SCHEDULED_DATE=$(cat update_date)
CURRENT_DATE=$(TZ="${{ env.TZ }}" date +%F)
if [ "$SCHEDULED_DATE" != "$CURRENT_DATE" ]; then
echo "update_due=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "update_due=true" >> "$GITHUB_OUTPUT"
echo "scheduled_date=$SCHEDULED_DATE" >> "$GITHUB_OUTPUT"
update_branch:
needs: check_update
if: ${{ needs.check_update.outputs.update_due == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Configure Git Identity
run: |
git config --global user.name "James"
git config --global user.email "91348155+FrogAi@users.noreply.github.com"
- name: Checkout ${{ env.BRANCH_STAGING }}
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ env.BRANCH_STAGING }}
- name: Authenticate with GITHUB_TOKEN
run: |
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}
- name: Update README Date and Remove update file
run: |
DAY=$(TZ="${{ env.TZ }}" date +'%d' | sed 's/^0//')
case "$DAY" in
1|21|31) SUFFIX="st" ;;
2|22) SUFFIX="nd" ;;
3|23) SUFFIX="rd" ;;
*) SUFFIX="th" ;;
esac
MONTH=$(TZ="${{ env.TZ }}" date +'%B')
YEAR=$(TZ="${{ env.TZ }}" date +'%Y')
DATE="${MONTH} ${DAY}${SUFFIX}, ${YEAR}"
DATE_ESCAPED=$(printf '%s' "$DATE" | sed -E 's/ /%20/g; s/,/%2C/g')
sed -i -E "s|(Last%20Updated-)[^-)]*|\1${DATE_ESCAPED}|g" README.md
git add README.md
git rm -f "${{ env.UPDATE_FILE }}"
git commit -m "Updated README date to ${DATE}"
- name: Squash Commits
run: |
COMMIT_MSG=$(git log -1 --pretty=%B HEAD~1)
git reset --soft HEAD~2
git commit -m "$COMMIT_MSG"
- name: Rewrite Commit Dates to Noon ${{ env.TZ }}
run: |
COMMIT_DATETIME="${{ needs.check_update.outputs.scheduled_date }} 12:00"
COMMIT_PHX=$(TZ="${{ env.TZ }}" date -d "$COMMIT_DATETIME" +"%Y-%m-%dT%H:%M:%S %z")
git filter-branch --env-filter "export GIT_AUTHOR_DATE='$COMMIT_PHX'; export GIT_COMMITTER_DATE='$COMMIT_PHX'" "${{ env.BRANCH_STAGING }}"
- name: Fetch ${{ env.BRANCH_PREVIOUS }} and ${{ env.BRANCH_FROGPILOT }}
run: |
git fetch origin ${{ env.BRANCH_PREVIOUS }} ${{ env.BRANCH_FROGPILOT }}
- name: Wait Until Noon ${{ env.TZ }}
run: |
NOW=$(TZ="${{ env.TZ }}" date +%s)
TARGET=$(TZ="${{ env.TZ }}" date -d "12:00" +%s)
[ "$NOW" -lt "$TARGET" ] && sleep $((TARGET - NOW))
- name: Push ${{ env.BRANCH_STAGING }}
run: |
git push origin "${{ env.BRANCH_STAGING }}" --force
- name: Reset ${{ env.BRANCH_PREVIOUS }} to Match ${{ env.BRANCH_FROGPILOT }}
run: |
git switch "${{ env.BRANCH_PREVIOUS }}"
git reset --hard "origin/${{ env.BRANCH_FROGPILOT }}"
git push origin "${{ env.BRANCH_PREVIOUS }}" --force
- name: Reset ${{ env.BRANCH_FROGPILOT }} to Match ${{ env.BRANCH_STAGING }}
run: |
git switch "${{ env.BRANCH_FROGPILOT }}"
git reset --hard "origin/${{ env.BRANCH_STAGING }}"
git push origin "${{ env.BRANCH_FROGPILOT }}" --force

79
.github/workflows/update_tinygrad.yaml vendored Normal file
View File

@ -0,0 +1,79 @@
name: Update Tinygrad
on:
workflow_dispatch:
inputs:
runner:
description: "Select the runner"
required: true
default: "c3"
type: choice
options:
- c3
- c3x
jobs:
update_tinygrad:
name: Update Tinygrad
runs-on:
- self-hosted
- ${{ github.event.inputs.runner }}
steps:
- name: Get version
id: get_version
run: |
VERSION=$(grep -oP '^VERSION\s*=\s*"\K[^"]+' /data/openpilot/frogpilot/assets/model_manager.py)
echo "VERSION=$VERSION"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Clone GitLab repo
env:
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
run: |
rm -rf /data/tmp/frogpilot_tinygrad
mkdir -p /data/tmp/frogpilot_tinygrad
cd /data/tmp/frogpilot_tinygrad
git clone --depth 1 --branch Tinygrad "https://oauth2:${GITLAB_TOKEN}@gitlab.com/FrogAi/FrogPilot-Resources.git"
- name: Create Tinygrad Archive
run: |
set -euo pipefail
cd /data/openpilot
ARCHIVE_DIR="/data/tmp/frogpilot_tinygrad/FrogPilot-Resources"
ARCHIVE_NAME="Tinygrad_${{ steps.get_version.outputs.version }}.tar.gz"
TMPDIR="$(mktemp -d)"
touch "$TMPDIR/SConscript"
tar -czf "$ARCHIVE_NAME" \
--exclude="*.a" \
--exclude="*.o" \
--exclude="*.onnx" \
--exclude="*__pycache__*" \
--exclude="*tests*" \
--exclude="frogpilot/tinygrad_modeld/SConscript" \
frogpilot/tinygrad_modeld tinygrad_repo \
-C "$TMPDIR" \
--transform 's|^SConscript$|frogpilot/tinygrad_modeld/SConscript|' \
SConscript
mv "$ARCHIVE_NAME" "$ARCHIVE_DIR/"
rm -rf "$TMPDIR"
- name: Push updated Tinygrad
run: |
cd /data/tmp/frogpilot_tinygrad/FrogPilot-Resources
git config user.name "James"
git config user.email "91348155+FrogAi@users.noreply.github.com"
git add Tinygrad_*.tar.gz
git commit -m "Updated Tinygrad: ${{ steps.get_version.outputs.version }}" || echo "No changes to commit"
git push origin Tinygrad
- name: Cleanup temporary files
run: |
rm -rf /data/tmp/frogpilot_tinygrad

258
README.md
View File

@ -1,9 +1,33 @@
[![openpilot on the comma 3X](https://github.com/commaai/openpilot/assets/8762862/f09e6d29-db2d-4179-80c2-51e8d92bdb5c)](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 300+ 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)`
[![openpilot tests](https://github.com/commaai/openpilot/actions/workflows/selfdrive_tests.yaml/badge.svg)](https://github.com/commaai/openpilot/actions/workflows/selfdrive_tests.yaml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![X Follow](https://img.shields.io/twitter/follow/comma_ai)](https://x.com/comma_ai)
[![Discord](https://img.shields.io/discord/469524606043160576)](https://discord.comma.ai)
</div>
<table>
<tr>
@ -13,68 +37,216 @@ What is openpilot?
</tr>
</table>
To start using openpilot in a car
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.
To start developing openpilot
------
openpilot is developed by [comma](https://comma.ai/) and by users like you. We welcome both pull requests and issues on [GitHub](http://github.com/commaai/openpilot).
<div align="center" style="text-align: center;">
* Join the [community Discord](https://discord.comma.ai)
* Check out [the contributing docs](docs/CONTRIBUTING.md)
* Check out the [openpilot tools](tools/)
* Read about the [development workflow](docs/WORKFLOW.md)
* Code documentation lives at https://docs.comma.ai
* Information about running openpilot lives on the [community wiki](https://github.com/commaai/openpilot/wiki)
<h1>FrogPilot 🐸</h1>
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.
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/FrogAi/FrogPilot)
[![Discord](https://img.shields.io/discord/1137853399715549214?label=Discord)](https://discord.frogpilot.download)
[![Last Updated](https://img.shields.io/badge/Last%20Updated-October%2018th%2C%202025-brightgreen)](https://github.com/FrogAi/FrogPilot/releases/latest)
[![Wiki](https://img.shields.io/badge/Wiki-FrogPilot-blue?logo=wiki)](https://frogpilot.wiki.gg/)
Safety and Testing
----
</div>
* openpilot observes [ISO26262](https://en.wikipedia.org/wiki/ISO_26262) guidelines, see [SAFETY.md](docs/SAFETY.md) for more details.
* openpilot has software-in-the-loop [tests](.github/workflows/selfdrive_tests.yaml) that run on every commit.
* The code enforcing the safety model lives in panda and is written in C, see [code rigor](https://github.com/commaai/panda#code-rigor) for more details.
* panda has software-in-the-loop [safety tests](https://github.com/commaai/panda/tree/master/tests/safety).
* Internally, we have a hardware-in-the-loop Jenkins test suite that builds and unit tests the various processes.
* 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.
**FrogPilot** is a custom frog-themed fork of openpilot that embraces a collaborative, community-driven approach to push the project forward. It delivers bleeding-edge features and experimental improvements far ahead of official releases. As an unofficial and highly experimental version of openpilot, **FrogPilot** should always be used with caution!
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
openpilot vs **FrogPilot**
------
openpilot is released under the MIT license. Some parts of the software are released under other licenses as specified.
#### Community
| Feature | openpilot | **FrogPilot** |
|---------|:---------:|:---------:|
| A Welcoming Community | ❌ | ✅ |
| Erich / Primary Moderators / 🦇 | ✅ | ❌ |
Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and its directors, officers, employees, agents, stockholders, affiliates, subcontractors and customers from and against all allegations, claims, actions, suits, demands, damages, liabilities, obligations, losses, settlements, judgments, costs and expenses (including without limitation attorneys fees and costs) which arise out of, relate to or result from any use of this software by user.
#### Core Features
| Feature | openpilot | **FrogPilot** |
|---------|:---------:|:---------:|
| Always On Lateral (Steering) | ❌ | ✅ |
| Blind Spot Integration | ✅ | ✅ |
| Conditional Experimental Mode | ❌ | ✅ |
| Custom Themes | ❌ | ✅ |
| Driver Monitoring | ✅ | ✅ |
| Driving Model Selector | ❌ | ✅ |
| Holiday Themes | ❌ | ✅ |
| Speed Limit Support | ❌ | ✅ |
| Weather Detection | ❌ | ✅ |
**THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT.
YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS.
NO WARRANTY EXPRESSED OR IMPLIED.**
#### Device & Hardware
| Feature | openpilot | **FrogPilot** |
|---------|:---------:|:---------:|
| Advanced Volume Controller | ❌ | ✅ |
| Automatic Version Backups | ❌ | ✅ |
| C3 Support | ❌ | ✅ |
| comma Pedal Support | ❌ | ✅ |
| High Quality Recordings | ❌ | ✅ |
| SDSU Support | ❌ | ✅ |
| ZSS Support | ❌ | ✅ |
#### Gas/Brake
| Feature | openpilot | **FrogPilot** |
|---------|:---------:|:---------:|
| Adaptive Cruise Control (ACC) | ✅ | ✅ |
| Advanced Live Tuning | ❌ | ✅ |
| Custom Following Distances | ❌ | ✅ |
| Faster Human-Like Acceleration | ❌ | ✅ |
| Human-Like Speed Control in Curves | ❌ | ✅ |
| Smoother Human-Like Braking | ❌ | ✅ |
#### Steering
| Feature | openpilot | **FrogPilot** |
|---------|:---------:|:---------:|
| Advanced Live Tuning | ❌ | ✅ |
| Automatic Lane Changes | ❌ | ✅ |
| Increased Steering Torque* | ❌ | ✅ |
| Lane Centering (LKAS) | ✅ | ✅ |
| Lane Change Assist | ✅ | ✅ |
*Select vehicles only
And much much more!
🌟 Highlight Features
------
### 🚗 Always On Lateral (AOL)
With **"Always On Lateral"**, lane-centering stays active whenever cruise control is on, even when you press the accelerator or brake. This means steering assist won't cut out during manual speed adjustments giving you continuous support through curves, traffic, or mountain roads!
---
<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>
### 🧠 Conditional Experimental Mode (CEM)
![openpilot tests](https://github.com/commaai/openpilot/actions/workflows/selfdrive_tests.yaml/badge.svg)
[![codecov](https://codecov.io/gh/commaai/openpilot/branch/master/graph/badge.svg)](https://codecov.io/gh/commaai/openpilot)
**["Experimental Mode"](https://blog.comma.ai/090release/#experimental-mode)** lets openpilot drive at the speed it thinks a human would to allow slowing for curves, stopping at stoplights/stop signs, and adapting to traffic. This makes it powerful in complex scenarios, but it's still, well, "experimental" and less predictable than **"Chill Mode"**. But **"Conditional Experimental Mode"** gives you the best of both worlds by automatically switching between **"Chill Mode"** for steady cruising and **"Experimental Mode"** for more advanced situations to help fully automate your driving experience!
**"Conditional Experimental Mode"** switches into **"Experimental Mode"** when conditions like these are met:
- Approaching curves and turns
- Detecting slower or stopped lead vehicles
- Driving below a set speed
- Predicting an upcoming stop (e.g. stoplight or stop sign)
Once conditions clear it returns to **"Chill Mode"** for stability and predictability.
**Note: Stay attentive as "Experimental Mode" is an alpha feature and mistakes are expected!**
---
### 🎭 Driving Personalities
With **"Driving Personalities"**, you choose how the vehicle behaves with four adjustable profiles:
- **Traffic:** Catered towards stop-and-go traffic by minimizing gaps and delays
- **Aggressive:** Aimed to provide tighter following distances and quicker reactions
- **Standard:** Useful for a balanced, all-purpose driving
- **Relaxed:** A smoother driving experience with larger following distance gaps
Each profile can be fine-tuned to change the desired following distance, acceleration, and braking style letting you shape **FrogPilot**'s behavior to match your own driving preferences! Profiles can be switched instantly using the following distance button on the steering wheel, while **"Traffic Mode"** can be enabled by simply holding down the following distance button.
---
### 📏 Speed Limit Controller (SLC)
With **"Speed Limit Controller"**, **FrogPilot** automatically adapts to the road's posted speed using information from downloaded **["OpenStreetMap"](https://www.openstreetmap.org)** maps, online **["Mapbox"](https://www.mapbox.com)** data, and the vehicle's dashboard (if supported).
Offsets let you fine-tune how closely **FrogPilot** follows posted limits across different speed ranges allowing you to cruise slightly above or below for a more natural driving experience. If no speed limit is available, you can choose whether **FrogPilot** drives at the set speed, falls back to the last known speed limit, or uses **"Experimental Mode"** to estimate one with the driving model.
Maps can be downloaded directly in settings and updated automatically on a schedule ensuring your device always has the latest speed limits!
**Note: Speed limits are only as accurate as the available speed limit data. Always stay attentive and adjust your speed when necessary!**
---
### 🎨 Themes
With **"Themes"**, you can personalize **FrogPilot**'s driving screen to make it uniquely yours! Choose from:
- **Color Schemes**
- **Icon Packs**
- **Sound Packs**
- **Turn Signal Animations**
- **Steering Wheel Icons**
Enjoy pre-existing **FrogPilot** and seasonal holiday themes, or you can create your own with the **"Theme Maker"** and even share them with the community! For extra fun, enable features like the Mario Kartstyle **"Rainbow Path"** or **"Random Events"** that add playful visual effects while you drive!
---
And lots more! From safety enhancements to personalization options, **FrogPilot** continues to evolve with features that put you in control. Check it out today for yourself!
---
🔧 Branches
------
| Branch | Install&nbsp;URL | Description | Recommended&nbsp;For |
|----------------------------|---------------------------|--------------------------------------------------------|--------------------------|
| FrogPilot | frogpilot.download | The main release branch. | Everyone |
| FrogPilot&#8209;Staging | staging.frogpilot.download| Beta branch with upcoming features. Expect bugs! | Early&nbsp;Adopters |
| FrogPilot&#8209;Testing | testing.frogpilot.download| Alpha branch with bleeding-edge features. Breaks often!| Advanced&nbsp;Testers |
| FrogPilot&#8209;Development| No :) | Active development branch. Don't use! | **FrogPilot**&nbsp;Developers|
| MAKE&#8209;PRS&#8209;HERE | No :) | Workspace for pull requests. Don't use! | Contributors |
🧰 How to Install
------
The easiest way to install **FrogPilot** is by entering this URL on the installation screen:
```
frogpilot.download
```
**DO NOT** install the **FrogPilot-Development** branch. I'm constantly breaking things on there, so unless you don't want to use **FrogPilot**, **NEVER** install it!
![](https://i.imgur.com/LTCqRqB.png)
🐞 Bug Reports / Feature Requests
------
If you run into bugs, issues, or have ideas for new features, please post about it on the **[FrogPilot Discord](https://discord.gg/frogpilot)**! Feedback helps improve **FrogPilot** and create a better experience for everyone!
To report a bug, please post it in [**#bug-reports**](https://discord.com/channels/1137853399715549214/1162100167110053888).
To request a feature, please post it in [**#feature-requests**](https://discord.com/channels/1137853399715549214/1160318669839147259).
Please include as much detail as possible! Photos, videos, log files, or anything that can help explain the issue or idea are very helpful!
I'll do my best to respond promptly, but not every request can be addressed right away. Your feedback is always appreciated and helps make **FrogPilot** the best it can be!
📋 Credits
------
* [Aidenir](https://github.com/Aidenir)
* [AlexandreSato](https://github.com/AlexandreSato)
* [cfranyota](https://github.com/cfranyota)
* [cydia2020](https://github.com/cydia2020)
* [dragonpilot-community](https://github.com/dragonpilot-community)
* [ErichMoraga](https://github.com/ErichMoraga)
* [garrettpall](https://github.com/garrettpall)
* [jakethesnake420](https://github.com/jakethesnake420)
* [jyoung8607](https://github.com/jyoung8607)
* [mike8643](https://github.com/mike8643)
* [neokii](https://github.com/neokii)
* [OPGM](https://github.com/opgm)
* [OPKR](https://github.com/openpilotkr)
* [pfeiferj](https://github.com/pfeiferj)
* [realfast](https://github.com/realfast)
* [syncword](https://github.com/syncword)
* [twilsonco](https://github.com/twilsonco)
Star History
------
[![Star History Chart](https://api.star-history.com/svg?repos=FrogAi/FrogPilot&type=Date)](https://www.star-history.com/#FrogAi/FrogPilot&Date)

View File

@ -84,6 +84,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
startup @75;
startupNoCar @76;
startupNoControl @77;
startupNoSecOcKey @121;
startupMaster @78;
startupNoFw @104;
fcw @79;
@ -117,9 +118,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
paramsdPermanentError @119;
actuatorsApiUnavailable @120;
# FrogPilot Events
pedalInterceptorNoBrake @134;
radarCanErrorDEPRECATED @15;
communityFeatureDisallowedDEPRECATED @62;
radarCommIssueDEPRECATED @67;
@ -507,6 +505,9 @@ struct CarParams {
wheelSpeedFactor @63 :Float32; # Multiplier on wheels speeds to computer actual speeds
secOcRequired @74 :Bool; # Car requires SecOC message authentication to operate
secOcKeyAvailable @75 :Bool; # Stored SecOC key loaded from params
struct SafetyConfig {
safetyModel @0 :SafetyModel;
safetyParam @3 :UInt16;
@ -531,6 +532,7 @@ struct CarParams {
useSteeringAngle @0 :Bool;
kp @1 :Float32;
ki @2 :Float32;
kd @8 : Float32;
friction @3 :Float32;
kf @4 :Float32;
steeringAngleDeadzoneDeg @5 :Float32;
@ -544,8 +546,8 @@ struct CarParams {
kiBP @2 :List(Float32);
kiV @3 :List(Float32);
kf @6 :Float32;
deadzoneBPDEPRECATED @4 :List(Float32);
deadzoneVDEPRECATED @5 :List(Float32);
deadzoneBP @4 :List(Float32);
deadzoneV @5 :List(Float32);
}
struct LateralINDITuning {

View File

@ -1,6 +1,8 @@
using Cxx = import "./include/c++.capnp";
$Cxx.namespace("cereal");
using Car = import "car.capnp";
@0xb526ba661d550a59;
# custom.capnp: a home for empty structs reserved for custom forks
@ -8,32 +10,235 @@ $Cxx.namespace("cereal");
# cereal, so use these if you want custom events in your fork.
# you can rename the struct, but don't change the identifier
struct CustomReserved0 @0x81c2f05a394cf4af {
struct FrogPilotCarControl {
hudControl @0 :HUDControl;
struct HUDControl {
audibleAlert @0 :AudibleAlert;
enum AudibleAlert {
none @0;
engage @1;
disengage @2;
refuse @3;
warningSoft @4;
warningImmediate @5;
prompt @6;
promptRepeat @7;
promptDistracted @8;
# Random Events
angry @9;
continued @10;
dejaVu @11;
doc @12;
fart @13;
firefox @14;
goat @15;
hal9000 @16;
mail @17;
nessie @18;
noice @19;
startup @20;
thisIsFine @21;
uwu @22;
}
}
}
struct CustomReserved1 @0xaedffd8f31e7b55d {
struct FrogPilotCarEvent @0x81c2f05a394cf4af {
name @0 :EventName;
enable @1 :Bool;
noEntry @2 :Bool;
warning @3 :Bool;
userDisable @4 :Bool;
softDisable @5 :Bool;
immediateDisable @6 :Bool;
preEnable @7 :Bool;
permanent @8 :Bool;
overrideLateral @10 :Bool;
overrideLongitudinal @9 :Bool;
enum EventName @0xaedffd8f31e7b55d {
blockUser @0;
customStartupAlert @1;
forcingStop @2;
goatSteerSaturated @3;
greenLight @4;
holidayActive @5;
laneChangeBlockedLoud @6;
leadDeparting @7;
noLaneAvailable @8;
openpilotCrashed @9;
pedalInterceptorNoBrake @10;
speedLimitChanged @11;
torqueNNLoad @12;
trafficModeActive @13;
trafficModeInactive @14;
turningLeft @15;
turningRight @16;
# Random Events
accel30 @17;
accel35 @18;
accel40 @19;
dejaVuCurve @20;
firefoxSteerSaturated @21;
hal9000 @22;
openpilotCrashedRandomEvent @23;
thisIsFineSteerSaturated @24;
toBeContinued @25;
vCruise69 @26;
yourFrogTriedToKillMe @27;
youveGotMail @28;
}
}
struct CustomReserved2 @0xf35cc4560bbf6ec2 {
struct FrogPilotCarParams @0xf35cc4560bbf6ec2 {
canUsePedal @0 :Bool;
canUseSDSU @1 :Bool;
fpFlags @2 :UInt32;
isHDA2 @3 :Bool;
openpilotLongitudinalControlDisabled @4 :Bool;
safetyConfigs @5 :List(SafetyConfig);
struct SafetyConfig {
safetyParam @0 :UInt16;
}
}
struct CustomReserved3 @0xda96579883444c35 {
struct FrogPilotCarState @0xda96579883444c35 {
accelPressed @0 :Bool;
alwaysOnLateralAllowed @1 :Bool;
alwaysOnLateralEnabled @2 :Bool;
brakeLights @3 :Bool;
dashboardSpeedLimit @4 :Float32;
decelPressed @5 :Bool;
distancePressed @6 :Bool;
distanceLongPressed @7 :Bool;
distanceVeryLongPressed @8 :Bool;
ecoGear @9 :Bool;
forceCoast @10 :Bool;
pauseLateral @11 :Bool;
pauseLongitudinal @12 :Bool;
sportGear @13 :Bool;
trafficModeEnabled @14 :Bool;
struct ButtonEvent {
enum Type {
lkas @0;
}
}
}
struct CustomReserved4 @0x80ae746ee2596b11 {
struct FrogPilotControlsState @0x80ae746ee2596b11 {
alertStatus @0 :AlertStatus;
alertText1 @1 :Text;
alertText2 @2 :Text;
alertSize @3 :AlertSize;
alertBlinkingRate @4 :Float32;
alertType @5 :Text;
alertSound @6 :Car.CarControl.HUDControl.AudibleAlert;
enum AlertSize {
none @0; # don't display the alert
small @1; # small box
mid @2; # mid screen
full @3; # full screen
}
struct CustomReserved5 @0xa5cd762cd951a455 {
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
frogpilot @3; # FrogPilot startup alert
}
}
struct CustomReserved6 @0xf98d843bfd7004a3 {
struct FrogPilotDeviceState @0xa5cd762cd951a455 {
freeSpace @0 :Int16;
usedSpace @1 :Int16;
}
struct CustomReserved7 @0xb86e6369214c01c8 {
struct FrogPilotModelDataV2 @0xf98d843bfd7004a3 {
turnDirection @0 :TurnDirection;
enum TurnDirection {
none @0;
turnLeft @1;
turnRight @2;
}
}
struct CustomReserved8 @0xf416ec09499d9d19 {
struct FrogPilotNavigation @0xf416ec09499d9d19 {
approachingIntersection @0 :Bool;
approachingTurn @1 :Bool;
navigationSpeedLimit @2 :Float32;
}
struct CustomReserved9 @0xa1680744031fdb2d {
struct FrogPilotPlan @0xa1680744031fdb2d {
accelerationJerk @0 :Float32;
accelerationJerkStock @1 :Float32;
cscControllingSpeed @2 :Bool;
cscSpeed @3 :Float32;
cscTraining @4 :Bool;
dangerJerk @5 :Float32;
desiredFollowDistance @6 :Int64;
experimentalMode @7 :Bool;
forcingStop @8 :Bool;
forcingStopLength @9 :Float32;
frogpilotEvents @10 :List(FrogPilotCarEvent);
increasedStoppedDistance @11 :Float32;
lateralCheck @12 :Bool;
laneWidthLeft @13 :Float32;
laneWidthRight @14 :Float32;
maxAcceleration @15 :Float32;
minAcceleration @16 :Float32;
redLight @17 :Bool;
roadCurvature @18 :Float32;
slcMapSpeedLimit @19 :Float32;
slcMapboxSpeedLimit @20 :Float32;
slcNextSpeedLimit @21 :Float32;
slcOverriddenSpeed @22 :Float32;
slcSpeedLimit @23 :Float32;
slcSpeedLimitOffset @24 :Float32;
slcSpeedLimitSource @25 :Text;
speedJerk @26 :Float32;
speedJerkStock @27 :Float32;
speedLimitChanged @28 :Bool;
tFollow @29 :Float32;
themeUpdated @30 :Bool;
togglesUpdated @31 :Bool;
trackingLead @32 :Bool;
unconfirmedSlcSpeedLimit @33 :Float32;
vCruise @34 :Float32;
}
struct FrogPilotRadarState @0xcb9fd56c7057593a {
leadLeft @0 :LeadData;
leadRight @1 :LeadData;
struct LeadData {
dRel @0 :Float32;
yRel @1 :Float32;
vRel @2 :Float32;
aRel @3 :Float32;
vLead @4 :Float32;
dPath @6 :Float32;
vLat @7 :Float32;
vLeadK @8 :Float32;
aLeadK @9 :Float32;
fcw @10 :Bool;
status @11 :Bool;
aLeadTau @12 :Float32;
modelProb @13 :Float32;
radar @14 :Bool;
radarTrackId @15 :Int32 = -1;
aLeadDEPRECATED @5 :Float32;
}
}

View File

@ -698,6 +698,7 @@ struct ControlsState @0x97ff69c53601abf1 {
personality @66 :LongitudinalPersonality;
longControlState @30 :Car.CarControl.Actuators.LongControlState;
vPid @2 :Float32;
vTargetLead @3 :Float32;
vCruise @22 :Float32; # actual set speed
vCruiseCluster @63 :Float32; # set speed to display in the UI
@ -865,7 +866,38 @@ struct ControlsState @0x97ff69c53601abf1 {
canMonoTimesDEPRECATED @21 :List(UInt64);
desiredCurvatureRateDEPRECATED @62 :Float32;
canErrorCounterDEPRECATED @57 :UInt32;
vPidDEPRECATED @2 :Float32;
}
struct DrivingModelData {
frameId @0 :UInt32;
frameIdExtra @1 :UInt32;
frameDropPerc @6 :Float32;
modelExecutionTime @7 :Float32;
action @2 :ModelDataV2.Action;
laneLineMeta @3 :LaneLineMeta;
meta @4 :MetaData;
path @5 :PolyPath;
struct PolyPath {
xCoefficients @0 :List(Float32);
yCoefficients @1 :List(Float32);
zCoefficients @2 :List(Float32);
}
struct LaneLineMeta {
leftY @0 :Float32;
rightY @1 :Float32;
leftProb @2 :Float32;
rightProb @3 :Float32;
}
struct MetaData {
laneChangeState @0 :LaneChangeState;
laneChangeDirection @1 :LaneChangeDirection;
}
}
# All SI units and in device frame
@ -913,8 +945,8 @@ struct ModelDataV2 {
# Model perceived motion
temporalPose @21 :Pose;
navEnabledDEPRECATED @22 :Bool;
locationMonoTimeDEPRECATED @24 :UInt64;
navEnabled @22 :Bool;
locationMonoTime @24 :UInt64;
# e2e lateral planner
lateralPlannerSolutionDEPRECATED @25: LateralPlannerSolution;
@ -980,6 +1012,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 {
@ -1002,6 +1036,8 @@ struct ModelDataV2 {
struct Action {
desiredCurvature @0 :Float32;
desiredAcceleration @1 :Float32;
shouldStop @2 :Bool;
}
}
@ -1221,6 +1257,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;
@ -2041,6 +2109,22 @@ struct LiveTorqueParametersData {
useParams @12 :Bool;
}
struct LiveDelayData {
lateralDelay @0 :Float32;
validBlocks @1 :Int32;
status @2 :Status;
lateralDelayEstimate @3 :Float32;
lateralDelayEstimateStd @5 :Float32;
points @4 :List(Float32);
enum Status {
unestimated @0;
estimated @1;
invalid @2;
}
}
struct LiveMapDataDEPRECATED {
speedLimitValid @0 :Bool;
speedLimit @1 :Float32;
@ -2257,13 +2341,16 @@ struct Event {
gnssMeasurements @91 :GnssMeasurements;
liveParameters @61 :LiveParametersData;
liveTorqueParameters @94 :LiveTorqueParametersData;
liveDelay @130 : LiveDelayData;
cameraOdometry @63 :CameraOdometry;
thumbnail @66: Thumbnail;
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;
# camera stuff, each camera state has a matching encode idx
@ -2318,16 +2405,16 @@ struct Event {
customReservedRawData2 @126 :Data;
# *********** Custom: reserved for forks ***********
customReserved0 @107 :Custom.CustomReserved0;
customReserved1 @108 :Custom.CustomReserved1;
customReserved2 @109 :Custom.CustomReserved2;
customReserved3 @110 :Custom.CustomReserved3;
customReserved4 @111 :Custom.CustomReserved4;
customReserved5 @112 :Custom.CustomReserved5;
customReserved6 @113 :Custom.CustomReserved6;
customReserved7 @114 :Custom.CustomReserved7;
customReserved8 @115 :Custom.CustomReserved8;
customReserved9 @116 :Custom.CustomReserved9;
frogpilotCarControl @107 :Custom.FrogPilotCarControl;
frogpilotCarParams @108 :Custom.FrogPilotCarParams;
frogpilotCarState @109 :Custom.FrogPilotCarState;
frogpilotControlsState @110 :Custom.FrogPilotControlsState;
frogpilotDeviceState @111 :Custom.FrogPilotDeviceState;
frogpilotModelV2 @112 :Custom.FrogPilotModelDataV2;
frogpilotNavigation @113 :Custom.FrogPilotNavigation;
frogpilotOnroadEvents @114: List(Custom.FrogPilotCarEvent);
frogpilotPlan @115 :Custom.FrogPilotPlan;
frogpilotRadarState @116 :Custom.FrogPilotRadarState;
# *********** legacy + deprecated ***********
model @9 :Legacy.ModelData; # TODO: rename modelV2 and mark this as deprecated
@ -2368,6 +2455,6 @@ struct Event {
driverStateDEPRECATED @59 :DriverStateDEPRECATED;
sensorEventsDEPRECATED @11 :List(SensorEventData);
lateralPlanDEPRECATED @64 :LateralPlan;
navModelDEPRECATED @104 :NavModelData;
navModel @104 :NavModelData;
}
}

View File

@ -34,6 +34,7 @@ _services: dict[str, tuple] = {
"errorLogMessage": (True, 0., 1),
"liveCalibration": (True, 4., 4),
"liveTorqueParameters": (True, 4., 1),
"liveDelay": (True, 4., 1),
"androidLog": (True, 0.),
"carState": (True, 100., 10),
"carControl": (True, 100., 10),
@ -47,7 +48,8 @@ _services: dict[str, tuple] = {
"gnssMeasurements": (True, 10., 10),
"clocks": (True, 0.1, 1),
"ubloxRaw": (True, 20.),
"liveLocationKalman": (True, 20., 5),
"livePose": (True, 20., 4),
"liveLocationKalman": (True, 20.),
"liveParameters": (True, 20., 5),
"cameraOdometry": (True, 20., 5),
"thumbnail": (True, 0.2, 1),
@ -60,12 +62,15 @@ _services: dict[str, tuple] = {
"driverMonitoringState": (True, 20., 10),
"wideRoadEncodeIdx": (False, 20., 1),
"wideRoadCameraState": (True, 20., 20),
"drivingModelData": (True, 20., 10),
"modelV2": (True, 20., 40),
"managerState": (True, 2., 1),
"uploaderState": (True, 0., 1),
"navInstruction": (True, 1., 10),
"navRoute": (True, 0.),
"navThumbnail": (True, 0.),
"navModel": (True, 2., 4.),
"mapRenderState": (True, 2., 1.),
"uiPlan": (True, 20., 40.),
"qRoadEncodeIdx": (False, 20.),
"userFlag": (True, 0., 1),
@ -87,6 +92,18 @@ _services: dict[str, tuple] = {
"customReservedRawData0": (True, 0.),
"customReservedRawData1": (True, 0.),
"customReservedRawData2": (True, 0.),
# FrogPilot
"frogpilotCarControl": (True, 100., 10),
"frogpilotCarParams": (True, 0.02, 1),
"frogpilotCarState": (True, 100., 10),
"frogpilotControlsState": (True, 100., 10),
"frogpilotDeviceState": (True, 2., 1),
"frogpilotModelV2": (True, 20., 40),
"frogpilotNavigation": (True, 1., 10),
"frogpilotOnroadEvents": (True, 1., 1),
"frogpilotPlan": (True, 20., 5),
"frogpilotRadarState": (True, 20., 5),
}
SERVICE_LIST = {name: Service(*vals) for
idx, (name, vals) in enumerate(_services.items())}

View File

@ -5,7 +5,10 @@ from datetime import datetime, timedelta
from openpilot.system.hardware.hw import Paths
from openpilot.system.version import get_version
from openpilot.frogpilot.common.frogpilot_utilities import use_konik_server
API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com')
KONIK_API_HOST = os.getenv('API_HOST', 'https://api.konik.ai')
class Api:
def __init__(self, dongle_id):
@ -43,4 +46,4 @@ def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
headers['User-Agent'] = "openpilot-" + get_version()
return requests.request(method, API_HOST + "/" + endpoint, timeout=timeout, headers=headers, params=params)
return requests.request(method, (KONIK_API_HOST if use_konik_server() else API_HOST) + "/" + endpoint, timeout=timeout, headers=headers, params=params)

View File

@ -79,6 +79,10 @@ cl_context cl_create_context(cl_device_id device_id) {
return CL_CHECK_ERR(clCreateContext(NULL, 1, &device_id, NULL, NULL, &err));
}
void cl_release_context(cl_context context) {
clReleaseContext(context);
}
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args) {
return cl_program_from_source(ctx, device_id, util::read_file(path), args);
}

View File

@ -23,6 +23,7 @@
cl_device_id cl_get_device_id(cl_device_type device_type);
cl_context cl_create_context(cl_device_id device_id);
void cl_release_context(cl_context context);
cl_program cl_program_from_source(cl_context ctx, cl_device_id device_id, const std::string& src, const char* args = nullptr);
cl_program cl_program_from_binary(cl_context ctx, cl_device_id device_id, const uint8_t* binary, size_t length, const char* args = nullptr);
cl_program cl_program_from_file(cl_context ctx, cl_device_id device_id, const char* path, const char* args);

View File

@ -11,6 +11,14 @@ class Conversions:
MS_TO_KNOTS = 1.9438
KNOTS_TO_MS = 1. / MS_TO_KNOTS
# Distance
METER_TO_FOOT = 3.28084
FOOT_TO_METER = 1. / METER_TO_FOOT
METER_TO_MILE = METER_TO_FOOT / 5280
MILE_TO_METER = 1. / METER_TO_MILE
CM_TO_INCH = 1. / 2.54
INCH_TO_CM = 1. / CM_TO_INCH
# Angle
DEG_TO_RAD = np.pi / 180.
RAD_TO_DEG = 1. / DEG_TO_RAD

View File

@ -76,6 +76,10 @@ std::string ensure_params_path(const std::string &prefix, const std::string &pat
class FileLock {
public:
FileLock(const std::string &fn) {
if (fn.rfind("/cache", 0) == 0 || fn.rfind("/data/params_backup", 0) == 0) {
return;
}
fd_ = HANDLE_EINTR(open(fn.c_str(), O_CREAT, 0775));
if (fd_ < 0 || HANDLE_EINTR(flock(fd_, LOCK_EX)) < 0) {
LOGE("Failed to lock file %s, errno=%d", fn.c_str(), errno);
@ -138,7 +142,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"HasAcceptedTerms", PERSISTENT},
{"IMEI", PERSISTENT},
{"InstallDate", PERSISTENT},
{"IsDriverViewEnabled", CLEAR_ON_MANAGER_START},
{"IsDriverViewEnabled", CLEAR_ON_ONROAD_TRANSITION},
{"IsEngaged", PERSISTENT},
{"IsLdwEnabled", PERSISTENT},
{"IsMetric", PERSISTENT},
@ -157,6 +161,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"LastPowerDropDetected", CLEAR_ON_MANAGER_START},
{"LastUpdateException", CLEAR_ON_MANAGER_START},
{"LastUpdateTime", PERSISTENT},
{"LiveDelay", PERSISTENT},
{"LiveParameters", PERSISTENT},
{"LiveTorqueParameters", PERSISTENT | DONT_LOG},
{"LongitudinalPersonality", PERSISTENT},
@ -189,6 +194,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"RecordFrontLock", PERSISTENT}, // for the internal fleet
{"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"RouteCount", PERSISTENT},
{"SecOCKey", PERSISTENT | DONT_LOG},
{"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION},
{"SshEnabled", PERSISTENT},
{"TermsVersion", PERSISTENT},
@ -207,6 +213,370 @@ std::unordered_map<std::string, uint32_t> keys = {
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
{"UpdaterLastFetchTime", PERSISTENT},
{"Version", PERSISTENT},
// FrogPilot parameters
{"AccelerationPath", PERSISTENT},
{"AccelerationProfile", PERSISTENT},
{"AdjacentLeadsUI", PERSISTENT},
{"AdjacentPath", PERSISTENT},
{"AdjacentPathMetrics", PERSISTENT},
{"AdvancedCustomUI", PERSISTENT},
{"AdvancedLateralTune", PERSISTENT},
{"AdvancedLongitudinalTune", PERSISTENT},
{"AggressiveFollow", PERSISTENT},
{"AggressiveJerkAcceleration", PERSISTENT},
{"AggressiveJerkDanger", PERSISTENT},
{"AggressiveJerkDeceleration", PERSISTENT},
{"AggressiveJerkSpeed", PERSISTENT},
{"AggressiveJerkSpeedDecrease", PERSISTENT},
{"AggressivePersonalityProfile", PERSISTENT},
{"AlertVolumeControl", PERSISTENT},
{"AlwaysOnLateral", PERSISTENT},
{"AlwaysOnLateralLKAS", PERSISTENT},
{"AlwaysOnLateralMain", PERSISTENT},
{"AMapKey1", PERSISTENT | DONT_LOG},
{"AMapKey2", PERSISTENT | DONT_LOG},
{"ApiCache_DriveStats", PERSISTENT},
{"AutomaticallyDownloadModels", PERSISTENT},
{"AutomaticUpdates", PERSISTENT},
{"AvailableModelNames", PERSISTENT},
{"AvailableModels", PERSISTENT},
{"BigMap", PERSISTENT},
{"BlacklistedModels", PERSISTENT},
{"BlindSpotMetrics", PERSISTENT},
{"BlindSpotPath", PERSISTENT},
{"BorderMetrics", PERSISTENT},
{"CalibratedLateralAcceleration", PERSISTENT},
{"CalibrationProgress", PERSISTENT},
{"CameraView", PERSISTENT},
{"CancelModelDownload", CLEAR_ON_MANAGER_START},
{"CancelThemeDownload", CLEAR_ON_MANAGER_START},
{"CarMake", PERSISTENT},
{"CarModel", PERSISTENT},
{"CarModelName", PERSISTENT},
{"CECurves", PERSISTENT},
{"CECurvesLead", PERSISTENT},
{"CELead", PERSISTENT},
{"CEModelStopTime", PERSISTENT},
{"CENavigation", PERSISTENT},
{"CENavigationIntersections", PERSISTENT},
{"CENavigationLead", PERSISTENT},
{"CENavigationTurns", PERSISTENT},
{"CESignalSpeed", PERSISTENT},
{"CESignalLaneDetection", PERSISTENT},
{"CESlowerLead", PERSISTENT},
{"CESpeed", PERSISTENT},
{"CESpeedLead", PERSISTENT},
{"CEStatus", CLEAR_ON_OFFROAD_TRANSITION},
{"CEStoppedLead", PERSISTENT},
{"ClusterOffset", PERSISTENT},
{"ColorToDownload", CLEAR_ON_MANAGER_START},
{"Compass", PERSISTENT},
{"ConditionalExperimental", PERSISTENT},
{"CurvatureData", PERSISTENT | DONT_LOG},
{"CurveSpeedController", PERSISTENT},
{"CustomAlerts", PERSISTENT},
{"CustomColors", PERSISTENT},
{"CustomCruise", PERSISTENT},
{"CustomCruiseLong", PERSISTENT},
{"CustomDistanceIcons", PERSISTENT},
{"CustomIcons", PERSISTENT},
{"CustomPersonalities", PERSISTENT},
{"CustomSignals", PERSISTENT},
{"CustomSounds", PERSISTENT},
{"CustomUI", PERSISTENT},
{"DebugMode", CLEAR_ON_OFFROAD_TRANSITION},
{"DecelerationProfile", PERSISTENT},
{"DeveloperMetrics", PERSISTENT},
{"DeveloperSidebar", PERSISTENT},
{"DeveloperSidebarMetric1", PERSISTENT},
{"DeveloperSidebarMetric2", PERSISTENT},
{"DeveloperSidebarMetric3", PERSISTENT},
{"DeveloperSidebarMetric4", PERSISTENT},
{"DeveloperSidebarMetric5", PERSISTENT},
{"DeveloperSidebarMetric6", PERSISTENT},
{"DeveloperSidebarMetric7", PERSISTENT},
{"DeveloperWidgets", PERSISTENT},
{"DeveloperUI", PERSISTENT},
{"DeviceManagement", PERSISTENT},
{"DeviceShutdown", PERSISTENT},
{"DisableOnroadUploads", PERSISTENT},
{"DisableOpenpilotLongitudinal", PERSISTENT},
{"DiscordUsername", PERSISTENT},
{"DistanceButtonControl", PERSISTENT},
{"DistanceIconToDownload", CLEAR_ON_MANAGER_START},
{"DisengageVolume", PERSISTENT},
{"DoToggleReset", PERSISTENT},
{"DoToggleResetStock", PERSISTENT},
{"DownloadableColors", PERSISTENT},
{"DownloadableDistanceIcons", PERSISTENT},
{"DownloadableIcons", PERSISTENT},
{"DownloadableSignals", PERSISTENT},
{"DownloadableSounds", PERSISTENT},
{"DownloadableWheels", PERSISTENT},
{"DownloadAllModels", CLEAR_ON_MANAGER_START},
{"DriverCamera", PERSISTENT},
{"DynamicPathWidth", PERSISTENT},
{"DynamicPedalsOnUI", PERSISTENT},
{"EngageVolume", PERSISTENT},
{"ExperimentalGMTune", PERSISTENT},
{"Fahrenheit", PERSISTENT},
{"FavoriteDestinations", PERSISTENT | DONT_LOG},
{"FlashPanda", CLEAR_ON_MANAGER_START},
{"ForceAutoTune", PERSISTENT},
{"ForceAutoTuneOff", PERSISTENT},
{"ForceFingerprint", PERSISTENT},
{"ForceMPHDashboard", PERSISTENT},
{"ForceOffroad", CLEAR_ON_MANAGER_START},
{"ForceOnroad", CLEAR_ON_MANAGER_START},
{"ForceStops", PERSISTENT},
{"ForceTorqueController", PERSISTENT},
{"FPSCounter", PERSISTENT},
{"FrogPilotCarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
{"FrogPilotCarParamsPersistent", PERSISTENT},
{"FrogPilotDongleId", PERSISTENT | DONT_LOG},
{"FrogPilotDrives", PERSISTENT},
{"FrogPilotKilometers", PERSISTENT},
{"FrogPilotMinutes", PERSISTENT},
{"FrogPilotStats", PERSISTENT | DONT_LOG},
{"FrogPilotToggles", CLEAR_ON_MANAGER_START},
{"FrogPilotTogglesUpdated", CLEAR_ON_MANAGER_START},
{"FrogPilotTuningLevels", CLEAR_ON_MANAGER_START},
{"FrogsGoMoosTweak", PERSISTENT},
{"FullMap", PERSISTENT},
{"GasRegenCmd", PERSISTENT},
{"GoatScream", PERSISTENT},
{"GreenLightAlert", PERSISTENT},
{"HideAlerts", PERSISTENT},
{"HideLeadMarker", PERSISTENT},
{"HideMap", PERSISTENT},
{"HideMapIcon", PERSISTENT},
{"HideMaxSpeed", PERSISTENT},
{"HideSpeed", PERSISTENT},
{"HideSpeedLimit", PERSISTENT},
{"HigherBitrate", PERSISTENT},
{"HolidayThemes", PERSISTENT},
{"HumanAcceleration", PERSISTENT},
{"HumanFollowing", PERSISTENT},
{"IconToDownload", CLEAR_ON_MANAGER_START},
{"IncreasedStoppedDistance", PERSISTENT},
{"IncreaseThermalLimits", PERSISTENT},
{"IssueReported", CLEAR_ON_MANAGER_START},
{"KonikDongleId", PERSISTENT},
{"KonikMinutes", PERSISTENT},
{"LaneChanges", PERSISTENT},
{"LaneChangeTime", PERSISTENT},
{"LaneDetectionWidth", PERSISTENT},
{"LaneLinesWidth", PERSISTENT},
{"LastMapsUpdate", PERSISTENT},
{"LateralTune", PERSISTENT},
{"LeadDepartingAlert", PERSISTENT},
{"LeadDetectionThreshold", PERSISTENT},
{"LeadInfo", PERSISTENT},
{"LKASButtonControl", PERSISTENT},
{"LockDoors", PERSISTENT},
{"LockDoorsTimer", PERSISTENT},
{"LongDistanceButtonControl", PERSISTENT},
{"LongitudinalActuatorDelay", PERSISTENT},
{"LongitudinalActuatorDelayStock", PERSISTENT},
{"LongitudinalTune", PERSISTENT},
{"LongPitch", PERSISTENT},
{"LoudBlindspotAlert", PERSISTENT},
{"LowVoltageShutdown", PERSISTENT},
{"ManualUpdateInitiated", CLEAR_ON_MANAGER_START},
{"MapAcceleration", PERSISTENT},
{"MapboxPublicKey", PERSISTENT | DONT_LOG},
{"MapBoxRequests", PERSISTENT},
{"MapboxSecretKey", PERSISTENT | DONT_LOG},
{"MapDeceleration", PERSISTENT},
{"MapdLogLevel", CLEAR_ON_MANAGER_START},
{"MapGears", PERSISTENT},
{"MapsSelected", PERSISTENT},
{"MapSpeedLimit", CLEAR_ON_MANAGER_START},
{"MapStyle", PERSISTENT},
{"MaxDesiredAcceleration", PERSISTENT},
{"MinimumBackupSize", PERSISTENT},
{"MinimumLaneChangeSpeed", PERSISTENT},
{"Model", PERSISTENT},
{"ModelDownloadProgress", CLEAR_ON_MANAGER_START},
{"ModelDrivesAndScores", PERSISTENT},
{"ModelRandomizer", PERSISTENT},
{"ModelToDownload", CLEAR_ON_MANAGER_START},
{"ModelUI", PERSISTENT},
{"ModelVersions", PERSISTENT},
{"NavigationUI", PERSISTENT},
{"NextMapSpeedLimit", CLEAR_ON_MANAGER_START},
{"NewLongAPI", PERSISTENT},
{"NNFF", PERSISTENT},
{"NNFFLite", PERSISTENT},
{"NNFFModelName", CLEAR_ON_OFFROAD_TRANSITION},
{"NoLogging", PERSISTENT},
{"NoUploads", PERSISTENT},
{"NudgelessLaneChange", PERSISTENT},
{"NumericalTemp", PERSISTENT},
{"Offset1", PERSISTENT},
{"Offset2", PERSISTENT},
{"Offset3", PERSISTENT},
{"Offset4", PERSISTENT},
{"Offset5", PERSISTENT},
{"Offset6", PERSISTENT},
{"Offset7", PERSISTENT},
{"OneLaneChange", PERSISTENT},
{"OnroadDistanceButton", PERSISTENT},
{"OnroadDistanceButtonPressed", CLEAR_ON_MANAGER_START},
{"openpilotMinutes", PERSISTENT},
{"OSMDownloadBounds", PERSISTENT},
{"OSMDownloadLocations", PERSISTENT},
{"OSMDownloadProgress", CLEAR_ON_MANAGER_START},
{"OverpassRequests", PERSISTENT},
{"PathEdgeWidth", PERSISTENT},
{"PathWidth", PERSISTENT},
{"PauseAOLOnBrake", PERSISTENT},
{"PauseLateralOnSignal", PERSISTENT},
{"PauseLateralSpeed", PERSISTENT},
{"PedalsOnUI", PERSISTENT},
{"PersonalizeOpenpilot", PERSISTENT},
{"PreferredSchedule", PERSISTENT},
{"PreviousSpeedLimit", PERSISTENT},
{"PromptDistractedVolume", PERSISTENT},
{"PromptVolume", PERSISTENT},
{"QOLLateral", PERSISTENT},
{"QOLLongitudinal", PERSISTENT},
{"QOLVisuals", PERSISTENT},
{"RadarTracksUI", PERSISTENT},
{"RainbowPath", PERSISTENT},
{"RandomEvents", PERSISTENT},
{"RandomThemes", PERSISTENT},
{"RefuseVolume", PERSISTENT},
{"RelaxedFollow", PERSISTENT},
{"RelaxedJerkAcceleration", PERSISTENT},
{"RelaxedJerkDanger", PERSISTENT},
{"RelaxedJerkDeceleration", PERSISTENT},
{"RelaxedJerkSpeed", PERSISTENT},
{"RelaxedJerkSpeedDecrease", PERSISTENT},
{"RelaxedPersonalityProfile", PERSISTENT},
{"ReverseCruise", PERSISTENT},
{"RoadEdgesWidth", PERSISTENT},
{"RoadName", CLEAR_ON_MANAGER_START},
{"RoadNameUI", PERSISTENT},
{"RotatingWheel", PERSISTENT},
{"ScreenBrightness", PERSISTENT},
{"ScreenBrightnessOnroad", PERSISTENT},
{"ScreenManagement", PERSISTENT},
{"ScreenRecorder", PERSISTENT},
{"ScreenTimeout", PERSISTENT},
{"ScreenTimeoutOnroad", PERSISTENT},
{"SearchInput", PERSISTENT},
{"SecOCKeys", PERSISTENT | DONT_LOG},
{"SetSpeedLimit", PERSISTENT},
{"SetSpeedOffset", PERSISTENT},
{"ShowCEMStatus", PERSISTENT},
{"ShowCPU", PERSISTENT},
{"ShowCSCStatus", PERSISTENT},
{"ShowGPU", PERSISTENT},
{"ShowIP", PERSISTENT},
{"ShowMemoryUsage", PERSISTENT},
{"ShownToggleDescriptions", PERSISTENT},
{"ShowSLCOffset", PERSISTENT},
{"ShowSpeedLimits", PERSISTENT},
{"ShowSteering", PERSISTENT},
{"ShowStoppingPoint", PERSISTENT},
{"ShowStoppingPointMetrics", PERSISTENT},
{"ShowStorageLeft", PERSISTENT},
{"ShowStorageUsed", PERSISTENT},
{"Sidebar", PERSISTENT},
{"SignalMetrics", PERSISTENT},
{"SignalToDownload", CLEAR_ON_MANAGER_START},
{"SLCConfirmation", PERSISTENT},
{"SLCConfirmationHigher", PERSISTENT},
{"SLCConfirmationLower", PERSISTENT},
{"SLCFallback", PERSISTENT},
{"SLCLookaheadHigher", PERSISTENT},
{"SLCLookaheadLower", PERSISTENT},
{"SLCMapboxFiller", PERSISTENT},
{"SLCOverride", PERSISTENT},
{"SLCPriority1", PERSISTENT},
{"SLCPriority2", PERSISTENT},
{"SLCPriority3", PERSISTENT},
{"SNGHack", PERSISTENT},
{"SoundToDownload", CLEAR_ON_MANAGER_START},
{"SpeedLimitAccepted", CLEAR_ON_MANAGER_START},
{"SpeedLimitChangedAlert", PERSISTENT},
{"SpeedLimitController", PERSISTENT},
{"SpeedLimitFiller", PERSISTENT},
{"SpeedLimits", PERSISTENT | DONT_LOG},
{"SpeedLimitsFiltered", PERSISTENT | DONT_LOG},
{"SpeedLimitSources", PERSISTENT},
{"StandardFollow", PERSISTENT},
{"StandardJerkAcceleration", PERSISTENT},
{"StandardJerkDanger", PERSISTENT},
{"StandardJerkDeceleration", PERSISTENT},
{"StandardJerkSpeed", PERSISTENT},
{"StandardJerkSpeedDecrease", PERSISTENT},
{"StandardPersonalityProfile", PERSISTENT},
{"StandbyMode", PERSISTENT},
{"StartAccel", PERSISTENT},
{"StartAccelStock", PERSISTENT},
{"StartupMessageBottom", PERSISTENT},
{"StartupMessageTop", PERSISTENT},
{"StaticPedalsOnUI", PERSISTENT},
{"SteerDelay", PERSISTENT},
{"SteerDelayStock", PERSISTENT},
{"SteerFriction", PERSISTENT},
{"SteerFrictionStock", PERSISTENT},
{"SteerLatAccel", PERSISTENT},
{"SteerLatAccelStock", PERSISTENT},
{"SteerKP", PERSISTENT},
{"SteerKPStock", PERSISTENT},
{"SteerRatio", PERSISTENT},
{"SteerRatioStock", PERSISTENT},
{"StockDongleId", PERSISTENT},
{"StopAccel", PERSISTENT},
{"StopAccelStock", PERSISTENT},
{"StoppingDecelRate", PERSISTENT},
{"StoppingDecelRateStock", PERSISTENT},
{"StoppedTimer", PERSISTENT},
{"TacoTune", PERSISTENT},
{"TacoTuneHacks", PERSISTENT},
{"TestAlert", CLEAR_ON_MANAGER_START},
{"TetheringEnabled", PERSISTENT},
{"ThemeDownloadProgress", CLEAR_ON_MANAGER_START},
{"ThemesDownloaded", PERSISTENT},
{"TinygradUpdateAvailable", PERSISTENT},
{"TogglesUpdated", PERSISTENT},
{"ToyotaDoors", PERSISTENT},
{"TrafficFollow", PERSISTENT},
{"TrafficJerkAcceleration", PERSISTENT},
{"TrafficJerkDanger", PERSISTENT},
{"TrafficJerkDeceleration", PERSISTENT},
{"TrafficJerkSpeed", PERSISTENT},
{"TrafficJerkSpeedDecrease", PERSISTENT},
{"TrafficPersonalityProfile", PERSISTENT},
{"TuningLevel", PERSISTENT},
{"TuningLevelConfirmed", PERSISTENT},
{"TurnDesires", PERSISTENT},
{"UnlimitedLength", PERSISTENT},
{"UnlockDoors", PERSISTENT},
{"Updated", PERSISTENT},
{"UpdateSpeedLimits", CLEAR_ON_MANAGER_START},
{"UpdateSpeedLimitsStatus", CLEAR_ON_MANAGER_START},
{"UpdateTinygrad", CLEAR_ON_MANAGER_START},
{"UpdateWheelImage", CLEAR_ON_MANAGER_START},
{"UseActiveTheme", CLEAR_ON_MANAGER_START},
{"UseKonikServer", PERSISTENT},
{"UseSI", PERSISTENT},
{"UseVienna", PERSISTENT},
{"VEgoStarting", PERSISTENT},
{"VEgoStartingStock", PERSISTENT},
{"VEgoStopping", PERSISTENT},
{"VEgoStoppingStock", PERSISTENT},
{"VeryLongDistanceButtonControl", PERSISTENT},
{"VoltSNG", PERSISTENT},
{"WarningImmediateVolume", PERSISTENT},
{"WarningSoftVolume", PERSISTENT},
{"WheelIcon", PERSISTENT},
{"WheelSpeed", PERSISTENT},
{"WheelToDownload", CLEAR_ON_MANAGER_START},
};
} // namespace

View File

@ -43,6 +43,14 @@ public:
inline bool getBool(const std::string &key, bool block = false) {
return get(key, block) == "1";
}
inline int getInt(const std::string &key, bool block = false) {
std::string value = get(key, block);
return value.empty() ? 0 : std::stoi(value);
}
inline float getFloat(const std::string &key, bool block = false) {
std::string value = get(key, block);
return value.empty() ? 0.0 : std::stof(value);
}
std::map<std::string, std::string> readAll();
// helpers for writing values
@ -53,10 +61,22 @@ public:
inline int putBool(const std::string &key, bool val) {
return put(key.c_str(), val ? "1" : "0", 1);
}
inline int putInt(const std::string &key, int val) {
return put(key.c_str(), std::to_string(val).c_str(), std::to_string(val).size());
}
inline int putFloat(const std::string &key, float val) {
return put(key.c_str(), std::to_string(val).c_str(), std::to_string(val).size());
}
void putNonBlocking(const std::string &key, const std::string &val);
inline void putBoolNonBlocking(const std::string &key, bool val) {
putNonBlocking(key, val ? "1" : "0");
}
inline void putIntNonBlocking(const std::string &key, int val) {
putNonBlocking(key, std::to_string(val));
}
inline void putFloatNonBlocking(const std::string &key, float val) {
putNonBlocking(key, std::to_string(val));
}
private:
void asyncWriteThread();

View File

@ -17,11 +17,17 @@ cdef extern from "common/params.h":
c_Params(string) except + nogil
string get(string, bool) nogil
bool getBool(string, bool) nogil
int getInt(string, bool) nogil
float getFloat(string, bool) nogil
int remove(string) nogil
int put(string, string) nogil
void putNonBlocking(string, string) nogil
void putBoolNonBlocking(string, bool) nogil
void putIntNonBlocking(string, int) nogil
void putFloatNonBlocking(string, float) nogil
int putBool(string, bool) nogil
int putInt(string, int) nogil
int putFloat(string, float) nogil
bool checkKey(string) nogil
string getParamPath(string) nogil
void clearAll(ParamKeyType)
@ -77,6 +83,20 @@ cdef class Params:
r = self.p.getBool(k, block)
return r
def get_int(self, key, bool block=False):
cdef string k = self.check_key(key)
cdef int r
with nogil:
r = self.p.getInt(k, block)
return r
def get_float(self, key, bool block=False):
cdef string k = self.check_key(key)
cdef float r
with nogil:
r = self.p.getFloat(k, block)
return r
def put(self, key, dat):
"""
Warning: This function blocks until the param is written to disk!
@ -94,6 +114,16 @@ cdef class Params:
with nogil:
self.p.putBool(k, val)
def put_int(self, key, int val):
cdef string k = self.check_key(key)
with nogil:
self.p.putInt(k, val)
def put_float(self, key, float val):
cdef string k = self.check_key(key)
with nogil:
self.p.putFloat(k, val)
def put_nonblocking(self, key, dat):
cdef string k = self.check_key(key)
cdef string dat_bytes = ensure_bytes(dat)
@ -105,6 +135,16 @@ cdef class Params:
with nogil:
self.p.putBoolNonBlocking(k, val)
def put_int_nonblocking(self, key, int val):
cdef string k = self.check_key(key)
with nogil:
self.p.putIntNonBlocking(k, val)
def put_float_nonblocking(self, key, float val):
cdef string k = self.check_key(key)
with nogil:
self.p.putFloatNonBlocking(k, val)
def remove(self, key):
cdef string k = self.check_key(key)
with nogil:

View File

@ -271,4 +271,18 @@ std::string check_output(const std::string& command) {
return result;
}
bool system_time_valid() {
// Default to March 30, 2024
tm min_tm = {.tm_year = 2024 - 1900, .tm_mon = 2, .tm_mday = 30};
time_t min_date = mktime(&min_tm);
struct stat st;
if (stat("/lib/systemd/systemd", &st) == 0) {
min_date = std::max(min_date, st.st_mtime + 86400); // Add 1 day (86400 seconds)
}
return time(nullptr) > min_date;
}
} // namespace util

View File

@ -36,6 +36,9 @@ const double MS_TO_KPH = 3.6;
const double MS_TO_MPH = MS_TO_KPH * KM_TO_MILE;
const double METER_TO_MILE = KM_TO_MILE / 1000.0;
const double METER_TO_FOOT = 3.28084;
const double FOOT_TO_METER = 1. / METER_TO_FOOT;
const double CM_TO_INCH = 1. / 2.54;
const double INCH_TO_CM = 1. / CM_TO_INCH;
namespace util {
@ -93,6 +96,8 @@ bool create_directories(const std::string &dir, mode_t mode);
std::string check_output(const std::string& command);
bool system_time_valid();
inline void sleep_for(const int milliseconds) {
if (milliseconds > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));

View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
import requests
import tempfile
from datetime import datetime
from pathlib import Path
from openpilot.frogpilot.common.frogpilot_utilities import delete_file, is_url_pingable
from openpilot.frogpilot.common.frogpilot_variables import RESOURCES_REPO, params_memory
GITHUB_URL = f"https://raw.githubusercontent.com/{RESOURCES_REPO}"
GITLAB_URL = f"https://gitlab.com/{RESOURCES_REPO}/-/raw"
def check_github_rate_limit(session):
try:
response = session.get("https://api.github.com/rate_limit", timeout=10)
response.raise_for_status()
rate_limit_info = response.json()
remaining = rate_limit_info["rate"]["remaining"]
print(f"GitHub API Requests Remaining: {remaining}")
if remaining > 0:
return True
reset_time = datetime.utcfromtimestamp(rate_limit_info["rate"]["reset"]).strftime("%Y-%m-%d %H:%M:%S")
print("GitHub rate limit reached")
print(f"GitHub Rate Limit Resets At (UTC): {reset_time}")
return False
except requests.exceptions.RequestException as exception:
print(f"Error checking GitHub rate limit: {exception}")
return False
def download_file(cancel_param, destination, progress_param, url, download_param, session, offset_bytes=0, total_bytes=0):
try:
destination.parent.mkdir(parents=True, exist_ok=True)
total_size = get_remote_file_size(url, session)
if total_size == 0:
if not url.endswith(".gif"):
handle_error(None, "Download invalid...", "Download invalid...", download_param, progress_param)
return
with session.get(url, stream=True, timeout=10) as response:
response.raise_for_status()
with tempfile.NamedTemporaryFile(delete=False, dir=destination.parent) as temp_file:
temp_file_path = Path(temp_file.name)
downloaded_size = 0
for chunk in response.iter_content(chunk_size=16384):
if params_memory.get_bool(cancel_param):
temp_file_path.unlink(missing_ok=True)
handle_error(None, "Download cancelled...", "Download cancelled...", download_param, progress_param)
return
if chunk:
temp_file.write(chunk)
downloaded_size += len(chunk)
if total_bytes:
overall_progress = (offset_bytes + downloaded_size) / total_bytes * 100
else:
overall_progress = downloaded_size / total_size * 100
if overall_progress != 100:
params_memory.put(progress_param, f"{overall_progress:.0f}%")
else:
params_memory.put(progress_param, "Verifying authenticity...")
temp_file_path.rename(destination)
except Exception as exception:
handle_request_error(exception, destination, download_param, progress_param)
def get_remote_file_size(url, session):
try:
response = session.head(url, headers={"Accept-Encoding": "identity"}, timeout=10)
response.raise_for_status()
return int(response.headers.get("Content-Length", 0))
except Exception as exception:
handle_request_error(exception, None, None, None)
return 0
def get_repository_url(session):
if is_url_pingable("https://github.com"):
if check_github_rate_limit(session):
return GITHUB_URL
if is_url_pingable("https://gitlab.com"):
return GITLAB_URL
return None
def handle_error(destination, error_message, error, download_param, progress_param):
if destination:
delete_file(destination)
if progress_param and "404" not in error_message:
print(f"Error occurred: {error}")
params_memory.put(progress_param, error_message)
params_memory.remove(download_param)
def handle_request_error(error, destination, download_param, progress_param):
error_map = {
requests.exceptions.ConnectionError: "Connection dropped",
requests.exceptions.HTTPError: lambda error: f"Server error ({error.response.status_code})" if error and getattr(error, "response", None) else "Server error",
requests.exceptions.RequestException: "Network request error. Check connection",
requests.exceptions.Timeout: "Download timed out",
}
error_message = error_map.get(type(error), "Unexpected error")
handle_error(destination, f"Failed: {error_message}", error, download_param, progress_param)
def verify_download(file_path, url, session):
remote_file_size = get_remote_file_size(url, session)
if remote_file_size == 0:
print(f"Error fetching remote size for {file_path}")
return False
if not file_path.is_file():
print(f"File not found: {file_path}")
return False
if remote_file_size != file_path.stat().st_size:
print(f"File size mismatch for {file_path}")
return False
return True

View File

@ -0,0 +1,44 @@
{
"LaneLines": {
"red": 40,
"green": 185,
"blue": 170,
"alpha": 255
},
"LeadMarker": {
"red": 40,
"green": 185,
"blue": 170,
"alpha": 255
},
"Path": {
"red": 40,
"green": 185,
"blue": 170,
"alpha": 255
},
"PathEdge": {
"red": 32,
"green": 148,
"blue": 136,
"alpha": 255
},
"Sidebar1": {
"red": 40,
"green": 185,
"blue": 170,
"alpha": 255
},
"Sidebar2": {
"red": 237,
"green": 118,
"blue": 50,
"alpha": 255
},
"Sidebar3": {
"red": 203,
"green": 247,
"blue": 18,
"alpha": 255
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -0,0 +1,44 @@
{
"LaneLines": {
"red": 23,
"green": 130,
"blue": 59,
"alpha": 255
},
"LeadMarker": {
"red": 23,
"green": 130,
"blue": 59,
"alpha": 255
},
"Path": {
"red": 23,
"green": 130,
"blue": 59,
"alpha": 255
},
"PathEdge": {
"red": 28,
"green": 156,
"blue": 84,
"alpha": 255
},
"Sidebar1": {
"red": 23,
"green": 130,
"blue": 59,
"alpha": 255
},
"Sidebar2": {
"red": 54,
"green": 133,
"blue": 192,
"alpha": 255
},
"Sidebar3": {
"red": 194,
"green": 17,
"blue": 17,
"alpha": 255
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -0,0 +1,44 @@
{
"LaneLines": {
"red": 40,
"green": 195,
"blue": 169,
"alpha": 255
},
"LeadMarker": {
"red": 40,
"green": 195,
"blue": 169,
"alpha": 255
},
"Path": {
"red": 40,
"green": 195,
"blue": 169,
"alpha": 255
},
"PathEdge": {
"red": 238,
"green": 226,
"blue": 95,
"alpha": 255
},
"Sidebar1": {
"red": 40,
"green": 195,
"blue": 169,
"alpha": 255
},
"Sidebar2": {
"red": 238,
"green": 226,
"blue": 95,
"alpha": 255
},
"Sidebar3": {
"red": 238,
"green": 0,
"blue": 0,
"alpha": 255
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,44 @@
{
"LaneLines": {
"red": 174,
"green": 113,
"blue": 212,
"alpha": 255
},
"LeadMarker": {
"red": 174,
"green": 113,
"blue": 212,
"alpha": 255
},
"Path": {
"red": 174,
"green": 113,
"blue": 212,
"alpha": 255
},
"PathEdge": {
"red": 139,
"green": 90,
"blue": 170,
"alpha": 255
},
"Sidebar1": {
"red": 175,
"green": 219,
"blue": 242,
"alpha": 255
},
"Sidebar2": {
"red": 254,
"green": 222,
"blue": 67,
"alpha": 255
},
"Sidebar3": {
"red": 174,
"green": 113,
"blue": 212,
"alpha": 255
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -0,0 +1,44 @@
{
"LaneLines": {
"red": 99,
"green": 123,
"blue": 244,
"alpha": 255
},
"LeadMarker": {
"red": 99,
"green": 123,
"blue": 244,
"alpha": 255
},
"Path": {
"red": 99,
"green": 123,
"blue": 244,
"alpha": 255
},
"PathEdge": {
"red": 255,
"green": 255,
"blue": 255,
"alpha": 255
},
"Sidebar1": {
"red": 255,
"green": 0,
"blue": 0,
"alpha": 255
},
"Sidebar2": {
"red": 255,
"green": 255,
"blue": 255,
"alpha": 255
},
"Sidebar3": {
"red": 99,
"green": 123,
"blue": 244,
"alpha": 255
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

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