Compare commits

..

16 Commits

Author SHA1 Message Date
DevTekVE 1a763974a3 bump panda 2024-12-08 09:20:43 +01:00
DevTekVE b8b57a73e3 bump panda 2024-12-07 20:29:37 +01:00
DevTekVE f129291933 bump panda 2024-12-05 20:46:59 +01:00
DevTekVE 51d0fe8428 Bump to latest mads-new panda 2024-12-05 00:07:19 +01:00
Jason Wen 777ff8dcb4 Sync: commaai/openpilot:master into sunnypilot/sunnypilot:master-new (#459) 2024-11-26 23:44:36 -05:00
Jason Wen 9446dd60d1 Merge branch 'upstream/master' into sync-20241126
# Conflicts:
#	opendbc_repo
2024-11-26 22:54:12 -05:00
Jason Wen 1deae82f12 Sync: commaai/openpilot:master into sunnypilot/sunnypilot:master-new (#458) 2024-11-23 12:28:14 -05:00
Jason Wen 0649653947 Merge branch 'upstream/master' into sync-20241122 2024-11-23 10:26:18 -05:00
DevTekVE ab65b19ba5 Hyundai: Enhanced Smart Cruise Control (ESCC) (#443)
* initial updates to the actions to run for sp

* ignore license file

* more updates

* undoing some of the changes because I was blocking the runs on

* allowing the submodule check as well

* Allowing macos builds

* test adding cache key

* don't attempt build_release for selfdrive for the time being.

* Blocking macos builds as well since they have a 10x miltiplier for GH aciton minutes, waaaay too much!

* lol nice typo codespell

* change ref commit id to check if replay passes

* Sync up submodules for ESCC

* Remove ESCC base and interfaces classes

Consolidated ESCC functionalities directly into the Hyundai ESCC module, removing redundant base and interface classes. This simplified the class structure and improved code maintainability.

* Removing hints because they were causing a circular dependency

* bump opendbc

* bump opendbc

* Bump opendbc

* Fixing inconsistencies thanks to the tests!

* Bumping opendbc after fixing tests

* update opendbc

* Updating to the new flags ordinal on cereal

* Reverting some of the misc changes, clarifying naming and passing the scc12 and fca11 values to the methods as they are defined out of order

* undoing more naming changes to simplify diff

* More naming and tiny adjustments

* use constant for msg id

* bump opendbc

* bump submodules

* already added

* bump opendbc

* bump opendbc

* bump opendbc

* fix init

* bump submodules

* bump submodules

* unit test!

* rename

* always use true radar tracks if available

* update comment

* bump submodules

---------

Co-authored-by: Jason Wen <haibin.wen3@gmail.com>
2024-11-22 09:07:39 -05:00
DevTekVE 36f8192612 ci: sunnypilot UI GH Action fix ensure push to master-ui artifact (#453)
Fixes the GitHub action that was failing when the pipeline was running as a result of a push to master-new because it was not properly recognized as "master"
2024-11-17 09:49:37 +01:00
DevTekVE 4b66cd0577 ci: fix repo permissions in ui preview (#450)
* more fix

* forcing a change on UI to test

* undo ui change for test

* temp add branch

* adding more ways to set the master uo

* more bruteforce

* undoing force
2024-11-16 22:27:29 -05:00
DevTekVE ad742515f1 ci: sunnypilot show UI diff on PRs (#449)
add master-new as well to the triggers for the diff ui
2024-11-16 23:45:12 +01:00
Jason Wen 2426354d72 bump opendbc (#448)
* bump opendbc

* Bump opendbc to our changed car params

* New Int16 test

* spFlags

* original name?

* Testing more carparams combinations

* Another crazy idea

* typo

* use this field

* bump

* bump opendbc

---------

Co-authored-by: DevTekVE <devtekve@gmail.com>
2024-11-16 17:04:12 -05:00
DevTekVE cf55992c26 CI: sunnypilot configuration (#447)
* initial updates to the actions to run for sp

* ignore license file

* more updates

* undoing some of the changes because I was blocking the runs on

* allowing the submodule check as well

* Allowing macos builds

* test adding cache key

* don't attempt build_release for selfdrive for the time being.

* Blocking macos builds as well since they have a 10x miltiplier for GH aciton minutes, waaaay too much!

* lol nice typo codespell

* change ref commit id to check if replay passes
2024-11-16 10:24:47 -05:00
DevTekVE 3da0dfd47f Updating submodules 2024-11-15 08:16:52 +01:00
Jason Wen 6edaf619bf Add Custom MIT License (#438) 2024-11-15 08:11:51 +01:00
113 changed files with 2105 additions and 3261 deletions
+3
View File
@@ -0,0 +1,3 @@
.Xauthority
.env
.host/
+18
View File
@@ -0,0 +1,18 @@
FROM ghcr.io/commaai/openpilot-base:latest
RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa gdb bash-completion
RUN python3 -m ensurepip --upgrade
RUN pip3 install ipython jupyter jupyterlab
RUN cd /tmp && \
ARCH=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \
curl -L -o virtualgl.deb "https://github.com/VirtualGL/virtualgl/releases/download/3.1.1/virtualgl_3.1.1_$ARCH.deb" && \
dpkg -i virtualgl.deb
RUN usermod -aG video batman
USER batman
RUN cd $HOME && \
curl -O https://raw.githubusercontent.com/commaai/agnos-builder/master/userspace/home/.tmux.conf && \
curl -O https://raw.githubusercontent.com/commaai/agnos-builder/master/userspace/home/.vimrc
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
TARGET_USER=batman
source .devcontainer/.host/.env
# override display flag for mac hosts
if [[ $HOST_OS == darwin ]]; then
echo "Setting up DISPLAY override for macOS..."
cat <<EOF >> /home/$TARGET_USER/.bashrc
source .devcontainer/.host/.env
if [ -n "\$HOST_DISPLAY" ]; then
DISPLAY_NUM=\$(echo "\$HOST_DISPLAY" | awk -F: '{print \$NF}')
export DISPLAY=host.docker.internal:\$DISPLAY_NUM
fi
EOF
fi
# setup virtualgl for mac hosts
if [[ $HOST_OS == darwin ]]; then
echo "Setting up virtualgl for macOS..."
cat <<EOF >> /home/$TARGET_USER/.bashrc
if [ -n "\$HOST_DISPLAY" ]; then
export VGL_PORT=10000
export VGL_CLIENT=host.docker.internal
export VGL_COMPRESS=rgb
export VGL_DISPLAY=:99
export VGL_FPS=60
# prevent vglrun from running exec
alias exec=:; source vglrun :; unalias exec
fi
EOF
fi
# These lines are temporary, to remain backwards compatible with old devcontainers
# that were running as root and therefore had their caches written as root
sudo chown -R $TARGET_USER: /tmp/scons_cache
sudo chown -R $TARGET_USER: /tmp/comma_download_cache
sudo chown -R $TARGET_USER: /home/batman/.comma
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
source .devcontainer/.host/.env
# setup safe directories for submodules
SUBMODULE_DIRS=$(git config --file .gitmodules --get-regexp path | awk '{ print $2 }')
for DIR in $SUBMODULE_DIRS; do
git config --global --add safe.directory "$PWD/$DIR"
done
# virtual display for virtualgl
if [[ "$HOST_OS" == "darwin" ]] && [[ -n "$HOST_DISPLAY" ]]; then
echo "Starting virtual display at :99 ..."
tmux new-session -d -s fakedisplay Xvfb :99 -screen 0 1920x1080x24
fi
+53
View File
@@ -0,0 +1,53 @@
{
"name": "openpilot devcontainer",
"build": {
"dockerfile": "Dockerfile"
},
"postCreateCommand": ".devcontainer/container_post_create.sh",
"postStartCommand": ".devcontainer/container_post_start.sh",
"initializeCommand": [".devcontainer/host_setup"],
"privileged": true,
"containerEnv": {
"DISPLAY": "${localEnv:DISPLAY}",
"PYTHONPATH": "${containerWorkspaceFolder}",
"TERM": "xterm-256color",
"force_color_prompt": "1"
},
"runArgs": [
"--volume=/dev:/dev",
"--volume=/tmp/.X11-unix:/tmp/.X11-unix",
"--volume=${localWorkspaceFolder}/.devcontainer/.host/.Xauthority:/home/batman/.Xauthority",
"--volume=${localEnv:HOME}/.comma:/home/batman/.comma",
"--volume=${localEnv:HOME}/.azure:/home/batman/.azure",
"--volume=/tmp/comma_download_cache:/tmp/comma_download_cache",
"--shm-size=1G",
"--add-host=host.docker.internal:host-gateway", // required to use host.docker.internal on linux
"--publish=0.0.0.0:8070-8079:8070-8079" // body ZMQ services
],
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": false,
"installOhMyZsh": false,
"upgradePackages": false,
"username": "batman"
},
"ghcr.io/devcontainers-contrib/features/gh-cli:1": {},
"ghcr.io/devcontainers/features/azure-cli:1": {}
},
"containerUser": "batman",
"remoteUser": "batman",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-vscode.cpptools",
"ms-toolsai.jupyter",
"guyskk.language-cython",
"lharri73.dbc"
]
}
},
"mounts": [
"type=volume,source=scons_cache,target=/tmp/scons_cache"
]
}
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# pull base image
if [[ -z $USE_LOCAL_IMAGE ]]; then
echo "Updating openpilot_base image if needed..."
docker pull ghcr.io/commaai/openpilot-base:latest
fi
# setup .host dir
mkdir -p .devcontainer/.host
# setup links to Xauthority
XAUTHORITY_LINK=".devcontainer/.host/.Xauthority"
rm -f $XAUTHORITY_LINK
if [[ -z $XAUTHORITY ]]; then
echo "XAUTHORITY not set. Fallback to ~/.Xauthority ..."
if ! [[ -f $HOME/.Xauthority ]]; then
echo "~/.XAuthority file does not exist. GUI tools may not work properly."
touch $XAUTHORITY_LINK # dummy file to satisfy container volume mount
else
ln -sf $HOME/.Xauthority $XAUTHORITY_LINK
fi
else
ln -sf $XAUTHORITY $XAUTHORITY_LINK
fi
# setup host env file
HOST_INFO_FILE=".devcontainer/.host/.env"
SYSTEM=$(uname -s | tr '[:upper:]' '[:lower:]')
echo "HOST_OS=\"$SYSTEM\"" > $HOST_INFO_FILE
echo "HOST_DISPLAY=\"$DISPLAY\"" >> $HOST_INFO_FILE
# run virtualgl if macos
if [[ $SYSTEM == "darwin" ]]; then
echo
if [[ -f /opt/VirtualGL/bin/vglclient ]]; then
echo "Starting VirtualGL client at port 10000..."
VGL_LOG_FILE=".devcontainer/.host/.vgl/vglclient.log"
mkdir -p "$(dirname $VGL_LOG_FILE)"
/opt/VirtualGL/bin/vglclient -l "$VGL_LOG_FILE" -display "$DISPLAY" -port 10000 -detach
else
echo "VirtualGL not found. GUI tools may not work properly. Some GUI tools require OpenGL to work properly. To use them with XQuartz on mac, VirtualGL needs to be installed. To install it run:"
echo
echo " brew install --cask virtualgl"
echo
fi
fi
+10
View File
@@ -0,0 +1,10 @@
:: pull base image
IF NOT DEFINED USE_LOCAL_IMAGE ^
echo "Updating openpilot_base image if needed..." && ^
docker pull ghcr.io/commaai/openpilot-base:latest
:: setup .host dir
mkdir .devcontainer\.host
:: setup host env file
echo "" > .devcontainer\.host\.env
+1 -1
View File
@@ -8,7 +8,7 @@ assignees: ''
**Checklist**
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/opcar/docs.py` to generate new docs
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
- [ ] route with openpilot:
- [ ] route with stock system:
+1 -1
View File
@@ -44,7 +44,7 @@ Explain how you tested this bug fix.
**Checklist**
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/opcar/docs.py` to generate new docs
- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py)
- [ ] route with openpilot:
- [ ] route with stock system:
+5 -5
View File
@@ -24,7 +24,7 @@ jobs:
# Check PR target branch
- name: check branch
uses: Vankka/pr-target-branch-action@def32ec9d93514138d6ac0132ee62e120a72aed5
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
@@ -37,17 +37,17 @@ jobs:
# Welcome comment
- name: "First timers PR"
uses: actions/first-interaction@v1
if: github.event.pull_request.head.repo.full_name != 'commaai/openpilot'
if: github.event.pull_request.head.repo.full_name != 'sunnypilot/sunnypilot'
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: |
<!-- _(run_id **${{ github.run_id }}**)_ -->
Thanks for contributing to openpilot! In order for us to review your PR as quickly as possible, check the following:
* Convert your PR to a draft unless it's ready to review
* Read the [contributing docs](https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md)
* Read the [contributing docs](https://github.com/sunnypilot/sunnypilot/blob/master/docs/CONTRIBUTING.md)
* Before marking as "ready for review", ensure:
* the goal is clearly stated in the description
* all the tests are passing
* the change is [something we merge](https://github.com/commaai/openpilot/blob/master/docs/CONTRIBUTING.md#what-gets-merged)
* the change is [something we merge](https://github.com/sunnypilot/sunnypilot/blob/master/docs/CONTRIBUTING.md#what-gets-merged)
* include a route or your device' dongle ID if relevant
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
badges:
name: create badges
runs-on: ubuntu-latest
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
permissions:
contents: write
steps:
@@ -29,7 +29,7 @@ jobs:
git checkout --orphan badges
git rm -rf --cached .
git config user.email "badge-researcher@comma.ai"
git config user.email "badge-researcher@sunnypilot.ai"
git config user.name "Badge Researcher"
git add translation_badge.svg
+2 -2
View File
@@ -15,7 +15,7 @@ env:
jobs:
setup:
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
runs-on: ubuntu-latest
outputs:
ci_runs: ${{ steps.ci_runs_setup.outputs.matrix }}
@@ -31,7 +31,7 @@ jobs:
strategy:
fail-fast: false
matrix: ${{fromJSON(needs.setup.outputs.ci_runs)}}
uses: commaai/openpilot/.github/workflows/ci_weekly_run.yaml@master
uses: sunnypilot/sunnypilot/.github/workflows/ci_weekly_run.yaml@master
with:
run_number: ${{ matrix.run_number }}
+5 -1
View File
@@ -12,6 +12,10 @@ concurrency:
jobs:
selfdrive_tests:
uses: commaai/openpilot/.github/workflows/selfdrive_tests.yaml@master
uses: sunnypilot/sunnypilot/.github/workflows/selfdrive_tests.yaml@master
with:
run_number: ${{ inputs.run_number }}
tools_tests:
uses: sunnypilot/sunnypilot/.github/workflows/tools_tests.yaml@master
with:
run_number: ${{ inputs.run_number }}
+3 -3
View File
@@ -35,13 +35,13 @@ jobs:
# Push to docs.comma.ai
- uses: actions/checkout@v4
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
if: github.ref == 'refs/heads/master' && github.repository == 'sunnypilot/sunnypilot'
with:
path: openpilot-docs
ssh-key: ${{ secrets.OPENPILOT_DOCS_KEY }}
repository: commaai/openpilot-docs
repository: sunnypilot/sunnypilot-docs
- name: Push
if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot'
if: github.ref == 'refs/heads/master' && github.repository == 'sunnypilot/sunnypilot'
run: |
set -x
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
build_prebuilt:
name: build prebuilt
runs-on: ubuntu-latest
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
env:
PUSH_IMAGE: true
permissions:
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
container:
image: ghcr.io/commaai/openpilot-base:latest
runs-on: ubuntu-latest
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
permissions:
checks: read
contents: write
+2 -2
View File
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
container:
image: ghcr.io/commaai/openpilot-base:latest
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
steps:
- uses: actions/checkout@v4
with:
@@ -28,7 +28,7 @@ jobs:
git add .
- name: update car docs
run: |
scons -j$(nproc) --minimal opendbc_repo
scons -j$(nproc) --minimal opendbc
PYTHONPATH=. python selfdrive/car/docs.py
git add docs/CARS.md
- name: Create Pull Request
+60 -28
View File
@@ -4,6 +4,7 @@ on:
push:
branches:
- master
- master-new
pull_request:
workflow_dispatch:
workflow_call:
@@ -14,10 +15,11 @@ on:
type: string
concurrency:
group: selfdrive-tests-ci-run-${{ inputs.run_number }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.run_id || github.head_ref || github.ref }}-${{ github.workflow }}-${{ github.event_name }}
group: selfdrive-tests-ci-run-${{ inputs.run_number }}-${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/master-new') && github.run_id || github.head_ref || github.ref }}-${{ github.workflow }}-${{ github.event_name }}
cancel-in-progress: true
env:
REPORT_NAME: report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/master-new') && 'master' || github.event.number }}
PYTHONWARNINGS: error
BASE_IMAGE: openpilot-base
AZURE_TOKEN: ${{ secrets.AZURE_COMMADATACI_OPENPILOTCI_TOKEN }}
@@ -31,10 +33,11 @@ env:
jobs:
build_release:
if: github.repository == 'commaai/openpilot' # build_release blocked for the time being to only comma as we may have a different process.
name: build release
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }}
env:
STRIPPED_DIR: /tmp/releasepilot
steps:
@@ -52,7 +55,7 @@ jobs:
run: TARGET_DIR=$STRIPPED_DIR release/build_devel.sh
- uses: ./.github/workflows/setup-with-retry
- name: Check submodules
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
timeout-minutes: 3
run: release/check-submodules.sh
- name: Build openpilot and run checks
@@ -75,9 +78,15 @@ jobs:
${{ env.RUN }} "scripts/lint/lint.sh --skip check_added_large_files"
build:
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
strategy:
matrix:
arch: ${{ fromJson(
((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && '["x86_64", "aarch64"]' || '["x86_64"]' ) }}
runs-on: ${{ ((matrix.arch == 'aarch64') && 'namespace-profile-arm64-2x8') ||
((matrix.arch == 'x86_64') && ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16') ||
'ubuntu-latest'}}
steps:
- uses: actions/checkout@v4
with:
@@ -86,14 +95,18 @@ jobs:
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
run: |
echo "PUSH_IMAGE=true" >> "$GITHUB_ENV"
echo "TARGET_ARCHITECTURE=${{ matrix.arch }}" >> "$GITHUB_ENV"
$DOCKER_LOGIN
- uses: ./.github/workflows/setup-with-retry
- uses: ./.github/workflows/compile-openpilot
timeout-minutes: 30
build_mac:
if: github.repository == 'commaai/openpilot' # Blocking macos builds as well since they have a 10x miltiplier for GH action minutes, waaaay too much!
name: build macOS
runs-on: ${{ github.repository == 'commaai/openpilot' && 'namespace-profile-macos-8x14' || 'macos-latest' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }}
steps:
- uses: actions/checkout@v4
with:
@@ -102,6 +115,7 @@ jobs:
uses: ./.github/workflows/auto-cache
with:
path: ~/Library/Caches/Homebrew
key: build_macos_${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}
- name: Install dependencies
run: ./tools/mac_setup.sh
env:
@@ -113,14 +127,32 @@ jobs:
uses: ./.github/workflows/auto-cache
with:
path: /tmp/scons_cache
key: build_macos_${{ hashFiles('.github/workflows/selfdrive_tests.yaml') }}
- name: Building openpilot
run: . .venv/bin/activate && scons -j$(nproc)
docker_push_multiarch:
name: docker push multiarch tag
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'commaai/openpilot'
needs: [build]
steps:
- uses: actions/checkout@v4
with:
submodules: false
- name: Setup docker
run: |
$DOCKER_LOGIN
- name: Merge x64 and arm64 tags
run: |
export PUSH_IMAGE=true
scripts/retry.sh selfdrive/test/docker_tag_multiarch.sh base x86_64 aarch64
static_analysis:
name: static analysis
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
env:
PYTHONWARNINGS: default
steps:
@@ -134,9 +166,9 @@ jobs:
unit_tests:
name: unit tests
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
@@ -161,9 +193,9 @@ jobs:
process_replay:
name: process replay
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4
with:
@@ -214,9 +246,9 @@ jobs:
test_cars:
name: cars
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
@@ -306,9 +338,9 @@ jobs:
simulator_driving:
name: simulator driving
runs-on:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
steps:
- uses: actions/checkout@v4
with:
@@ -327,9 +359,9 @@ 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:
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
- ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-experiments:docker.builds.local-cache=separate' || 'ubuntu-24.04' }}
runs-on: ${{ ((github.repository == 'commaai/openpilot') &&
((github.event_name != 'pull_request') ||
(github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }}
steps:
- uses: actions/checkout@v4
with:
@@ -353,5 +385,5 @@ jobs:
- name: Upload Test Report
uses: actions/upload-artifact@v4
with:
name: report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
name: ${{ env.REPORT_NAME }}
path: selfdrive/ui/tests/test_ui/report_1/screenshots
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
stale-pr-message: 'This PR has had no activity for ${{ env.DAYS_BEFORE_PR_STALE }} days. It will be automatically closed in ${{ env.DAYS_BEFORE_PR_CLOSE }} days if there is no activity.'
close-pr-message: 'This PR has been automatically closed due to inactivity. Feel free to re-open once activity resumes.'
stale-pr-label: stale
delete-branch: ${{ github.event.pull_request.head.repo.full_name == 'commaai/openpilot' }} # only delete branches on the main repo
delete-branch: ${{ github.event.pull_request.head.repo.full_name == 'sunnypilot/sunnypilot' }} # only delete branches on the main repo
exempt-pr-labels: "ignore stale,needs testing" # if wip or it needs testing from the community, don't mark as stale
days-before-pr-stale: ${{ env.DAYS_BEFORE_PR_STALE }}
days-before-pr-close: ${{ env.DAYS_BEFORE_PR_CLOSE }}
+55
View File
@@ -0,0 +1,55 @@
name: tools
on:
push:
branches:
- master
- master-new
pull_request:
workflow_call:
inputs:
run_number:
default: '1'
required: true
type: string
concurrency:
group: tools-tests-ci-run-${{ inputs.run_number }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.run_id || github.head_ref || github.ref }}-${{ github.workflow }}-${{ github.event_name }}
cancel-in-progress: true
env:
BASE_IMAGE: openpilot-base
DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
BUILD: selfdrive/test/docker_build.sh base
RUN: docker run --shm-size 2G -v $GITHUB_WORKSPACE:/tmp/openpilot -w /tmp/openpilot -e FILEREADER_CACHE=1 -e PYTHONPATH=/tmp/openpilot -e NUM_JOBS -e JOB_ID -e GITHUB_ACTION -e GITHUB_REF -e GITHUB_HEAD_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_RUN_ID -v $GITHUB_WORKSPACE/.ci_cache/scons_cache:/tmp/scons_cache -v $GITHUB_WORKSPACE/.ci_cache/comma_download_cache:/tmp/comma_download_cache -v $GITHUB_WORKSPACE/.ci_cache/openpilot_cache:/tmp/openpilot_cache $BASE_IMAGE /bin/bash -c
jobs:
devcontainer:
name: devcontainer
runs-on: ubuntu-latest
if: false # we can re-enable once this is faster
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/workflows/setup-with-retry
- name: Use local image for testing devcontainer with latest base image
run: |
echo "USE_LOCAL_IMAGE=true" >> "$GITHUB_ENV"
- name: Setup Dev Container CLI
run: npm install -g @devcontainers/cli
- name: Build dev container image
run: ./scripts/retry.sh devcontainer build --workspace-folder .
- name: Run dev container
run: |
mkdir -p /tmp/devcontainer_scons_cache/
cp -r $GITHUB_WORKSPACE/.ci_cache/scons_cache/. /tmp/devcontainer_scons_cache/
devcontainer up --workspace-folder .
- name: Test environment
run: |
devcontainer exec --workspace-folder . scons -j$(nproc) cereal/ common/
devcontainer exec --workspace-folder . pip3 install pip-install-test
devcontainer exec --workspace-folder . touch /home/batman/.comma/auth.json
devcontainer exec --workspace-folder . sudo touch /root/test.txt
+12 -10
View File
@@ -3,23 +3,25 @@ on:
push:
branches:
- master
- master-new
pull_request_target:
types: [assigned, opened, synchronize, reopened, edited]
branches:
- 'master'
- 'master-new'
paths:
- 'selfdrive/ui/**'
workflow_dispatch:
env:
UI_JOB_NAME: "Create UI Report"
REPORT_NAME: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }}
SHA: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.sha || github.event.pull_request.head.sha }}
REPORT_NAME: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/master-new') && 'master' || github.event.number }}
SHA: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/master-new') && github.sha || github.event.pull_request.head.sha }}
BRANCH_NAME: "openpilot/pr-${{ github.event.number }}"
jobs:
preview:
if: github.repository == 'commaai/openpilot'
if: github.repository == 'sunnypilot/sunnypilot'
name: preview
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -58,13 +60,13 @@ jobs:
- name: Getting master ui
uses: actions/checkout@v4
with:
repository: commaai/ci-artifacts
repository: sunnypilot/ci-artifacts
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
path: ${{ github.workspace }}/master_ui
ref: openpilot_master_ui
- name: Saving new master ui
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
if: (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/master-new') && github.event_name == 'push'
working-directory: ${{ github.workspace }}/master_ui
run: |
git checkout --orphan=new_master_ui
@@ -106,13 +108,13 @@ jobs:
DIFF="${DIFF}<table>"
DIFF="${DIFF}<tr>"
DIFF="${DIFF} <td> master <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_master_ref.png\"> </td>"
DIFF="${DIFF} <td> proposed <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
DIFF="${DIFF} <td> master <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_master_ref.png\"> </td>"
DIFF="${DIFF} <td> proposed <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
DIFF="${DIFF}</tr>"
DIFF="${DIFF}<tr>"
DIFF="${DIFF} <td> diff <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.png\"> </td>"
DIFF="${DIFF} <td> composite diff <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.gif\"> </td>"
DIFF="${DIFF} <td> diff <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.png\"> </td>"
DIFF="${DIFF} <td> composite diff <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}_diff.gif\"> </td>"
DIFF="${DIFF}</tr>"
DIFF="${DIFF}</table>"
@@ -125,7 +127,7 @@ jobs:
if [[ $INDEX -eq 0 ]]; then
TABLE="${TABLE}<tr>"
fi
TABLE="${TABLE} <td> <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
TABLE="${TABLE} <td> <img src=\"https://raw.githubusercontent.com/sunnypilot/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
if [[ $INDEX -eq 1 || $(($i + 1)) -eq ${#A[*]} ]]; then
TABLE="${TABLE}</tr>"
fi
+6 -6
View File
@@ -1,18 +1,18 @@
[submodule "panda"]
path = panda
url = ../../commaai/panda.git
url = https://github.com/sunnyhaibin/panda.git
[submodule "opendbc"]
path = opendbc_repo
url = ../../commaai/opendbc.git
url = https://github.com/sunnypilot/opendbc.git
[submodule "msgq"]
path = msgq_repo
url = ../../commaai/msgq.git
url = https://github.com/sunnypilot/msgq.git
[submodule "rednose_repo"]
path = rednose_repo
url = ../../commaai/rednose.git
url = https://github.com/commaai/rednose.git
[submodule "teleoprtc_repo"]
path = teleoprtc_repo
url = ../../commaai/teleoprtc
url = https://github.com/commaai/teleoprtc
[submodule "tinygrad"]
path = tinygrad_repo
url = https://github.com/commaai/tinygrad.git
url = https://github.com/tinygrad/tinygrad.git
+7 -4
View File
@@ -68,14 +68,17 @@ RUN usermod -aG sudo $USER
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER $USER
COPY --chown=$USER pyproject.toml uv.lock /home/$USER
COPY --chown=$USER tools/install_python_dependencies.sh /home/$USER/tools/
COPY --chown=$USER pyproject.toml uv.lock /tmp/
COPY --chown=$USER tools/install_python_dependencies.sh /tmp/tools/
ENV VIRTUAL_ENV=/home/$USER/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN cd /home/$USER && \
RUN cd /tmp && \
tools/install_python_dependencies.sh && \
rm -rf tools/ pyproject.toml uv.lock .cache
mkdir -p $VIRTUAL_ENV && \
cp -r /tmp/.venv/* $VIRTUAL_ENV && \
rm -rf /tmp/* && \
rm -rf /home/$USER/.cache
USER root
RUN sudo git config --global --add safe.directory /tmp/openpilot
Vendored
+2 -11
View File
@@ -79,10 +79,6 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps)
return
}
if (isReplay()) {
error("REPLAYING TESTS IS NOT ALLOWED. FIX THEM INSTEAD.")
}
def extra = extra_env.collect { "export ${it}" }.join('\n');
def branch = env.BRANCH_NAME ?: 'master';
def gitDiff = sh returnStdout: true, script: 'curl -s -H "Authorization: Bearer ${GITHUB_COMMENTS_TOKEN}" https://api.github.com/repos/commaai/openpilot/compare/master...${GIT_BRANCH} | jq .files[].filename || echo "/"', label: 'Getting changes'
@@ -127,11 +123,6 @@ def hasPathChanged(String gitDiff, List<String> paths) {
return false
}
def isReplay() {
def replayClass = "org.jenkinsci.plugins.workflow.cps.replay.ReplayCause"
return currentBuild.rawBuild.getCauses().any{ cause -> cause.toString().contains(replayClass) }
}
def setupCredentials() {
withCredentials([
string(credentialsId: 'azure_token', variable: 'AZURE_TOKEN'),
@@ -216,8 +207,8 @@ node {
step("build", "cd system/manager && ./build.py"),
step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", [diffPaths: ["panda", "selfdrive/pandad/"]]),
step("test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"),
step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]),
step("test pigeond", "pytest system/ubloxd/tests/test_pigeond.py", [diffPaths: ["system/ubloxd/"]]),
step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"),
step("test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"),
step("test manager", "pytest system/manager/test/test_manager.py"),
])
},
+21
View File
@@ -0,0 +1,21 @@
# Custom MIT License
Copyright (c) 2024, Haibin Wen, SUNNYPILOT LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to view and modify the Software, subject to the following conditions:
1. **Permission Required**: Permission Required for Commercial, For-Profit, or Closed Source Use: Use of the Software, in whole or in part, for any commercial purposes, for-profit projects, or in closed source projects requires explicit written permission from the original author(s).
2. **Redistribution**: Any redistribution of the Software, modified or unmodified, must retain this license notice and the following acknowledgment:
"This software is licensed under a custom license requiring permission for use."
3. **Visibility**: Any project that uses the Software must visibly mention the following acknowledgment:
"This project uses software from Haibin Wen and SUNNYPILOT LLC and is licensed under a custom license requiring permission for use."
4. **No Warranty**: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Contact sunnypilot Support <support@sunnypilot.ai> for permission requests.
---
Haibin Wen, SUNNYPILOT LLC
-1
View File
@@ -366,7 +366,6 @@ SConscript(['rednose/SConscript'])
# Build system services
SConscript([
'system/ui/SConscript',
'system/proclogd/SConscript',
'system/ubloxd/SConscript',
'system/loggerd/SConscript',
-3
View File
@@ -486,9 +486,6 @@ struct DeviceState @0xa4d8b5af2aa492eb {
nvmeTempC @35 :List(Float32);
modemTempC @36 :List(Float32);
pmicTempC @39 :List(Float32);
intakeTempC @46 :Float32;
exhaustTempC @47 :Float32;
caseTempC @48 :Float32;
maxTempC @44 :Float32; # max of other temps, used to control fan
thermalZones @38 :List(ThermalZone);
thermalStatus @14 :ThermalStatus;
+1 -1
View File
@@ -17,5 +17,5 @@ class TestServices:
def test_generated_header(self):
with tempfile.NamedTemporaryFile(suffix=".h") as f:
ret = os.system(f"python3 {services.__file__} > {f.name} && clang++ {f.name} -std=c++11")
ret = os.system(f"python3 {services.__file__} > {f.name} && clang++ {f.name}")
assert ret == 0, "generated services header is not valid C"
+1
View File
@@ -112,6 +112,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DisablePowerDown", PERSISTENT},
{"DisableUpdates", PERSISTENT},
{"DisengageOnAccelerator", PERSISTENT},
{"DmModelInitialized", CLEAR_ON_ONROAD_TRANSITION},
{"DongleId", PERSISTENT},
{"DoReboot", CLEAR_ON_MANAGER_START},
{"DoShutdown", CLEAR_ON_MANAGER_START},
+1 -1
View File
@@ -13,7 +13,7 @@ public:
if (prefix.empty()) {
prefix = util::random_string(15);
}
msgq_path = Path::shm_path() + "/" + prefix;
msgq_path = "/dev/shm/" + prefix;
bool ret = util::create_directories(msgq_path, 0777);
assert(ret);
setenv("OPENPILOT_PREFIX", prefix.c_str(), 1);
+1 -1
View File
@@ -11,7 +11,7 @@ from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
class OpenpilotPrefix:
def __init__(self, prefix: str = None, clean_dirs_on_exit: bool = True, shared_download_cache: bool = False):
self.prefix = prefix if prefix else str(uuid.uuid4().hex[0:15])
self.msgq_path = os.path.join(Paths.shm_path(), self.prefix)
self.msgq_path = os.path.join('/dev/shm', self.prefix)
self.clean_dirs_on_exit = clean_dirs_on_exit
self.shared_download_cache = shared_download_cache
+2 -6
View File
@@ -48,13 +48,13 @@ class Ratekeeper:
def __init__(self, rate: float, print_delay_threshold: float | None = 0.0) -> None:
"""Rate in Hz for ratekeeping. print_delay_threshold must be nonnegative."""
self._interval = 1. / rate
self._next_frame_time = time.monotonic() + self._interval
self._print_delay_threshold = print_delay_threshold
self._frame = 0
self._remaining = 0.0
self._process_name = getproctitle()
self._dts = deque([self._interval], maxlen=100)
self._last_monitor_time = -1.
self._next_frame_time = -1.
self._last_monitor_time = time.monotonic()
@property
def frame(self) -> int:
@@ -79,10 +79,6 @@ class Ratekeeper:
# Monitors the cumulative lag, but does not enforce a rate
def monitor_time(self) -> bool:
if self._last_monitor_time < 0:
self._next_frame_time = time.monotonic() + self._interval
self._last_monitor_time = time.monotonic()
prev = self._last_monitor_time
self._last_monitor_time = time.monotonic()
self._dts.append(self._last_monitor_time - prev)
+1 -2
View File
@@ -2,9 +2,8 @@
#include "common/watchdog.h"
#include "common/util.h"
#include "system/hardware/hw.h"
const std::string watchdog_fn_prefix = Path::shm_path() + "/wd_"; // + <pid>
const std::string watchdog_fn_prefix = "/dev/shm/wd_"; // + <pid>
bool watchdog_kick(uint64_t ts) {
static std::string fn = watchdog_fn_prefix + std::to_string(getpid());
+2 -2
View File
@@ -167,7 +167,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Lexus|ES 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=ES 2017-18">Buy Here</a></sub></details>||
|Lexus|ES 2019-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=ES 2019-24">Buy Here</a></sub></details>||
|Lexus|ES Hybrid 2017-18|All|openpilot available[<sup>2</sup>](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=ES Hybrid 2017-18">Buy Here</a></sub></details>||
|Lexus|ES Hybrid 2019-25|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=ES Hybrid 2019-25">Buy Here</a></sub></details>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Lexus|ES Hybrid 2019-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=ES Hybrid 2019-24">Buy Here</a></sub></details>|<a href="https://youtu.be/BZ29osRVJeg?t=12" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Lexus|GS F 2016|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=GS F 2016">Buy Here</a></sub></details>||
|Lexus|IS 2017-19|All|Stock|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=IS 2017-19">Buy Here</a></sub></details>||
|Lexus|IS 2022-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 RJ45 cable (7 ft)<br>- 1 Toyota A connector<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lexus&model=IS 2022-23">Buy Here</a></sub></details>||
@@ -188,7 +188,7 @@ A supported vehicle is one that just works when you install a comma device. All
|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Ford Q3 connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Lincoln&model=Aviator Plug-in Hybrid 2020-24">Buy Here</a></sub></details>||
|MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=MAN&model=eTGE 2020-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,12</sup>](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 USB-C coupler<br>- 1 VW J533 connector<br>- 1 angled mount (8 degrees)<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=MAN&model=TGE 2017-24">Buy Here</a></sub></details>|<a href="https://youtu.be/4100gLeabmo" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Mazda|CX-5 2022-25|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Mazda&model=CX-5 2022-25">Buy Here</a></sub></details>||
|Mazda|CX-5 2022-24|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Mazda&model=CX-5 2022-24">Buy Here</a></sub></details>||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 RJ45 cable (7 ft)<br>- 1 comma 3X<br>- 1 comma power v2<br>- 1 harness box<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Mazda&model=CX-9 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
|Nissan|Altima 2019-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Nissan&model=Altima 2019-20">Buy Here</a></sub></details>||
|Nissan|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 RJ45 cable (7 ft)<br>- 1 USB-C coupler<br>- 1 comma 3X<br>- 1 harness box<br>- 1 long OBD-C cable<br>- 1 mount<br>- 1 right angle OBD-C cable (1.5 ft)<br><a href="https://comma.ai/shop/comma-3x.html?make=Nissan&model=Leaf 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg"></img></a>|
+1 -1
View File
@@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1
if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="11.3"
export AGNOS_VERSION="11.2"
fi
export STAGING_ROOT="/data/safe_staging"
+1 -1
Submodule panda updated: c7cc2deaf0...bc5df997f5
+1 -4
View File
@@ -31,9 +31,6 @@ dependencies = [
# body / webrtcd
"aiohttp",
"aiortc",
# aiortc does not put an upper bound on pyopenssl and is now incompatible
# with the latest release
"pyopenssl < 24.3.0",
"pyaudio",
# panda
@@ -101,6 +98,7 @@ dev = [
"azure-identity",
"azure-storage-blob",
"dictdiffer",
"flaky",
"lru-dict",
"matplotlib",
"parameterized >=0.8, <0.9",
@@ -241,7 +239,6 @@ exclude = [
"cereal",
"panda",
"opendbc",
"opendbc_repo",
"rednose_repo",
"tinygrad_repo",
"teleoprtc",
+1
View File
@@ -32,6 +32,7 @@ blacklist = [
".git/",
".github/",
".devcontainer/",
"Darwin/",
".vscode",
+5 -5
View File
@@ -37,7 +37,7 @@ for f in sorted(pyf):
lns = len(src.split("\n"))
tree = ast.parse(src)
Analyzer().visit(tree)
print(f"{lns:5d} {f} {xbit}")
print("%5d %s %s" % (lns, f, xbit))
if 'test' in f:
testlns += lns
elif f.startswith(('tools/', 'scripts/', 'selfdrive/debug')):
@@ -47,8 +47,8 @@ for f in sorted(pyf):
else:
tlns += lns
print(f"{tlns} lines of openpilot python")
print(f"{carlns} lines of car ports")
print(f"{scriptlns} lines of tools/scripts/debug")
print(f"{testlns} lines of tests")
print("%d lines of openpilot python" % tlns)
print("%d lines of car ports" % carlns)
print("%d lines of tools/scripts/debug" % scriptlns)
print("%d lines of tests" % testlns)
#print(sorted(list(imps)))
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env bash
FAIL=0
if grep -n '#include "third_party/raylib/include/raylib\.h"' $@ | grep -v '^system/ui/raylib/raylib\.h'; then
echo -e "Bad raylib include found! Use '#include \"system/ui/raylib/raylib.h\"' instead\n"
FAIL=1
fi
exit $FAIL
+1 -2
View File
@@ -13,7 +13,7 @@ cd $ROOT
FAILED=0
IGNORED_FILES="uv\.lock|docs\/CARS.md"
IGNORED_FILES="uv\.lock|docs\/CARS.md|LICENSE\.md"
IGNORED_DIRS="^third_party.*|^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*"
function run() {
@@ -53,7 +53,6 @@ function run_tests() {
run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES
run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES
run "check_nomerge_comments" $DIR/check_nomerge_comments.sh $ALL_FILES
run "check_raylib_includes" $DIR/check_raylib_includes.sh $ALL_FILES
if [[ -z "$FAST" ]]; then
run "mypy" mypy $PYTHON_FILES
+2 -2
View File
@@ -16,9 +16,9 @@ def waste(core):
j = 0
while 1:
if (i % 100) == 0:
setproctitle(f"{core:3d}: {i:8d}")
setproctitle("%3d: %8d" % (core, i))
lt = time.monotonic()
print(f"{core:3d}: {i:8d} {lt-st:f} {j:.2f}")
print("%3d: %8d %f %.2f" % (core, i, lt-st, j))
st = lt
i += 1
j = np.sum(np.matmul(m1, m2))
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7565541b4e6213221174839b9b2b67397ced0b9807ea56413989fd37325b3b6
size 4908
+1 -1
View File
@@ -17,7 +17,7 @@ class TestCarDocs:
with open(CARS_MD_OUT) as f:
current_cars_md = f.read()
assert generated_cars_md == current_cars_md, "Run selfdrive/car/docs.py to update the compatibility documentation"
assert generated_cars_md == current_cars_md, "Run selfdrive/opcar/docs.py to update the compatibility documentation"
def test_docs_diff(self):
dump_path = os.path.join(BASEDIR, "selfdrive", "car", "tests", "cars_dump")
+1 -1
View File
@@ -28,7 +28,7 @@ def can_printer(bus, max_msg, addr, ascii_decode):
x = binascii.hexlify(msgs[_addr][-1]).decode('ascii')
freq = len(msgs[_addr]) / (time.monotonic() - start)
if max_msg is None or _addr < max_msg:
dd += f"{_addr:04X}({_addr:4d})({len(msgs[_addr]):6d})({freq:3}dHz) {x.ljust(20)} {a}\n"
dd += "%04X(%4d)(%6d)(%3dHz) %s %s\n" % (_addr, _addr, len(msgs[_addr]), freq, x.ljust(20), a)
print(dd)
lp = time.monotonic()
@@ -29,7 +29,7 @@ if __name__ == '__main__':
start_t = time.process_time_ns()
for msg in msgs:
can_list = can_capnp_to_list([msg])
for cp in tm.CI.can_parsers.values():
for cp in tm.CI.can_parsers:
if cp is not None:
cp.update_strings(can_list)
ets.append((time.process_time_ns() - start_t) * 1e-6)
+1 -2
View File
@@ -8,7 +8,6 @@ from typing import cast
from cereal.services import SERVICE_LIST
from openpilot.tools.lib.logreader import LogReader, ReadMode
from openpilot.selfdrive.test.process_replay.migration import migrate_all
if __name__ == "__main__":
cnt_events: Counter = Counter()
@@ -21,7 +20,7 @@ if __name__ == "__main__":
start_time = math.inf
end_time = -math.inf
ignition_off = None
for msg in migrate_all(LogReader(sys.argv[1], ReadMode.QLOG)):
for msg in LogReader(sys.argv[1], ReadMode.QLOG):
t = (msg.logMonoTime - start_time) / 1e9
end_time = max(end_time, msg.logMonoTime)
start_time = min(start_time, msg.logMonoTime)
+1 -1
View File
@@ -22,7 +22,7 @@ def get_fingerprint(lr):
msgs[c.address] = len(c.dat)
# show CAN fingerprint
fingerprint = ', '.join(f"{v[0]}: {v[1]}" for v in sorted(msgs.items()))
fingerprint = ', '.join("%d: %d" % v for v in sorted(msgs.items()))
print(f"\nfound {len(msgs)} messages. CAN fingerprint:\n")
print(fingerprint)
+1 -1
View File
@@ -25,7 +25,7 @@ while True:
if c.src % 0x80 == 0 and c.address < 0x800 and c.address not in (0x7df, 0x7e0, 0x7e8):
msgs[c.address] = len(c.dat)
fingerprint = ', '.join(f"{v[0]}: {v[1]}" for v in sorted(msgs.items()))
fingerprint = ', '.join("%d: %d" % v for v in sorted(msgs.items()))
print(f"number of messages {len(msgs)}:")
print(f"fingerprint {fingerprint}")
@@ -1,3 +1,4 @@
import pytest
import numpy as np
from collections import defaultdict
from enum import Enum
@@ -86,6 +87,8 @@ def run_scenarios(scenario, logs):
return get_select_fields_data(logs), get_select_fields_data(replayed_logs)
@pytest.mark.xdist_group("test_locationd_scenarios")
@pytest.mark.shared_download_cache
class TestLocationdScenarios:
"""
Test locationd with different scenarios. In all these scenarios, we expect the following:
+2
View File
@@ -12,6 +12,7 @@ from cereal import messaging
from cereal.messaging import PubMaster, SubMaster
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
from openpilot.common.swaglog import cloudlog
from openpilot.common.params import Params
from openpilot.common.realtime import set_realtime_priority
from openpilot.selfdrive.modeld.runners import ModelRunner, Runtime
from openpilot.selfdrive.modeld.models.commonmodel_pyx import CLContext
@@ -125,6 +126,7 @@ def main():
cl_context = CLContext()
model = ModelState(cl_context)
cloudlog.warning("models loaded, dmonitoringmodeld starting")
Params().put_bool("DmModelInitialized", True)
cloudlog.warning("connecting to driver stream")
vipc_client = VisionIpcClient("camerad", VisionStreamType.VISION_STREAM_DRIVER, True, cl_context)
+1 -1
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9dc64f5d1e7d6b67f1d4659a3483f03b4324b4c7b969a5ba90c4e37e62bf6fce
oid sha256:663f58026cdf0b5c8e079a8a1591c8e2b5fa7e5c0f29a882011a17c405af10f4
size 50320584
@@ -14,7 +14,7 @@ from openpilot.common.params import Params
from openpilot.common.timeout import Timeout
from openpilot.selfdrive.pandad import can_list_to_can_capnp
from openpilot.system.hardware import TICI
from openpilot.selfdrive.test.helpers import with_processes
from openpilot.selfdrive.test.helpers import phone_only, with_processes
@retry(attempts=3)
@@ -72,6 +72,7 @@ class TestBoarddLoopback:
os.environ['STARTED'] = '1'
os.environ['BOARDD_LOOPBACK'] = '1'
@phone_only
@with_processes(['pandad'])
def test_loopback(self):
num_pandas = 2 if TICI and "SINGLE_PANDA" not in os.environ else 1
+2 -1
View File
@@ -7,7 +7,7 @@ import random
import cereal.messaging as messaging
from cereal.services import SERVICE_LIST
from openpilot.system.hardware import HARDWARE
from openpilot.selfdrive.test.helpers import with_processes
from openpilot.selfdrive.test.helpers import phone_only, with_processes
from openpilot.selfdrive.pandad.tests.test_pandad_loopback import setup_pandad, send_random_can_messages
JUNGLE_SPAM = "JUNGLE_SPAM" in os.environ
@@ -23,6 +23,7 @@ class TestBoarddSpi:
if not JUNGLE_SPAM:
os.environ['BOARDD_LOOPBACK'] = '1'
@phone_only
@with_processes(['pandad'])
def test_spi_corruption(self, subtests):
setup_pandad(1)
+1 -1
View File
@@ -42,7 +42,7 @@ class TestAlerts:
for name, e in events.items():
if not name.endswith("DEPRECATED"):
fail_msg = f"{name} @{e} not in EVENTS"
fail_msg = "%s @%d not in EVENTS" % (name, e)
assert e in EVENTS.keys(), fail_msg
# ensure alert text doesn't exceed allowed width
+9
View File
@@ -10,6 +10,7 @@ from functools import wraps
import cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.system.manager.process_config import managed_processes
from openpilot.system.hardware import PC
from openpilot.system.version import training_version, terms_version
@@ -28,6 +29,14 @@ def set_params_enabled():
msg.liveCalibration.rpyCalib = [0.0, 0.0, 0.0]
params.put("CalibrationParams", msg.to_bytes())
def phone_only(f):
@wraps(f)
def wrap(self, *args, **kwargs):
if PC:
pytest.skip("This test is not meant to run on PC")
return f(self, *args, **kwargs)
return wrap
def release_only(f):
@wraps(f)
def wrap(self, *args, **kwargs):
@@ -5,13 +5,13 @@ import copy
import json
import heapq
import signal
import platform
from collections import Counter, OrderedDict
from dataclasses import dataclass, field
from typing import Any
from collections.abc import Callable, Iterable
from tqdm import tqdm
import capnp
from openpilot.system.hardware.hw import Paths
import cereal.messaging as messaging
from cereal import car
@@ -780,7 +780,8 @@ def generate_params_config(lr=None, CP=None, fingerprint=None, custom_params=Non
def generate_environ_config(CP=None, fingerprint=None, log_dir=None) -> dict[str, Any]:
environ_dict = {}
environ_dict["PARAMS_ROOT"] = f"{Paths.shm_path()}/params"
if platform.system() != "Darwin":
environ_dict["PARAMS_ROOT"] = "/dev/shm/params"
if log_dir is not None:
environ_dict["LOG_ROOT"] = log_dir
+1 -1
View File
@@ -1 +1 @@
255ceb08c75bc85379da5ec247e612be3716fb43
4bf2792e5997c0d916fa9be4442fd4c4901f597a
+2
View File
@@ -110,3 +110,5 @@ if GetOption('extras') and arch != "Darwin":
# build watch3
if arch in ['x86_64', 'aarch64', 'Darwin'] or GetOption('extras'):
qt_env.Program("watch3", ["watch3.cc"], LIBS=qt_libs + ['common', 'msgq', 'visionipc'])
SConscript(['raylib/SConscript'])
-1
View File
@@ -124,7 +124,6 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
// left: PrimeAdWidget
QStackedWidget *left_widget = new QStackedWidget(this);
QVBoxLayout *left_prime_layout = new QVBoxLayout();
left_prime_layout->setContentsMargins(0, 0, 0, 0);
QWidget *prime_user = new PrimeUserWidget();
prime_user->setStyleSheet(R"(
border-radius: 10px;
+1
View File
@@ -0,0 +1 @@
_spinner
+17
View File
@@ -0,0 +1,17 @@
Import('env', 'arch', 'common')
raylib_env = env.Clone()
raylib_util_lib = env.Library("raylib_util_lib", ['util.cc'], LIBS='raylib')
linked_libs = ['raylib', raylib_util_lib, common]
raylib_env['LIBPATH'] += [f'#third_party/raylib/{arch}/']
mac_frameworks = []
if arch == "Darwin":
mac_frameworks += ['OpenCL', 'CoreVideo', 'Cocoa', 'GLUT', 'CoreFoundation', 'OpenGL', 'IOKit']
elif arch == 'larch64':
linked_libs += []
else:
linked_libs += ['OpenCL', 'dl', 'pthread']
if arch != 'aarch64':
raylib_env.Program("_spinner", ["spinner.cc"], LIBS=linked_libs, FRAMEWORKS=mac_frameworks)
@@ -2,7 +2,8 @@
#include <cmath>
#include <iostream>
#include "system/ui/raylib/util.h"
#include "selfdrive/ui/raylib/util.h"
#include "third_party/raylib/include/raylib.h"
constexpr int kProgressBarWidth = 1000;
constexpr int kProgressBarHeight = 20;
@@ -18,15 +19,15 @@ int main(int argc, char *argv[]) {
std::cin.sync_with_stdio(false);
std::cin.tie(nullptr);
Texture2D commaTexture = LoadTextureResized("../../selfdrive/assets/img_spinner_comma.png", kTextureSize);
Texture2D spinnerTexture = LoadTextureResized("../../selfdrive/assets/img_spinner_track.png", kTextureSize);
Texture2D commaTexture = LoadTextureResized("../../assets/img_spinner_comma.png", kTextureSize);
Texture2D spinnerTexture = LoadTextureResized("../../assets/img_spinner_track.png", kTextureSize);
float rotation = 0.0f;
std::string userInput;
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(RAYLIB_BLACK);
ClearBackground(BLACK);
rotation = fmod(rotation + kRotationRate, 360.0f);
Vector2 center = {GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f};
@@ -36,8 +37,8 @@ int main(int argc, char *argv[]) {
// Draw rotating spinner and static comma logo
DrawTexturePro(spinnerTexture, {0, 0, (float)kTextureSize, (float)kTextureSize},
{center.x, center.y, (float)kTextureSize, (float)kTextureSize},
spinnerOrigin, rotation, RAYLIB_WHITE);
DrawTextureV(commaTexture, commaPosition, RAYLIB_WHITE);
spinnerOrigin, rotation, WHITE);
DrawTextureV(commaTexture, commaPosition, WHITE);
// Check for user input
if (std::cin.rdbuf()->in_avail() > 0) {
@@ -49,14 +50,14 @@ int main(int argc, char *argv[]) {
float yPos = GetScreenHeight() - kMargin - kProgressBarHeight;
if (std::all_of(userInput.begin(), userInput.end(), ::isdigit)) {
Rectangle bar = {center.x - kProgressBarWidth / 2.0f, yPos, kProgressBarWidth, kProgressBarHeight};
DrawRectangleRounded(bar, 0.5f, 10, RAYLIB_GRAY);
DrawRectangleRounded(bar, 0.5f, 10, GRAY);
int progress = std::clamp(std::stoi(userInput), 0, 100);
bar.width *= progress / 100.0f;
DrawRectangleRounded(bar, 0.5f, 10, RAYLIB_RAYWHITE);
DrawRectangleRounded(bar, 0.5f, 10, RAYWHITE);
} else {
Vector2 textSize = MeasureTextEx(getFont(), userInput.c_str(), kFontSize, 1.0);
DrawTextEx(getFont(), userInput.c_str(), {center.x - textSize.x / 2, yPos}, kFontSize, 1.0, RAYLIB_WHITE);
DrawTextEx(getFont(), userInput.c_str(), {center.x - textSize.x / 2, yPos}, kFontSize, 1.0, WHITE);
}
}
@@ -1,4 +1,4 @@
#include "system/ui/raylib/util.h"
#include "selfdrive/ui/raylib/util.h"
#include <array>
@@ -23,6 +23,7 @@ struct FontManager {
FontManager() {
for (int i = 0; i < fonts.size(); ++i) {
fonts[i] = LoadFontEx(FONT_FILE_PATHS[i], 120, nullptr, 250);
SetTextureFilter(fonts[i].texture, TEXTURE_FILTER_TRILINEAR);
}
}
@@ -42,6 +43,7 @@ Texture2D LoadTextureResized(const char *fileName, int size) {
Image img = LoadImage(fileName);
ImageResize(&img, size, size);
Texture2D texture = LoadTextureFromImage(img);
SetTextureFilter(texture, TEXTURE_FILTER_TRILINEAR);
return texture;
}
@@ -49,6 +51,6 @@ void initApp(const char *title, int fps) {
Hardware::set_display_power(true);
Hardware::set_brightness(65);
// SetTraceLogLevel(LOG_NONE);
InitWindow(2160, 1080, title);
InitWindow(0, 0, title);
SetTargetFPS(fps);
}
@@ -2,7 +2,7 @@
#include <string>
#include "system/ui/raylib/raylib.h"
#include "third_party/raylib/include/raylib.h"
enum class FontWeight {
Normal,
+38 -47
View File
@@ -54,7 +54,6 @@ RETRY_DELAY = 10 # seconds
MAX_RETRY_COUNT = 30 # Try for at most 5 minutes if upload fails immediately
MAX_AGE = 31 * 24 * 3600 # seconds
WS_FRAME_SIZE = 4096
DEVICE_STATE_UPDATE_INTERVAL = 1.0 # in seconds
NetworkType = log.DeviceState.NetworkType
@@ -100,9 +99,9 @@ send_queue: Queue[str] = queue.Queue()
upload_queue: Queue[UploadItem] = queue.Queue()
low_priority_send_queue: Queue[str] = queue.Queue()
log_recv_queue: Queue[str] = queue.Queue()
cancelled_uploads: set[str] = set()
cur_upload_items: dict[int, UploadItem | None] = {}
cur_upload_items_lock = threading.Lock()
def strip_zst_extension(fn: str) -> str:
@@ -130,9 +129,8 @@ class UploadQueueCache:
@staticmethod
def cache(upload_queue: Queue[UploadItem]) -> None:
try:
with upload_queue.mutex:
items = [asdict(item) for item in upload_queue.queue]
queue: list[UploadItem | None] = list(upload_queue.queue)
items = [asdict(i) for i in queue if i is not None and (i.id not in cancelled_uploads)]
Params().put("AthenadUploadQueue", json.dumps(items))
except Exception:
cloudlog.exception("athena.UploadQueueCache.cache.exception")
@@ -199,13 +197,11 @@ def retry_upload(tid: int, end_event: threading.Event, increase_count: bool = Tr
progress=0,
current=False
)
with cur_upload_items_lock:
upload_queue.put_nowait(item)
cur_upload_items[tid] = None
upload_queue.put_nowait(item)
UploadQueueCache.cache(upload_queue)
cur_upload_items[tid] = None
for _ in range(RETRY_DELAY):
time.sleep(1)
if end_event.is_set():
@@ -215,17 +211,15 @@ def retry_upload(tid: int, end_event: threading.Event, increase_count: bool = Tr
def cb(sm, item, tid, end_event: threading.Event, sz: int, cur: int) -> None:
# Abort transfer if connection changed to metered after starting upload
# or if athenad is shutting down to re-connect the websocket
if not item.allow_cellular:
if (time.monotonic() - sm.recv_time['deviceState']) > DEVICE_STATE_UPDATE_INTERVAL:
sm.update(0)
if sm['deviceState'].networkMetered:
raise AbortTransferException
sm.update(0)
metered = sm['deviceState'].networkMetered
if metered and (not item.allow_cellular):
raise AbortTransferException
if end_event.is_set():
raise AbortTransferException
with cur_upload_items_lock:
cur_upload_items[tid] = replace(item, progress=cur / sz if sz else 1)
cur_upload_items[tid] = replace(item, progress=cur / sz if sz else 1)
def upload_handler(end_event: threading.Event) -> None:
@@ -233,10 +227,14 @@ def upload_handler(end_event: threading.Event) -> None:
tid = threading.get_ident()
while not end_event.is_set():
cur_upload_items[tid] = None
try:
with cur_upload_items_lock:
cur_upload_items[tid] = None
cur_upload_items[tid] = item = replace(upload_queue.get(timeout=1), current=True)
cur_upload_items[tid] = item = replace(upload_queue.get(timeout=1), current=True)
if item.id in cancelled_uploads:
cancelled_uploads.remove(item.id)
continue
# Remove item if too old
age = datetime.now() - datetime.fromtimestamp(item.created_at / 1000)
@@ -260,13 +258,13 @@ def upload_handler(end_event: threading.Event) -> None:
sz = -1
cloudlog.event("athena.upload_handler.upload_start", fn=fn, sz=sz, network_type=network_type, metered=metered, retry_count=item.retry_count)
response = _do_upload(item, partial(cb, sm, item, tid, end_event))
with _do_upload(item, partial(cb, sm, item, tid, end_event)) as response:
if response.status_code not in (200, 201, 401, 403, 412):
cloudlog.event("athena.upload_handler.retry", status_code=response.status_code, fn=fn, sz=sz, network_type=network_type, metered=metered)
retry_upload(tid, end_event)
else:
cloudlog.event("athena.upload_handler.success", fn=fn, sz=sz, network_type=network_type, metered=metered)
if response.status_code not in (200, 201, 401, 403, 412):
cloudlog.event("athena.upload_handler.retry", status_code=response.status_code, fn=fn, sz=sz, network_type=network_type, metered=metered)
retry_upload(tid, end_event)
else:
cloudlog.event("athena.upload_handler.success", fn=fn, sz=sz, network_type=network_type, metered=metered)
UploadQueueCache.cache(upload_queue)
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.SSLError):
@@ -311,16 +309,13 @@ def getMessage(service: str, timeout: int = 1000) -> dict:
raise Exception("invalid service")
socket = messaging.sub_sock(service, timeout=timeout)
try:
ret = messaging.recv_one(socket)
ret = messaging.recv_one(socket)
if ret is None:
raise TimeoutError
if ret is None:
raise TimeoutError
# this is because capnp._DynamicStructReader doesn't have typing information
return cast(dict, ret.to_dict())
finally:
del socket
# this is because capnp._DynamicStructReader doesn't have typing information
return cast(dict, ret.to_dict())
@dispatcher.add_method
@@ -415,10 +410,8 @@ def uploadFilesToUrls(files_data: list[UploadFileDict]) -> UploadFilesToUrlRespo
@dispatcher.add_method
def listUploadQueue() -> list[UploadItemDict]:
with cur_upload_items_lock, upload_queue.mutex:
items = list(upload_queue.queue) + [item for item in cur_upload_items.values() if item is not None]
return [asdict(item) for item in items]
items = list(upload_queue.queue) + list(cur_upload_items.values())
return [asdict(i) for i in items if (i is not None) and (i.id not in cancelled_uploads)]
@dispatcher.add_method
@@ -426,14 +419,13 @@ def cancelUpload(upload_id: str | list[str]) -> dict[str, int | str]:
if not isinstance(upload_id, list):
upload_id = [upload_id]
with upload_queue.mutex:
remaining_items = [item for item in upload_queue.queue if item.id not in upload_id]
if len(remaining_items) == len(upload_queue.queue):
return {"success": 0, "error": "not found"}
uploading_ids = {item.id for item in list(upload_queue.queue)}
cancelled_ids = uploading_ids.intersection(upload_id)
if len(cancelled_ids) == 0:
return {"success": 0, "error": "not found"}
upload_queue.queue.clear()
upload_queue.queue.extend(remaining_items)
return {"success": 1}
cancelled_uploads.update(cancelled_ids)
return {"success": 1}
@dispatcher.add_method
def setRouteViewed(route: str) -> dict[str, int | str]:
@@ -634,9 +626,8 @@ def log_handler(end_event: threading.Event) -> None:
def stat_handler(end_event: threading.Event) -> None:
STATS_DIR = Paths.stats_root()
last_scan = 0.0
while not end_event.is_set():
last_scan = 0.
curr_scan = time.monotonic()
try:
if curr_scan - last_scan > 10:
+7 -3
View File
@@ -78,6 +78,7 @@ class TestAthenadMethods:
athenad.upload_queue = queue.Queue()
athenad.cur_upload_items.clear()
athenad.cancelled_uploads.clear()
for i in os.listdir(Paths.log_root()):
p = os.path.join(Paths.log_root(), i)
@@ -239,7 +240,7 @@ class TestAthenadMethods:
@with_upload_handler
def test_upload_handler_retry(self, mocker, host, status, retry):
mock_put = mocker.patch('requests.put')
mock_put.return_value.__enter__.return_value.status_code = status
mock_put.return_value.status_code = status
fn = self._create_file('qlog.zst')
item = athenad.UploadItem(path=fn, url=f"{host}/qlog.zst", headers={}, created_at=int(time.time()*1000), id='', allow_cellular=True)
@@ -281,10 +282,13 @@ class TestAthenadMethods:
athenad.upload_queue.put_nowait(item)
dispatcher["cancelUpload"](item.id)
assert item.id in athenad.cancelled_uploads
self._wait_for_upload()
time.sleep(0.1)
assert athenad.upload_queue.qsize() == 0
assert len(athenad.cancelled_uploads) == 0
@with_upload_handler
def test_cancel_expiry(self):
@@ -327,7 +331,7 @@ class TestAthenadMethods:
assert items[0] == asdict(item)
assert not items[0]['current']
dispatcher["cancelUpload"](item.id)
athenad.cancelled_uploads.add(item.id)
items = dispatcher["listUploadQueue"]()
assert len(items) == 0
@@ -339,7 +343,7 @@ class TestAthenadMethods:
athenad.upload_queue.put_nowait(item2)
# Ensure canceled items are not persisted
dispatcher["cancelUpload"](item2.id)
athenad.cancelled_uploads.add(item2.id)
# serialize item
athenad.UploadQueueCache.cache(athenad.upload_queue)
+9 -12
View File
@@ -65,19 +65,16 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, SpectraCamera *
const SensorInfo *sensor = cam->sensor.get();
is_raw = cam->is_raw;
camera_bufs_raw = std::make_unique<VisionBuf[]>(frame_buf_count);
frame_metadata = std::make_unique<FrameMetadata[]>(frame_buf_count);
// RAW frames from ISP
if (is_raw) {
camera_bufs_raw = std::make_unique<VisionBuf[]>(frame_buf_count);
const int raw_frame_size = (sensor->frame_height + sensor->extra_height) * sensor->frame_stride;
for (int i = 0; i < frame_buf_count; i++) {
camera_bufs_raw[i].allocate(raw_frame_size);
camera_bufs_raw[i].init_cl(device_id, context);
}
LOGD("allocated %d CL buffers", frame_buf_count);
// RAW + final frames from ISP
const int raw_frame_size = (sensor->frame_height + sensor->extra_height) * sensor->frame_stride;
for (int i = 0; i < frame_buf_count; i++) {
camera_bufs_raw[i].allocate(raw_frame_size);
camera_bufs_raw[i].init_cl(device_id, context);
}
LOGD("allocated %d CL buffers", frame_buf_count);
out_img_width = sensor->frame_width;
out_img_height = sensor->hdr_offset > 0 ? (sensor->frame_height - sensor->hdr_offset) / 2 : sensor->frame_height;
@@ -86,8 +83,8 @@ void CameraBuf::init(cl_device_id device_id, cl_context context, SpectraCamera *
// TODO: VENUS_BUFFER_SIZE should give the size, but it's too small. dependent on encoder settings?
size_t nv12_size = (out_img_width <= 1344 ? 2900 : 2346)*cam->stride;
vipc_server->create_buffers_with_sizes(stream_type, VIPC_BUFFER_COUNT, out_img_width, out_img_height, nv12_size, cam->stride, cam->uv_offset);
LOGD("created %d YUV vipc buffers with size %dx%d", VIPC_BUFFER_COUNT, cam->stride, cam->y_height);
vipc_server->create_buffers_with_sizes(stream_type, YUV_BUFFER_COUNT, out_img_width, out_img_height, nv12_size, cam->stride, cam->uv_offset);
LOGD("created %d YUV vipc buffers with size %dx%d", YUV_BUFFER_COUNT, cam->stride, cam->y_height);
imgproc = new ImgProc(device_id, context, this, sensor, cam->cc.camera_num, cam->stride, cam->uv_offset);
}
+1 -1
View File
@@ -8,7 +8,7 @@
#include "common/util.h"
const int VIPC_BUFFER_COUNT = 18;
const int YUV_BUFFER_COUNT = 20;
typedef struct FrameMetadata {
uint32_t frame_id;
+2 -2
View File
@@ -69,10 +69,10 @@ public:
};
void CameraState::init(VisionIpcServer *v, cl_device_id device_id, cl_context ctx) {
camera.camera_open(v, device_id, ctx);
if (!camera.enabled) return;
camera.camera_open(v, device_id, ctx);
fl_pix = camera.cc.focal_len / camera.sensor->pixel_size_mm;
set_exposure_rect();
+34 -37
View File
@@ -242,9 +242,6 @@ SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config,
cc(config),
is_raw(raw) {
mm.init(m->video0_fd);
ife_buf_depth = is_raw ? 4 : VIPC_BUFFER_COUNT;
assert(ife_buf_depth < MAX_IFE_BUFS);
}
SpectraCamera::~SpectraCamera() {
@@ -264,12 +261,12 @@ int SpectraCamera::clear_req_queue() {
}
void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_context ctx) {
if (!enabled) return;
if (!openSensor()) {
return;
}
if (!enabled) return;
// size is driven by all the HW that handles frames,
// the video encoder has certain alignment requirements in this case
stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, sensor->frame_width);
@@ -291,15 +288,14 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c
linkDevices();
LOGD("camera init %d", cc.camera_num);
buf.init(device_id, ctx, this, v, ife_buf_depth, cc.stream_type);
buf.init(device_id, ctx, this, v, FRAME_BUF_COUNT, cc.stream_type);
camera_map_bufs();
enqueue_req_multi(1, ife_buf_depth, 0);
}
void SpectraCamera::enqueue_req_multi(uint64_t start, int n, bool dp) {
for (uint64_t i = start; i < start + n; ++i) {
request_ids[(i - 1) % ife_buf_depth] = i;
enqueue_buffer((i - 1) % ife_buf_depth, dp);
request_ids[(i - 1) % FRAME_BUF_COUNT] = i;
enqueue_buffer((i - 1) % FRAME_BUF_COUNT, dp);
}
}
@@ -674,7 +670,7 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) {
int ret;
uint64_t request_id = request_ids[i];
if (sync_objs[i]) {
if (buf_handle_raw[i] && sync_objs[i]) {
// wait
struct cam_sync_wait sync_wait = {0};
sync_wait.sync_obj = sync_objs[i];
@@ -737,31 +733,31 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) {
void SpectraCamera::camera_map_bufs() {
int ret;
for (int i = 0; i < ife_buf_depth; i++) {
for (int i = 0; i < FRAME_BUF_COUNT; i++) {
// configure ISP to put the image in place
struct cam_mem_mgr_map_cmd mem_mgr_map_cmd = {0};
mem_mgr_map_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
mem_mgr_map_cmd.mmu_hdls[0] = m->device_iommu;
mem_mgr_map_cmd.num_hdl = 1;
//mem_mgr_map_cmd.mmu_hdls[1] = m->icp_device_iommu;
//mem_mgr_map_cmd.num_hdl = 2;
mem_mgr_map_cmd.num_hdl = 1;
mem_mgr_map_cmd.flags = CAM_MEM_FLAG_HW_READ_WRITE;
if (is_raw) {
// RAW bayer images
mem_mgr_map_cmd.fd = buf.camera_bufs_raw[i].fd;
ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
assert(ret == 0);
LOGD("map buf req: (fd: %d) 0x%x %d", buf.camera_bufs_raw[i].fd, mem_mgr_map_cmd.out.buf_handle, ret);
buf_handle_raw[i] = mem_mgr_map_cmd.out.buf_handle;
} else {
// final processed images
VisionBuf *vb = buf.vipc_server->get_buffer(buf.stream_type, i);
mem_mgr_map_cmd.fd = vb->fd;
ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
LOGD("map buf req: (fd: %d) 0x%x %d", vb->fd, mem_mgr_map_cmd.out.buf_handle, ret);
buf_handle_yuv[i] = mem_mgr_map_cmd.out.buf_handle;
}
// RAW bayer images
mem_mgr_map_cmd.fd = buf.camera_bufs_raw[i].fd;
ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
assert(ret == 0);
LOGD("map buf req: (fd: %d) 0x%x %d", buf.camera_bufs_raw[i].fd, mem_mgr_map_cmd.out.buf_handle, ret);
buf_handle_raw[i] = mem_mgr_map_cmd.out.buf_handle;
// TODO: this needs to match camera bufs length
// final processed images
VisionBuf *vb = buf.vipc_server->get_buffer(buf.stream_type, i);
mem_mgr_map_cmd.fd = vb->fd;
ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_MAP_BUF, &mem_mgr_map_cmd, sizeof(mem_mgr_map_cmd));
LOGD("map buf req: (fd: %d) 0x%x %d", vb->fd, mem_mgr_map_cmd.out.buf_handle, ret);
buf_handle_yuv[i] = mem_mgr_map_cmd.out.buf_handle;
}
enqueue_req_multi(1, FRAME_BUF_COUNT, 0);
}
bool SpectraCamera::openSensor() {
@@ -874,7 +870,7 @@ void SpectraCamera::configISP() {
// allocate IFE memory, then configure it
ife_cmd.init(m, 67984, 0x20,
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE,
m->device_iommu, m->cdm_iommu, ife_buf_depth);
m->device_iommu, m->cdm_iommu, FRAME_BUF_COUNT);
if (!is_raw) {
ife_gamma_lut.init(m, 64*sizeof(uint32_t), 0x20,
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE,
@@ -929,7 +925,7 @@ void SpectraCamera::configICP() {
// BPS CMD buffer
unsigned char striping_out[] = "\x00";
bps_cmd.init(m, ife_buf_depth*ALIGNED_SIZE(464, 0x20), 0x20,
bps_cmd.init(m, FRAME_BUF_COUNT*ALIGNED_SIZE(464, 0x20), 0x20,
CAM_MEM_FLAG_HW_READ_WRITE | CAM_MEM_FLAG_KMD_ACCESS | CAM_MEM_FLAG_UMD_ACCESS | CAM_MEM_FLAG_CMD_BUF_TYPE | CAM_MEM_FLAG_HW_SHARED_ACCESS,
m->icp_device_iommu);
@@ -1050,8 +1046,9 @@ void SpectraCamera::camera_close() {
ret = device_control(csiphy_fd, CAM_RELEASE_DEV, session_handle, csiphy_dev_handle);
LOGD("release csiphy: %d", ret);
for (int i = 0; i < ife_buf_depth; i++) {
release(m->video0_fd, is_raw ? buf_handle_raw[i] : buf_handle_yuv[i]);
for (int i = 0; i < FRAME_BUF_COUNT; i++) {
release(m->video0_fd, buf_handle_yuv[i]);
release(m->video0_fd, buf_handle_raw[i]);
}
LOGD("released buffers");
}
@@ -1074,13 +1071,13 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) {
if (real_id != 0) { // next ready
if (real_id == 1) {idx_offset = main_id;}
int buf_idx = (real_id - 1) % ife_buf_depth;
int buf_idx = (real_id - 1) % FRAME_BUF_COUNT;
// check for skipped frames
if (main_id > frame_id_last + 1 && !skipped) {
LOGE("camera %d realign", cc.camera_num);
clear_req_queue();
enqueue_req_multi(real_id + 1, ife_buf_depth - 1, 0);
enqueue_req_multi(real_id + 1, FRAME_BUF_COUNT - 1, 0);
skipped = true;
} else if (main_id == frame_id_last + 1) {
skipped = false;
@@ -1089,7 +1086,7 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) {
// check for dropped requests
if (real_id > request_id_last + 1) {
LOGE("camera %d dropped requests %ld %ld", cc.camera_num, real_id, request_id_last);
enqueue_req_multi(request_id_last + 1 + ife_buf_depth, real_id - (request_id_last + 1), 0);
enqueue_req_multi(request_id_last + 1 + FRAME_BUF_COUNT, real_id - (request_id_last + 1), 0);
}
// metas
@@ -1102,12 +1099,12 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) {
meta_data.timestamp_sof = timestamp; // this is timestamped in the kernel's SOF IRQ callback
// dispatch
enqueue_req_multi(real_id + ife_buf_depth, 1, 1);
enqueue_req_multi(real_id + FRAME_BUF_COUNT, 1, 1);
} else { // not ready
if (main_id > frame_id_last + 10) {
LOGE("camera %d reset after half second of no response", cc.camera_num);
clear_req_queue();
enqueue_req_multi(request_id_last + 1, ife_buf_depth, 0);
enqueue_req_multi(request_id_last + 1, FRAME_BUF_COUNT, 0);
frame_id_last = main_id;
skipped = true;
}
+6 -7
View File
@@ -12,7 +12,7 @@
#include "system/camerad/cameras/camera_common.h"
#include "system/camerad/sensors/sensor.h"
#define MAX_IFE_BUFS 20
#define FRAME_BUF_COUNT 4
const int MIPI_SETTLE_CNT = 33; // Calculated by camera_freqs.py
@@ -116,7 +116,6 @@ public:
// *** state ***
int ife_buf_depth = -1;
bool open = false;
bool enabled = true;
CameraConfig cc;
@@ -152,11 +151,11 @@ public:
SpectraBuf bps_iq;
SpectraBuf bps_striping;
int buf_handle_yuv[MAX_IFE_BUFS] = {};
int buf_handle_raw[MAX_IFE_BUFS] = {};
int sync_objs[MAX_IFE_BUFS] = {};
int sync_objs_bps_out[MAX_IFE_BUFS] = {};
uint64_t request_ids[MAX_IFE_BUFS] = {};
int buf_handle_yuv[FRAME_BUF_COUNT] = {};
int buf_handle_raw[FRAME_BUF_COUNT] = {};
int sync_objs[FRAME_BUF_COUNT] = {};
int sync_objs_bps_out[FRAME_BUF_COUNT] = {};
uint64_t request_ids[FRAME_BUF_COUNT] = {};
uint64_t request_id_last = 0;
uint64_t frame_id_last = 0;
uint64_t idx_offset = 0;
+35 -37
View File
@@ -1,12 +1,12 @@
import pytest
import time
import numpy as np
from flaky import flaky
from collections import defaultdict
import cereal.messaging as messaging
from cereal import log
from cereal.services import SERVICE_LIST
from openpilot.common.retry import retry
from openpilot.system.manager.process_config import managed_processes
TEST_TIMESPAN = 10
@@ -17,46 +17,44 @@ FRAME_DELTA_TOLERANCE = {log.FrameData.ImageSensor.ar0231: 1.0,
CAMERAS = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState')
@retry(attempts=3, delay=5.0)
def setup_camerad(cls):
# run camerad and record logs
managed_processes['camerad'].start()
time.sleep(3)
socks = {c: messaging.sub_sock(c, conflate=False, timeout=100) for c in CAMERAS}
cls.logs = defaultdict(list)
start_time = time.monotonic()
while time.monotonic()- start_time < TEST_TIMESPAN:
for cam, s in socks.items():
cls.logs[cam] += messaging.drain_sock(s)
time.sleep(0.2)
managed_processes['camerad'].stop()
cls.log_by_frame_id = defaultdict(list)
cls.sensor_type = None
for cam, msgs in cls.logs.items():
if cls.sensor_type is None:
cls.sensor_type = getattr(msgs[0], msgs[0].which()).sensor.raw
expected_frames = SERVICE_LIST[cam].frequency * TEST_TIMESPAN
assert expected_frames*0.95 < len(msgs) < expected_frames*1.05, f"unexpected frame count {cam}: {expected_frames=}, got {len(msgs)}"
dts = np.abs(np.diff([getattr(m, m.which()).timestampSof/1e6 for m in msgs]) - 1000/SERVICE_LIST[cam].frequency)
assert (dts < FRAME_DELTA_TOLERANCE[cls.sensor_type]).all(), f"{cam} dts(ms) out of spec: max diff {dts.max()}, 99 percentile {np.percentile(dts, 99)}"
for m in msgs:
cls.log_by_frame_id[getattr(m, m.which()).frameId].append(m)
# strip beginning and end
for _ in range(3):
mn, mx = min(cls.log_by_frame_id.keys()), max(cls.log_by_frame_id.keys())
del cls.log_by_frame_id[mn]
del cls.log_by_frame_id[mx]
# TODO: this shouldn't be needed
@flaky(max_runs=3)
@pytest.mark.tici
class TestCamerad:
@classmethod
def setup_class(cls):
setup_camerad(cls)
# run camerad and record logs
managed_processes['camerad'].start()
time.sleep(3)
socks = {c: messaging.sub_sock(c, conflate=False, timeout=100) for c in CAMERAS}
cls.logs = defaultdict(list)
start_time = time.monotonic()
while time.monotonic()- start_time < TEST_TIMESPAN:
for cam, s in socks.items():
cls.logs[cam] += messaging.drain_sock(s)
time.sleep(0.2)
managed_processes['camerad'].stop()
cls.log_by_frame_id = defaultdict(list)
cls.sensor_type = None
for cam, msgs in cls.logs.items():
if cls.sensor_type is None:
cls.sensor_type = getattr(msgs[0], msgs[0].which()).sensor.raw
expected_frames = SERVICE_LIST[cam].frequency * TEST_TIMESPAN
assert expected_frames*0.95 < len(msgs) < expected_frames*1.05, f"unexpected frame count {cam}: {expected_frames=}, got {len(msgs)}"
dts = np.abs(np.diff([getattr(m, m.which()).timestampSof/1e6 for m in msgs]) - 1000/SERVICE_LIST[cam].frequency)
assert (dts < FRAME_DELTA_TOLERANCE[cls.sensor_type]).all(), f"{cam} dts(ms) out of spec: max diff {dts.max()}, 99 percentile {np.percentile(dts, 99)}"
for m in msgs:
cls.log_by_frame_id[getattr(m, m.which()).frameId].append(m)
# strip beginning and end
for _ in range(3):
mn, mx = min(cls.log_by_frame_id.keys()), max(cls.log_by_frame_id.keys())
del cls.log_by_frame_id[mn]
del cls.log_by_frame_id[mx]
def test_frame_skips(self):
skips = {}
+2 -3
View File
@@ -1,14 +1,12 @@
import time
import numpy as np
import pytest
from openpilot.selfdrive.test.helpers import with_processes
from openpilot.selfdrive.test.helpers import with_processes, phone_only
from openpilot.system.camerad.snapshot.snapshot import get_snapshots
TEST_TIME = 45
REPEAT = 5
@pytest.mark.tici
class TestCamerad:
@classmethod
def setup_class(cls):
@@ -30,6 +28,7 @@ class TestCamerad:
print([i_median, i_mean])
return med_ex[0] < i_median < med_ex[1] and mean_ex[0] < i_mean < mean_ex[1]
@phone_only
@with_processes(['camerad'])
def test_camera_operation(self):
passed = 0
+4 -46
View File
@@ -1,54 +1,11 @@
import os
from abc import abstractmethod, ABC
from dataclasses import dataclass, fields
from collections import namedtuple
from cereal import log
ThermalConfig = namedtuple('ThermalConfig', ['cpu', 'gpu', 'mem', 'bat', 'pmic'])
NetworkType = log.DeviceState.NetworkType
@dataclass
class ThermalZone:
# a zone from /sys/class/thermal/thermal_zone*
name: str # a.k.a type
scale: float = 1000. # scale to get degrees in C
zone_number = -1
def read(self) -> float:
if self.zone_number < 0:
for n in os.listdir("/sys/devices/virtual/thermal"):
if not n.startswith("thermal_zone"):
continue
with open(os.path.join("/sys/devices/virtual/thermal", n, "type")) as f:
if f.read().strip() == self.name:
self.zone_number = int(n.removeprefix("thermal_zone"))
break
try:
with open(f"/sys/devices/virtual/thermal/thermal_zone{self.zone_number}/temp") as f:
return int(f.read()) / self.scale
except FileNotFoundError:
return 0
@dataclass
class ThermalConfig:
cpu: list[ThermalZone] | None = None
gpu: list[ThermalZone] | None = None
pmic: list[ThermalZone] | None = None
memory: ThermalZone | None = None
intake: ThermalZone | None = None
exhaust: ThermalZone | None = None
case: ThermalZone | None = None
def get_msg(self):
ret = {}
for f in fields(ThermalConfig):
v = getattr(self, f.name)
if v is not None:
if isinstance(v, list):
ret[f.name + "TempC"] = [x.read() for x in v]
else:
ret[f.name + "TempC"] = v.read()
return ret
class HardwareBase(ABC):
@staticmethod
@@ -127,8 +84,9 @@ class HardwareBase(ABC):
def shutdown(self):
pass
@abstractmethod
def get_thermal_config(self):
return ThermalConfig()
pass
@abstractmethod
def set_screen_brightness(self, percentage):
+37 -5
View File
@@ -51,6 +51,39 @@ OFFROAD_DANGER_TEMP = 75
prev_offroad_states: dict[str, tuple[bool, str | None]] = {}
tz_by_type: dict[str, int] | None = None
def populate_tz_by_type():
global tz_by_type
tz_by_type = {}
for n in os.listdir("/sys/devices/virtual/thermal"):
if not n.startswith("thermal_zone"):
continue
with open(os.path.join("/sys/devices/virtual/thermal", n, "type")) as f:
tz_by_type[f.read().strip()] = int(n.removeprefix("thermal_zone"))
def read_tz(x):
if x is None:
return 0
if isinstance(x, str):
if tz_by_type is None:
populate_tz_by_type()
x = tz_by_type[x]
try:
with open(f"/sys/devices/virtual/thermal/thermal_zone{x}/temp") as f:
return int(f.read())
except FileNotFoundError:
return 0
def read_thermal(thermal_config):
dat = messaging.new_message('deviceState', valid=True)
dat.deviceState.cpuTempC = [read_tz(z) / thermal_config.cpu[1] for z in thermal_config.cpu[0]]
dat.deviceState.gpuTempC = [read_tz(z) / thermal_config.gpu[1] for z in thermal_config.gpu[0]]
dat.deviceState.memoryTempC = read_tz(thermal_config.mem[0]) / thermal_config.mem[1]
dat.deviceState.pmicTempC = [read_tz(z) / thermal_config.pmic[1] for z in thermal_config.pmic[0]]
return dat
def set_offroad_alert_if_changed(offroad_alert: str, show_alert: bool, extra_text: str | None=None):
@@ -199,8 +232,7 @@ def hardware_thread(end_event, hw_queue) -> None:
if (sm.frame % round(SERVICE_LIST['pandaStates'].frequency * DT_HW) != 0) and not ign_edge:
continue
msg = messaging.new_message('deviceState', valid=True)
msg.deviceState = thermal_config.get_msg()
msg = read_thermal(thermal_config)
msg.deviceState.deviceType = HARDWARE.get_device_type()
try:
@@ -230,13 +262,13 @@ def hardware_thread(end_event, hw_queue) -> None:
# this subset is only used for offroad
temp_sources = [
msg.deviceState.memoryTempC,
max(msg.deviceState.cpuTempC, default=0.),
max(msg.deviceState.gpuTempC, default=0.),
max(msg.deviceState.cpuTempC),
max(msg.deviceState.gpuTempC),
]
offroad_comp_temp = offroad_temp_filter.update(max(temp_sources))
# this drives the thermal status while onroad
temp_sources.append(max(msg.deviceState.pmicTempC, default=0.))
temp_sources.append(max(msg.deviceState.pmicTempC))
all_comp_temp = all_temp_filter.update(max(temp_sources))
msg.deviceState.maxTempC = all_comp_temp
-8
View File
@@ -47,12 +47,4 @@ namespace Path {
}
return "/tmp/comma_download_cache" + Path::openpilot_prefix() + "/";
}
inline std::string shm_path() {
#ifdef __APPLE__
return"/tmp";
#else
return "/dev/shm";
#endif
}
} // namespace Path
-7
View File
@@ -1,5 +1,4 @@
import os
import platform
from pathlib import Path
from openpilot.system.hardware import PC
@@ -57,9 +56,3 @@ class Paths:
return Paths.comma_home()
else:
return "/tmp/.comma"
@staticmethod
def shm_path() -> str:
if PC and platform.system() == "Darwin":
return "/tmp" # This is not really shared memory on macOS, but it's the closest we can get
return "/dev/shm"
+5 -2
View File
@@ -1,7 +1,7 @@
import random
from cereal import log
from openpilot.system.hardware.base import HardwareBase
from openpilot.system.hardware.base import HardwareBase, ThermalConfig
NetworkType = log.DeviceState.NetworkType
NetworkStrength = log.DeviceState.NetworkStrength
@@ -21,7 +21,7 @@ class Pc(HardwareBase):
print("uninstall")
def get_imei(self, slot):
return f"{random.randint(0, 1 << 32):015d}"
return "%015d" % random.randint(0, 1 << 32)
def get_serial(self):
return "cccccccc"
@@ -53,6 +53,9 @@ class Pc(HardwareBase):
def shutdown(self):
print("SHUTDOWN!")
def get_thermal_config(self):
return ThermalConfig(cpu=((None,), 1), gpu=((None,), 1), mem=(None, 1), bat=(None, 1), pmic=((None,), 1))
def set_screen_brightness(self, percentage):
pass
+19 -19
View File
@@ -1,19 +1,19 @@
[
{
"name": "boot",
"url": "https://commadist.azureedge.net/agnosupdate/boot-45e107ad65e6cc9ee95dc139f9ed11d56ef7f5f0657f579498a4a48f0a2f7ea3.img.xz",
"hash": "45e107ad65e6cc9ee95dc139f9ed11d56ef7f5f0657f579498a4a48f0a2f7ea3",
"hash_raw": "45e107ad65e6cc9ee95dc139f9ed11d56ef7f5f0657f579498a4a48f0a2f7ea3",
"size": 16418816,
"url": "https://commadist.azureedge.net/agnosupdate-staging/boot-184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a.img.xz",
"hash": "184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a",
"hash_raw": "184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a",
"size": 16414720,
"sparse": false,
"full_check": true,
"has_ab": true
},
{
"name": "system",
"url": "https://commadist.azureedge.net/agnosupdate/system-c0d738052c77f97b10bcea111479ddabd3fde2653d50533dd0fa2b17bb7881e9.img.xz",
"hash": "c0d738052c77f97b10bcea111479ddabd3fde2653d50533dd0fa2b17bb7881e9",
"hash_raw": "c0d738052c77f97b10bcea111479ddabd3fde2653d50533dd0fa2b17bb7881e9",
"url": "https://commadist.azureedge.net/agnosupdate-staging/system-93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea.img.xz",
"hash": "93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea",
"hash_raw": "93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea",
"size": 4404019200,
"sparse": false,
"full_check": false,
@@ -21,9 +21,9 @@
},
{
"name": "xbl",
"url": "https://commadist.azureedge.net/agnosupdate/xbl-bece486a68d9470c165e87955e451339cd86ada6ca2c7fde13c49144624ce030.img.xz",
"hash": "bece486a68d9470c165e87955e451339cd86ada6ca2c7fde13c49144624ce030",
"hash_raw": "bece486a68d9470c165e87955e451339cd86ada6ca2c7fde13c49144624ce030",
"url": "https://commadist.azureedge.net/agnosupdate/xbl-446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050.img.xz",
"hash": "446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050",
"hash_raw": "446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050",
"size": 3282256,
"sparse": false,
"full_check": true,
@@ -41,9 +41,9 @@
},
{
"name": "xbl_config",
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-868b6f9aa98871dc50ef191a2d8f432578d1eca84f87d9185f8fb61242c3b66f.img.xz",
"hash": "868b6f9aa98871dc50ef191a2d8f432578d1eca84f87d9185f8fb61242c3b66f",
"hash_raw": "868b6f9aa98871dc50ef191a2d8f432578d1eca84f87d9185f8fb61242c3b66f",
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995.img.xz",
"hash": "80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995",
"hash_raw": "80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995",
"size": 98124,
"sparse": false,
"full_check": true,
@@ -51,9 +51,9 @@
},
{
"name": "devcfg",
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-c27dc9ab628015ef265e1204ca736b2838ec179e9ecdd79e2ddb59d984b78df1.img.xz",
"hash": "c27dc9ab628015ef265e1204ca736b2838ec179e9ecdd79e2ddb59d984b78df1",
"hash_raw": "c27dc9ab628015ef265e1204ca736b2838ec179e9ecdd79e2ddb59d984b78df1",
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8.img.xz",
"hash": "8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8",
"hash_raw": "8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8",
"size": 40336,
"sparse": false,
"full_check": true,
@@ -61,9 +61,9 @@
},
{
"name": "aop",
"url": "https://commadist.azureedge.net/agnosupdate/aop-588bb60f0f8194d2df12f041e320a6dfeafae7209b312be3e4f6fe0744192837.img.xz",
"hash": "588bb60f0f8194d2df12f041e320a6dfeafae7209b312be3e4f6fe0744192837",
"hash_raw": "588bb60f0f8194d2df12f041e320a6dfeafae7209b312be3e4f6fe0744192837",
"url": "https://commadist.azureedge.net/agnosupdate/aop-c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4.img.xz",
"hash": "c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4",
"hash_raw": "c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4",
"size": 184364,
"sparse": false,
"full_check": true,
+14 -24
View File
@@ -10,7 +10,7 @@ from pathlib import Path
from cereal import log
from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action
from openpilot.system.hardware.base import HardwareBase, ThermalConfig, ThermalZone
from openpilot.system.hardware.base import HardwareBase, ThermalConfig
from openpilot.system.hardware.tici import iwlist
from openpilot.system.hardware.tici.pins import GPIO
from openpilot.system.hardware.tici.amplifier import Amplifier
@@ -323,19 +323,12 @@ class Tici(HardwareBase):
os.system("sudo poweroff")
def get_thermal_config(self):
intake, exhaust, case = None, None, None
if self.get_device_type() == "mici":
case = ThermalZone("case")
intake = ThermalZone("intake")
exhaust = ThermalZone("exhaust")
return ThermalConfig(cpu=[ThermalZone(f"cpu{i}-silver-usr") for i in range(4)] +
[ThermalZone(f"cpu{i}-gold-usr") for i in range(4)],
gpu=[ThermalZone("gpu0-usr"), ThermalZone("gpu1-usr")],
memory=ThermalZone("ddr-usr"),
pmic=[ThermalZone("pm8998_tz"), ThermalZone("pm8005_tz")],
intake=intake,
exhaust=exhaust,
case=case)
return ThermalConfig(cpu=(["cpu%d-silver-usr" % i for i in range(4)] +
["cpu%d-gold-usr" % i for i in range(4)], 1000),
gpu=(("gpu0-usr", "gpu1-usr"), 1000),
mem=("ddr-usr", 1000),
bat=(None, 1),
pmic=(("pm8998_tz", "pm8005_tz"), 1000))
def set_screen_brightness(self, percentage):
try:
@@ -487,16 +480,14 @@ class Tici(HardwareBase):
'AT$QCNETDEVCTL=3,1',
]
else:
# this modem gets upset with too many AT commands
if sim_id is None or len(sim_id) == 0:
cmds += [
# SIM sleep disable
'AT$QCSIMSLEEP=0',
'AT$QCSIMCFG=SimPowerSave,0',
cmds += [
# SIM sleep disable
'AT$QCSIMSLEEP=0',
'AT$QCSIMCFG=SimPowerSave,0',
# ethernet config
'AT$QCPCFG=usbNet,1',
]
# ethernet config
'AT$QCPCFG=usbNet,1',
]
for cmd in cmds:
try:
@@ -595,4 +586,3 @@ if __name__ == "__main__":
t.configure_modem()
t.initialize_hardware()
t.set_power_save(False)
print(t.get_sim_info())
+3 -3
View File
@@ -17,7 +17,7 @@ from openpilot.system.manager.process_config import managed_processes
from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID
from openpilot.common.swaglog import cloudlog, add_file_handler
from openpilot.system.version import get_build_metadata, terms_version, training_version
from openpilot.system.hardware.hw import Paths
def manager_init() -> None:
@@ -52,11 +52,11 @@ def manager_init() -> None:
# Create folders needed for msgq
try:
os.mkdir(Paths.shm_path())
os.mkdir("/dev/shm")
except FileExistsError:
pass
except PermissionError:
print(f"WARNING: failed to make {Paths.shm_path()}")
print("WARNING: failed to make /dev/shm")
# set version params
params.put("Version", build_metadata.openpilot.version)
+1 -2
View File
@@ -16,9 +16,8 @@ import openpilot.system.sentry as sentry
from openpilot.common.basedir import BASEDIR
from openpilot.common.params import Params
from openpilot.common.swaglog import cloudlog
from openpilot.system.hardware.hw import Paths
WATCHDOG_FN = f"{Paths.shm_path()}/wd_"
WATCHDOG_FN = "/dev/shm/wd_"
ENABLE_WATCHDOG = os.getenv("NO_WATCHDOG") is None
+1
View File
@@ -89,6 +89,7 @@ procs = [
PythonProcess("deleter", "system.loggerd.deleter", always_run),
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(not PC or WEBCAM)),
PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI),
#PythonProcess("ugpsd", "system.ugpsd", only_onroad, enabled=TICI),
PythonProcess("pandad", "selfdrive.pandad.pandad", always_run),
PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad),
NativeProcess("ubloxd", "system/ubloxd", ["./ubloxd"], ublox, enabled=TICI),
+2 -2
View File
@@ -273,7 +273,7 @@ def main() -> NoReturn:
(pending_msgs, log_outer_length), inner_log_packet = unpack_from('<BH', payload), payload[calcsize('<BH'):]
if pending_msgs > 0:
cloudlog.debug(f"have {pending_msgs} pending messages")
cloudlog.debug("have %d pending messages" % pending_msgs)
assert log_outer_length == len(inner_log_packet)
(log_inner_length, log_type, log_time), log_payload = unpack_from('<HHQ', inner_log_packet), inner_log_packet[calcsize('<HHQ'):]
@@ -283,7 +283,7 @@ def main() -> NoReturn:
continue
if DEBUG:
print(f"{time.time():.4f}: got log: {log_type} len {len(log_payload)}")
print("%.4f: got log: %x len %d" % (time.time(), log_type, len(log_payload)))
if log_type == LOG_GNSS_OEMDRE_MEASUREMENT_REPORT:
msg = messaging.new_message('qcomGnss', valid=True)
+1 -1
View File
@@ -322,7 +322,7 @@ def parse_struct(ss):
cnt = int(nam.split("[")[1].split("]")[0])
st += st[-1]*(cnt-1)
for i in range(cnt):
nams.append(f'{nam.split("[")[0]}[{i}]')
nams.append("%s[%d]" % (nam.split("[")[0], i))
else:
nams.append(nam)
return st, nams
+1 -1
View File
@@ -13,7 +13,7 @@ if __name__ == "__main__":
cnos = []
for m in ug.measurementReport.measurements:
cnos.append(m.cno)
print(f"Sats: {ug.measurementReport.numMeas} Accuracy: {gle.horizontalAccuracy:.2f} m cnos", sorted(cnos))
print("Sats: %d Accuracy: %.2f m cnos" % (ug.measurementReport.numMeas, gle.horizontalAccuracy), sorted(cnos))
except Exception:
pass
sm.update()
-1
View File
@@ -1 +0,0 @@
spinner
-23
View File
@@ -1,23 +0,0 @@
import subprocess
Import('env', 'arch', 'common')
renv = env.Clone()
UBUNTU_FOCAL = int(subprocess.check_output('[ -f /etc/os-release ] && . /etc/os-release && [ "$ID" = "ubuntu" ] && [ "$VERSION_ID" = "20.04" ] && echo 1 || echo 0', shell=True, encoding='utf-8').rstrip())
if not UBUNTU_FOCAL:
rayutil = env.Library("rayutil", ['raylib/util.cc'], LIBS='raylib')
linked_libs = ['raylib', rayutil, common]
renv['LIBPATH'] += [f'#third_party/raylib/{arch}/']
mac_frameworks = []
if arch == "Darwin":
mac_frameworks += ['OpenCL', 'CoreVideo', 'Cocoa', 'GLUT', 'CoreFoundation', 'OpenGL', 'IOKit']
elif arch == 'larch64':
linked_libs += ['GLESv2', 'GL', 'EGL', 'wayland-client', 'wayland-egl']
else:
linked_libs += ['OpenCL', 'dl', 'pthread']
if arch != 'aarch64':
renv.Program("spinner", ["raylib/spinner.cc"], LIBS=linked_libs, FRAMEWORKS=mac_frameworks)
-5
View File
@@ -1,5 +0,0 @@
#pragma once
#define OPENPILOT_RAYLIB
#include "third_party/raylib/include/raylib.h"
+138 -242
View File
@@ -1,22 +1,22 @@
/**********************************************************************************************
*
* raylib v5.6-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* raylib v5.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
*
* FEATURES:
* - NO external dependencies, all required libraries included with raylib
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly,
* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5.
* - Written in plain C code (C99) in PascalCase/camelCase notation
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile)
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile)
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
* - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts)
* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts)
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
* - Flexible Materials system, supporting classic maps and PBR maps
* - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF)
* - Animated 3D models supported (skeletal bones animation) (IQM)
* - Shaders support, including Model shaders and Postprocessing shaders
* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, QOA, XM, MOD)
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
* - VR stereo rendering with configurable HMD device parameters
* - Bindings to multiple programming languages available!
*
@@ -27,35 +27,29 @@
* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
*
* DEPENDENCIES (included):
* [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input
* [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input
* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading
* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP)
* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management
*
* OPTIONAL DEPENDENCIES (included):
* [rcore] msf_gif (Miles Fogle) for GIF recording
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation
* [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
* [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms
* [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
* [rtext] stb_truetype (Sean Barret) for ttf fonts loading
* [rtext] stb_rect_pack (Sean Barret) for rectangles packing
* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation
* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF)
* [rmodels] m3d (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
* [rmodels] vox_loader (Johann Nadalutti) for models loading (VOX)
* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
* [raudio] dr_wav (David Reid) for WAV audio file loading
* [raudio] dr_flac (David Reid) for FLAC audio file loading
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
* [raudio] stb_vorbis (Sean Barret) for OGG audio loading
* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading
* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading
* [raudio] qoa (Dominic Szablewski - https://phoboslab.org) for QOA audio manage
*
*
* LICENSE: zlib/libpng
@@ -63,7 +57,7 @@
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
* Copyright (c) 2013-2024 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -88,26 +82,21 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION_MAJOR 5
#define RAYLIB_VERSION_MINOR 6
#define RAYLIB_VERSION_MINOR 0
#define RAYLIB_VERSION_PATCH 0
#define RAYLIB_VERSION "5.6-dev"
#define RAYLIB_VERSION "5.0"
// Function specifiers in case library is build/used as a shared library
// Function specifiers in case library is build/used as a shared library (Windows)
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden
#if defined(_WIN32)
#if defined(__TINYC__)
#define __declspec(x) __attribute__((x))
#endif
#if defined(BUILD_LIBTYPE_SHARED)
#if defined(__TINYC__)
#define __declspec(x) __attribute__((x))
#endif
#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
#elif defined(USE_LIBTYPE_SHARED)
#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
#endif
#else
#if defined(BUILD_LIBTYPE_SHARED)
#define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib)
#endif
#endif
#ifndef RLAPI
@@ -172,91 +161,33 @@
// Some Basic Colors
// NOTE: Custom raylib color palette for amazing visuals on WHITE background
#define _rl_LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
#define _rl_GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray
#define _rl_DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray
#define _rl_YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow
#define _rl_GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold
#define _rl_ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange
#define _rl_PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink
#define _rl_RED CLITERAL(Color){ 230, 41, 55, 255 } // Red
#define _rl_MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon
#define _rl_GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green
#define _rl_LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime
#define _rl_DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green
#define _rl_SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue
#define _rl_BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue
#define _rl_DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue
#define _rl_PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple
#define _rl_VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet
#define _rl_DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple
#define _rl_BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige
#define _rl_BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown
#define _rl_DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown
#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
#define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray
#define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray
#define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow
#define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold
#define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange
#define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink
#define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red
#define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon
#define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green
#define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime
#define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green
#define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue
#define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue
#define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue
#define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple
#define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet
#define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple
#define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige
#define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown
#define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown
#define _rl_WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White
#define _rl_BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black
#define _rl_BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent)
#define _rl_MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta
#define _rl_RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#ifndef OPENPILOT_RAYLIB
#define LIGHTGRAY _rl_LIGHTGRAY
#define GRAY _rl_GRAY
#define DARKGRAY _rl_DARKGRAY
#define YELLOW _rl_YELLOW
#define GOLD _rl_GOLD
#define ORANGE _rl_ORANGE
#define PINK _rl_PINK
#define RED _rl_RED
#define MAROON _rl_MAROON
#define GREEN _rl_GREEN
#define LIME _rl_LIME
#define DARKGREEN _rl_DARKGREEN
#define SKYBLUE _rl_SKYBLUE
#define BLUE _rl_BLUE
#define DARKBLUE _rl_DARKBLUE
#define PURPLE _rl_PURPLE
#define VIOLET _rl_VIOLET
#define DARKPURPLE _rl_DARKBLUE
#define BEIGE _rl_BEIGE
#define BROWN _rl_BROWN
#define DARKBROWN _rl_DARKBROWN
#define WHITE _rl_WHITE
#define BLACK _rl_BLACK
#define BLANK _rl_BLANK
#define MAGENTA _rl_MAGENTA
#define RAYWHITE _rl_RAYWHITE
#else
#define RAYLIB_LIGHTGRAY _rl_LIGHTGRAY
#define RAYLIB_GRAY _rl_GRAY
#define RAYLIB_DARKGRAY _rl_DARKGRAY
#define RAYLIB_YELLOW _rl_YELLOW
#define RAYLIB_GOLD _rl_GOLD
#define RAYLIB_ORANGE _rl_ORANGE
#define RAYLIB_PINK _rl_PINK
#define RAYLIB_RED _rl_RED
#define RAYLIB_MAROON _rl_MAROON
#define RAYLIB_GREEN _rl_GREEN
#define RAYLIB_LIME _rl_LIME
#define RAYLIB_DARKGREEN _rl_DARKGREEN
#define RAYLIB_SKYBLUE _rl_SKYBLUE
#define RAYLIB_BLUE _rl_BLUE
#define RAYLIB_DARKBLUE _rl_DARKBLUE
#define RAYLIB_PURPLE _rl_PURPLE
#define RAYLIB_VIOLET _rl_VIOLET
#define RAYLIB_DARKPURPLE _rl_DARKBLUE
#define RAYLIB_BEIGE _rl_BEIGE
#define RAYLIB_BROWN _rl_BROWN
#define RAYLIB_DARKBROWN _rl_DARKBROWN
#define RAYLIB_WHITE _rl_WHITE
#define RAYLIB_BLACK _rl_BLACK
#define RAYLIB_BLANK _rl_BLANK
#define RAYLIB_MAGENTA _rl_MAGENTA
#define RAYLIB_RAYWHITE _rl_RAYWHITE
#endif
#define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White
#define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black
#define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent)
#define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta
#define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo)
//----------------------------------------------------------------------------------
// Structures Definition
@@ -416,10 +347,8 @@ typedef struct Mesh {
// Animation vertex data
float *animVertices; // Animated vertex positions (after bones transformations)
float *animNormals; // Animated normals (after bones transformations)
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)
Matrix *boneMatrices; // Bones animated transformation matrices
int boneCount; // Number of bones
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
// OpenGL identifiers
unsigned int vaoId; // OpenGL Vertex Array Object id
@@ -487,7 +416,7 @@ typedef struct ModelAnimation {
// Ray, ray for raycasting
typedef struct Ray {
Vector3 position; // Ray position (origin)
Vector3 direction; // Ray direction (normalized)
Vector3 direction; // Ray direction
} Ray;
// RayCollision, ray hit information
@@ -550,6 +479,7 @@ typedef struct VrDeviceInfo {
int vResolution; // Vertical resolution in pixels
float hScreenSize; // Horizontal size in meters
float vScreenSize; // Vertical size in meters
float vScreenCenter; // Screen center in meters
float eyeToScreenDistance; // Distance between eye and display in meters
float lensSeparationDistance; // Lens separation distance in meters
float interpupillaryDistance; // IPD (distance between pupils) in meters
@@ -743,7 +673,7 @@ typedef enum {
KEY_KP_EQUAL = 336, // Key: Keypad =
// Android key buttons
KEY_BACK = 4, // Key: Android back button
KEY_MENU = 5, // Key: Android menu button
KEY_MENU = 82, // Key: Android menu button
KEY_VOLUME_UP = 24, // Key: Android volume up button
KEY_VOLUME_DOWN = 25 // Key: Android volume down button
} KeyboardKey;
@@ -787,12 +717,12 @@ typedef enum {
GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button
GAMEPAD_BUTTON_LEFT_FACE_LEFT, // Gamepad left DPAD left button
GAMEPAD_BUTTON_RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y)
GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B)
GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Square, Xbox: X)
GAMEPAD_BUTTON_RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A)
GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X)
GAMEPAD_BUTTON_RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Circle, Xbox: B)
GAMEPAD_BUTTON_LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button
GAMEPAD_BUTTON_LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button
GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (first), it could be a trailing button
GAMEPAD_BUTTON_RIGHT_TRIGGER_1, // Gamepad top/back trigger right (one), it could be a trailing button
GAMEPAD_BUTTON_RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button
GAMEPAD_BUTTON_MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select)
GAMEPAD_BUTTON_MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX)
@@ -856,10 +786,7 @@ typedef enum {
SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf
} ShaderLocationIndex;
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
@@ -941,7 +868,8 @@ typedef enum {
CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces
CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces
CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE // Layout is defined by a 4x3 cross with cubemap faces
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces
CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map)
} CubemapLayout;
// Font type, defines generation method
@@ -981,11 +909,11 @@ typedef enum {
// Camera system modes
typedef enum {
CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing)
CAMERA_FREE, // Camera free mode
CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
CAMERA_FIRST_PERSON, // Camera first person
CAMERA_THIRD_PERSON // Camera third person
CAMERA_CUSTOM = 0, // Custom camera
CAMERA_FREE, // Free camera
CAMERA_ORBITAL, // Orbital camera
CAMERA_FIRST_PERSON, // First person camera
CAMERA_THIRD_PERSON // Third person camera
} CameraMode;
// Camera projection
@@ -1002,7 +930,7 @@ typedef enum {
} NPatchLayout;
// Callbacks to hook some internal functions
// WARNING: These callbacks are intended for advanced users
// WARNING: These callbacks are intended for advance users
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
@@ -1028,36 +956,36 @@ RLAPI void CloseWindow(void); // Close windo
RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)
RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized
RLAPI bool IsWindowFocused(void); // Check if window is currently focused
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP)
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP)
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP)
RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP)
RLAPI bool IsWindowResized(void); // Check if window has been resized last frame
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit)
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit)
RLAPI void SetWindowTitle(const char *title); // Set title for window
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP)
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)
RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f]
RLAPI void SetWindowFocused(void); // Set window focused
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP)
RLAPI void *GetWindowHandle(void); // Get native window handle
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI)
RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI)
RLAPI int GetMonitorCount(void); // Get number of connected monitors
RLAPI int GetCurrentMonitor(void); // Get current monitor where window is placed
RLAPI int GetCurrentMonitor(void); // Get current connected monitor
RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position
RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor)
RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor)
@@ -1069,7 +997,6 @@ RLAPI Vector2 GetWindowScaleDPI(void); // Get window
RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
RLAPI const char *GetClipboardText(void); // Get clipboard text content
RLAPI Image GetClipboardImage(void); // Get clipboard image content
RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
@@ -1108,7 +1035,7 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
// NOTE: Shader functionality is not available on OpenGL 1.1
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
@@ -1118,15 +1045,13 @@ RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
// Screen-space-related functions
#define GetMouseRay GetScreenToWorldRay // Compatibility hack for previous raylib versions
RLAPI Ray GetScreenToWorldRay(Vector2 position, Camera camera); // Get a ray trace from screen position (i.e mouse)
RLAPI Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height); // Get a ray trace from screen position (i.e mouse) in a viewport
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position
RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position
RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix)
RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix
RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Get the screen space position for a 3d world space position
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position
RLAPI Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position
RLAPI Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Get camera transform matrix (view matrix)
RLAPI Matrix GetCameraMatrix2D(Camera2D camera); // Get camera 2d transform matrix
RLAPI Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position
// Timing-related functions
RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
@@ -1135,7 +1060,7 @@ RLAPI double GetTime(void); // Get elapsed
RLAPI int GetFPS(void); // Get current FPS
// Custom frame control functions
// NOTE: Those functions are intended for advanced users that want full control over the frame processing
// NOTE: Those functions are intended for advance users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing)
@@ -1162,7 +1087,7 @@ RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal me
RLAPI void MemFree(void *ptr); // Internal memory free
// Set custom callbacks
// WARNING: Callbacks setup is intended for advanced users
// WARNING: Callbacks setup is intended for advance users
RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log
RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader
RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver
@@ -1191,12 +1116,10 @@ RLAPI const char *GetDirectoryPath(const char *filePath); // Get full pa
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
@@ -1208,14 +1131,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
// Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
RLAPI void UnloadAutomationEventList(AutomationEventList *list); // Unload automation events list from file
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
@@ -1229,7 +1148,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
// Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
@@ -1238,17 +1157,16 @@ RLAPI int GetCharPressed(void); // Get char presse
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
// Input-related functions: mouse
RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once
@@ -1279,7 +1197,7 @@ RLAPI int GetTouchPointCount(void); // Get number of t
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
RLAPI int GetGestureDetected(void); // Get latest detected gesture
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
@@ -1298,21 +1216,19 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
// NOTE: It can be useful when using basic shapes and one single font,
// defining a font char white rectangle would allow drawing everything in a single draw call
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
// Basic shapes drawing functions
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel using geometry (Vector version) [Can be slow, use with care]
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color inner, Color outer); // Draw a gradient-filled circle
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
@@ -1324,28 +1240,27 @@ RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color)
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color topRight, Color bottomRight); // Draw a gradient-filled rectangle with custom vertex colors
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle lines with rounded edges
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
// Splines drawing functions
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
@@ -1363,13 +1278,12 @@ RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vect
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
//------------------------------------------------------------------------------------
@@ -1380,12 +1294,12 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
// NOTE: These functions do not require GPU access
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
RLAPI bool IsImageReady(Image image); // Check if an image is ready
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
@@ -1405,7 +1319,6 @@ RLAPI Image GenImageText(int width, int height, const char *text);
// Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
RLAPI Image ImageFromImage(Image image, Rectangle rec); // Create an image from another image piece
RLAPI Image ImageFromChannel(Image image, int selectedChannel); // Create an image from a selected channel of another image (GRAYSCALE)
RLAPI Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font)
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
@@ -1416,10 +1329,9 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold);
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel
RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation
RLAPI void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize); // Apply custom square convolution kernel to image
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
@@ -1447,7 +1359,6 @@ RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color);
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version)
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
@@ -1456,11 +1367,6 @@ RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int hei
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
RLAPI void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
RLAPI void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
@@ -1471,9 +1377,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data
@@ -1492,9 +1398,8 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, V
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
// Color/pixel related functions
RLAPI bool ColorIsEqual(Color col1, Color col2); // Check if two colors are equal
RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color (0xRRGGBBAA)
RLAPI int ColorToInt(Color color); // Get hexadecimal value for a Color
RLAPI Vector4 ColorNormalize(Color color); // Get Color normalized as float [0..1]
RLAPI Color ColorFromNormalized(Vector4 normalized); // Get Color from normalized values [0..1]
RLAPI Vector3 ColorToHSV(Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1]
@@ -1504,7 +1409,6 @@ RLAPI Color ColorBrightness(Color color, float factor); // G
RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f
RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f]
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
@@ -1517,10 +1421,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
// Font loading/unloading functions
RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
RLAPI bool IsFontReady(Font font); // Check if a font is ready
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
@@ -1561,7 +1465,7 @@ RLAPI bool TextIsEqual(const char *text1, const char *text2);
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style)
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
RLAPI char *TextReplace(const char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!)
RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!)
RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!)
RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter
RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
@@ -1570,11 +1474,7 @@ RLAPI int TextFindIndex(const char *text, const char *find);
RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string
RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported)
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
@@ -1585,7 +1485,7 @@ RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
@@ -1610,7 +1510,7 @@ RLAPI void DrawGrid(int slices, float spacing);
// Model management functions
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
RLAPI bool IsModelReady(Model model); // Check if a model is ready
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
@@ -1619,10 +1519,8 @@ RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
RLAPI void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
@@ -1632,10 +1530,9 @@ RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
RLAPI bool ExportMeshAsCode(Mesh mesh, const char *fileName); // Export mesh as code file (.h) defining multiple arrays of vertex attributes
// Mesh generation functions
RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
@@ -1653,15 +1550,14 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
// Material loading/unloading functions
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
RLAPI bool IsMaterialReady(Material material); // Check if a material is ready
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
// Model animations loading/unloading functions
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU)
RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning)
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
@@ -1691,11 +1587,11 @@ RLAPI float GetMasterVolume(void); // Get mas
// Wave/Sound loading/unloading functions
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound
@@ -1713,7 +1609,7 @@ RLAPI void SetSoundVolume(Sound sound, float volume); // Set vol
RLAPI void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
RLAPI void SetSoundPan(Sound sound, float pan); // Set pan for a sound (0.5 is center)
RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave
RLAPI void WaveCrop(Wave *wave, int initFrame, int finalFrame); // Crop a wave to defined frames range
RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format
RLAPI float *LoadWaveSamples(Wave wave); // Load samples data from wave as a 32bit float data array
RLAPI void UnloadWaveSamples(float *samples); // Unload samples data loaded with LoadWaveSamples()
@@ -1721,7 +1617,7 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
// Music management functions
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready
RLAPI void UnloadMusicStream(Music music); // Unload music stream
RLAPI void PlayMusicStream(Music music); // Start music playing
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
@@ -1738,7 +1634,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur
// AudioStream management functions
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
@@ -1753,10 +1649,10 @@ RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as 'float'
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as <float>s
RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as 'float'
RLAPI void AttachAudioMixedProcessor(AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as <float>s
RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio stream processor from the entire audio pipeline
#if defined(__cplusplus)
+33 -792
View File
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
*
* CONVENTIONS:
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
@@ -12,7 +12,7 @@
* - Functions are always self-contained, no function use another raymath function inside,
* required code is directly re-implemented inside
* - Functions input parameters are always received by value (2 unavoidable exceptions)
* - Functions use always a "result" variable for return (except C++ operators)
* - Functions use always a "result" variable for return
* - Functions are always defined inline
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
* - No compound literals used to make sure libray is compatible with C++
@@ -27,12 +27,10 @@
* Define static inline functions code, so #include header suffices for use.
* This may use up lots of memory.
*
* #define RAYMATH_DISABLE_CPP_OPERATORS
* Disables C++ operator overloads for raymath types.
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -61,9 +59,7 @@
// Function specifiers definition
#if defined(RAYMATH_IMPLEMENTATION)
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
#define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll)
#elif defined(BUILD_LIBTYPE_SHARED)
#define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib)
#define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll).
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
#define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
#else
@@ -79,7 +75,6 @@
#endif
#endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -168,7 +163,7 @@ typedef struct float16 {
float v[16];
} float16;
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabsf()
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs()
//----------------------------------------------------------------------------------
// Module Functions Definition - Utils math
@@ -304,14 +299,6 @@ RMAPI float Vector2DotProduct(Vector2 v1, Vector2 v2)
return result;
}
// Calculate two vectors cross product
RMAPI float Vector2CrossProduct(Vector2 v1, Vector2 v2)
{
float result = (v1.x*v2.y - v1.y*v2.x);
return result;
}
// Calculate distance between two vectors
RMAPI float Vector2Distance(Vector2 v1, Vector2 v2)
{
@@ -442,28 +429,6 @@ RMAPI Vector2 Vector2Reflect(Vector2 v, Vector2 normal)
return result;
}
// Get min value for each pair of components
RMAPI Vector2 Vector2Min(Vector2 v1, Vector2 v2)
{
Vector2 result = { 0 };
result.x = fminf(v1.x, v2.x);
result.y = fminf(v1.y, v2.y);
return result;
}
// Get max value for each pair of components
RMAPI Vector2 Vector2Max(Vector2 v1, Vector2 v2)
{
Vector2 result = { 0 };
result.x = fmaxf(v1.x, v2.x);
result.y = fmaxf(v1.y, v2.y);
return result;
}
// Rotate vector by angle
RMAPI Vector2 Vector2Rotate(Vector2 v, float angle)
{
@@ -527,18 +492,18 @@ RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max)
{
length = sqrtf(length);
float scale = 1; // By default, 1 as the neutral element.
if (length < min)
{
scale = min/length;
float scale = min/length;
result.x = v.x*scale;
result.y = v.y*scale;
}
else if (length > max)
{
scale = max/length;
float scale = max/length;
result.x = v.x*scale;
result.y = v.y*scale;
}
result.x = v.x*scale;
result.y = v.y*scale;
}
return result;
@@ -557,31 +522,6 @@ RMAPI int Vector2Equals(Vector2 p, Vector2 q)
return result;
}
// Compute the direction of a refracted ray
// v: normalized direction of the incoming ray
// n: normalized normal vector of the interface of two optical media
// r: ratio of the refractive index of the medium from where the ray comes
// to the refractive index of the medium on the other side of the surface
RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r)
{
Vector2 result = { 0 };
float dot = v.x*n.x + v.y*n.y;
float d = 1.0f - r*r*(1.0f - dot*dot);
if (d >= 0.0f)
{
d = sqrtf(d);
v.x = r*v.x - (r*dot + d)*n.x;
v.y = r*v.y - (r*dot + d)*n.y;
result = v;
}
return result;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Vector3 math
//----------------------------------------------------------------------------------
@@ -663,12 +603,12 @@ RMAPI Vector3 Vector3Perpendicular(Vector3 v)
{
Vector3 result = { 0 };
float min = fabsf(v.x);
float min = (float) fabs(v.x);
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
if (fabsf(v.y) < min)
{
min = fabsf(v.y);
min = (float) fabs(v.y);
Vector3 tmp = {0.0f, 1.0f, 0.0f};
cardinalAxis = tmp;
}
@@ -788,7 +728,7 @@ RMAPI Vector3 Vector3Normalize(Vector3 v)
RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2)
{
Vector3 result = { 0 };
float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
@@ -805,7 +745,7 @@ RMAPI Vector3 Vector3Project(Vector3 v1, Vector3 v2)
RMAPI Vector3 Vector3Reject(Vector3 v1, Vector3 v2)
{
Vector3 result = { 0 };
float v1dv2 = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
float v2dv2 = (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z);
@@ -892,7 +832,7 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle)
// Vector3Normalize(axis);
float length = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z);
if (length == 0.0f) length = 1.0f;
float ilength = 1.0f/length;
float ilength = 1.0f / length;
axis.x *= ilength;
axis.y *= ilength;
axis.z *= ilength;
@@ -933,27 +873,6 @@ RMAPI Vector3 Vector3RotateByAxisAngle(Vector3 v, Vector3 axis, float angle)
return result;
}
// Move Vector towards target
RMAPI Vector3 Vector3MoveTowards(Vector3 v, Vector3 target, float maxDistance)
{
Vector3 result = { 0 };
float dx = target.x - v.x;
float dy = target.y - v.y;
float dz = target.z - v.z;
float value = (dx*dx) + (dy*dy) + (dz*dz);
if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;
float dist = sqrtf(value);
result.x = v.x + dx/dist*maxDistance;
result.y = v.y + dy/dist*maxDistance;
result.z = v.z + dz/dist*maxDistance;
return result;
}
// Calculate linear interpolation between two vectors
RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
{
@@ -966,22 +885,6 @@ RMAPI Vector3 Vector3Lerp(Vector3 v1, Vector3 v2, float amount)
return result;
}
// Calculate cubic hermite interpolation between two vectors and their tangents
// as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic
RMAPI Vector3 Vector3CubicHermite(Vector3 v1, Vector3 tangent1, Vector3 v2, Vector3 tangent2, float amount)
{
Vector3 result = { 0 };
float amountPow2 = amount*amount;
float amountPow3 = amount*amount*amount;
result.x = (2*amountPow3 - 3*amountPow2 + 1)*v1.x + (amountPow3 - 2*amountPow2 + amount)*tangent1.x + (-2*amountPow3 + 3*amountPow2)*v2.x + (amountPow3 - amountPow2)*tangent2.x;
result.y = (2*amountPow3 - 3*amountPow2 + 1)*v1.y + (amountPow3 - 2*amountPow2 + amount)*tangent1.y + (-2*amountPow3 + 3*amountPow2)*v2.y + (amountPow3 - amountPow2)*tangent2.y;
result.z = (2*amountPow3 - 3*amountPow2 + 1)*v1.z + (amountPow3 - 2*amountPow2 + amount)*tangent1.z + (-2*amountPow3 + 3*amountPow2)*v2.z + (amountPow3 - amountPow2)*tangent2.z;
return result;
}
// Calculate reflected vector to normal
RMAPI Vector3 Vector3Reflect(Vector3 v, Vector3 normal)
{
@@ -1175,19 +1078,20 @@ RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max)
{
length = sqrtf(length);
float scale = 1; // By default, 1 as the neutral element.
if (length < min)
{
scale = min/length;
float scale = min/length;
result.x = v.x*scale;
result.y = v.y*scale;
result.z = v.z*scale;
}
else if (length > max)
{
scale = max/length;
float scale = max/length;
result.x = v.x*scale;
result.y = v.y*scale;
result.z = v.z*scale;
}
result.x = v.x*scale;
result.y = v.y*scale;
result.z = v.z*scale;
}
return result;
@@ -1232,233 +1136,6 @@ RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r)
return result;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Vector4 math
//----------------------------------------------------------------------------------
RMAPI Vector4 Vector4Zero(void)
{
Vector4 result = { 0.0f, 0.0f, 0.0f, 0.0f };
return result;
}
RMAPI Vector4 Vector4One(void)
{
Vector4 result = { 1.0f, 1.0f, 1.0f, 1.0f };
return result;
}
RMAPI Vector4 Vector4Add(Vector4 v1, Vector4 v2)
{
Vector4 result = {
v1.x + v2.x,
v1.y + v2.y,
v1.z + v2.z,
v1.w + v2.w
};
return result;
}
RMAPI Vector4 Vector4AddValue(Vector4 v, float add)
{
Vector4 result = {
v.x + add,
v.y + add,
v.z + add,
v.w + add
};
return result;
}
RMAPI Vector4 Vector4Subtract(Vector4 v1, Vector4 v2)
{
Vector4 result = {
v1.x - v2.x,
v1.y - v2.y,
v1.z - v2.z,
v1.w - v2.w
};
return result;
}
RMAPI Vector4 Vector4SubtractValue(Vector4 v, float add)
{
Vector4 result = {
v.x - add,
v.y - add,
v.z - add,
v.w - add
};
return result;
}
RMAPI float Vector4Length(Vector4 v)
{
float result = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));
return result;
}
RMAPI float Vector4LengthSqr(Vector4 v)
{
float result = (v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w);
return result;
}
RMAPI float Vector4DotProduct(Vector4 v1, Vector4 v2)
{
float result = (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w);
return result;
}
// Calculate distance between two vectors
RMAPI float Vector4Distance(Vector4 v1, Vector4 v2)
{
float result = sqrtf(
(v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) +
(v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w));
return result;
}
// Calculate square distance between two vectors
RMAPI float Vector4DistanceSqr(Vector4 v1, Vector4 v2)
{
float result =
(v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) +
(v1.z - v2.z)*(v1.z - v2.z) + (v1.w - v2.w)*(v1.w - v2.w);
return result;
}
RMAPI Vector4 Vector4Scale(Vector4 v, float scale)
{
Vector4 result = { v.x*scale, v.y*scale, v.z*scale, v.w*scale };
return result;
}
// Multiply vector by vector
RMAPI Vector4 Vector4Multiply(Vector4 v1, Vector4 v2)
{
Vector4 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z, v1.w*v2.w };
return result;
}
// Negate vector
RMAPI Vector4 Vector4Negate(Vector4 v)
{
Vector4 result = { -v.x, -v.y, -v.z, -v.w };
return result;
}
// Divide vector by vector
RMAPI Vector4 Vector4Divide(Vector4 v1, Vector4 v2)
{
Vector4 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z, v1.w/v2.w };
return result;
}
// Normalize provided vector
RMAPI Vector4 Vector4Normalize(Vector4 v)
{
Vector4 result = { 0 };
float length = sqrtf((v.x*v.x) + (v.y*v.y) + (v.z*v.z) + (v.w*v.w));
if (length > 0)
{
float ilength = 1.0f/length;
result.x = v.x*ilength;
result.y = v.y*ilength;
result.z = v.z*ilength;
result.w = v.w*ilength;
}
return result;
}
// Get min value for each pair of components
RMAPI Vector4 Vector4Min(Vector4 v1, Vector4 v2)
{
Vector4 result = { 0 };
result.x = fminf(v1.x, v2.x);
result.y = fminf(v1.y, v2.y);
result.z = fminf(v1.z, v2.z);
result.w = fminf(v1.w, v2.w);
return result;
}
// Get max value for each pair of components
RMAPI Vector4 Vector4Max(Vector4 v1, Vector4 v2)
{
Vector4 result = { 0 };
result.x = fmaxf(v1.x, v2.x);
result.y = fmaxf(v1.y, v2.y);
result.z = fmaxf(v1.z, v2.z);
result.w = fmaxf(v1.w, v2.w);
return result;
}
// Calculate linear interpolation between two vectors
RMAPI Vector4 Vector4Lerp(Vector4 v1, Vector4 v2, float amount)
{
Vector4 result = { 0 };
result.x = v1.x + amount*(v2.x - v1.x);
result.y = v1.y + amount*(v2.y - v1.y);
result.z = v1.z + amount*(v2.z - v1.z);
result.w = v1.w + amount*(v2.w - v1.w);
return result;
}
// Move Vector towards target
RMAPI Vector4 Vector4MoveTowards(Vector4 v, Vector4 target, float maxDistance)
{
Vector4 result = { 0 };
float dx = target.x - v.x;
float dy = target.y - v.y;
float dz = target.z - v.z;
float dw = target.w - v.w;
float value = (dx*dx) + (dy*dy) + (dz*dz) + (dw*dw);
if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) return target;
float dist = sqrtf(value);
result.x = v.x + dx/dist*maxDistance;
result.y = v.y + dy/dist*maxDistance;
result.z = v.z + dz/dist*maxDistance;
result.w = v.w + dw/dist*maxDistance;
return result;
}
// Invert the given vector
RMAPI Vector4 Vector4Invert(Vector4 v)
{
Vector4 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z, 1.0f/v.w };
return result;
}
// Check whether two given vectors are almost equal
RMAPI int Vector4Equals(Vector4 p, Vector4 q)
{
#if !defined(EPSILON)
#define EPSILON 0.000001f
#endif
int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&
((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))));
return result;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Matrix math
//----------------------------------------------------------------------------------
@@ -1847,32 +1524,32 @@ RMAPI Matrix MatrixScale(float x, float y, float z)
}
// Get perspective projection matrix
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double nearPlane, double farPlane)
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far)
{
Matrix result = { 0 };
float rl = (float)(right - left);
float tb = (float)(top - bottom);
float fn = (float)(farPlane - nearPlane);
float fn = (float)(far - near);
result.m0 = ((float)nearPlane*2.0f)/rl;
result.m0 = ((float)near*2.0f)/rl;
result.m1 = 0.0f;
result.m2 = 0.0f;
result.m3 = 0.0f;
result.m4 = 0.0f;
result.m5 = ((float)nearPlane*2.0f)/tb;
result.m5 = ((float)near*2.0f)/tb;
result.m6 = 0.0f;
result.m7 = 0.0f;
result.m8 = ((float)right + (float)left)/rl;
result.m9 = ((float)top + (float)bottom)/tb;
result.m10 = -((float)farPlane + (float)nearPlane)/fn;
result.m10 = -((float)far + (float)near)/fn;
result.m11 = -1.0f;
result.m12 = 0.0f;
result.m13 = 0.0f;
result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
result.m14 = -((float)far*(float)near*2.0f)/fn;
result.m15 = 0.0f;
return result;
@@ -2224,32 +1901,6 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
return result;
}
// Calculate quaternion cubic spline interpolation using Cubic Hermite Spline algorithm
// as described in the GLTF 2.0 specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#interpolation-cubic
RMAPI Quaternion QuaternionCubicHermiteSpline(Quaternion q1, Quaternion outTangent1, Quaternion q2, Quaternion inTangent2, float t)
{
float t2 = t*t;
float t3 = t2*t;
float h00 = 2*t3 - 3*t2 + 1;
float h10 = t3 - 2*t2 + t;
float h01 = -2*t3 + 3*t2;
float h11 = t3 - t2;
Quaternion p0 = QuaternionScale(q1, h00);
Quaternion m0 = QuaternionScale(outTangent1, h10);
Quaternion p1 = QuaternionScale(q2, h01);
Quaternion m1 = QuaternionScale(inTangent2, h11);
Quaternion result = { 0 };
result = QuaternionAdd(p0, m0);
result = QuaternionAdd(result, p1);
result = QuaternionAdd(result, m1);
result = QuaternionNormalize(result);
return result;
}
// Calculate quaternion based on the rotation from one vector to another
RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
{
@@ -2309,7 +1960,7 @@ RMAPI Quaternion QuaternionFromMatrix(Matrix mat)
}
float biggestVal = sqrtf(fourBiggestSquaredMinus1 + 1.0f)*0.5f;
float mult = 0.25f/biggestVal;
float mult = 0.25f / biggestVal;
switch (biggestIndex)
{
@@ -2391,7 +2042,8 @@ RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
float ilength = 0.0f;
// Vector3Normalize(axis)
length = axisLength;
Vector3 v = axis;
length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
if (length == 0.0f) length = 1.0f;
ilength = 1.0f/length;
axis.x *= ilength;
@@ -2535,415 +2187,4 @@ RMAPI int QuaternionEquals(Quaternion p, Quaternion q)
return result;
}
// Decompose a transformation matrix into its rotational, translational and scaling components
RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotation, Vector3 *scale)
{
// Extract translation.
translation->x = mat.m12;
translation->y = mat.m13;
translation->z = mat.m14;
// Extract upper-left for determinant computation
const float a = mat.m0;
const float b = mat.m4;
const float c = mat.m8;
const float d = mat.m1;
const float e = mat.m5;
const float f = mat.m9;
const float g = mat.m2;
const float h = mat.m6;
const float i = mat.m10;
const float A = e*i - f*h;
const float B = f*g - d*i;
const float C = d*h - e*g;
// Extract scale
const float det = a*A + b*B + c*C;
Vector3 abc = { a, b, c };
Vector3 def = { d, e, f };
Vector3 ghi = { g, h, i };
float scalex = Vector3Length(abc);
float scaley = Vector3Length(def);
float scalez = Vector3Length(ghi);
Vector3 s = { scalex, scaley, scalez };
if (det < 0) s = Vector3Negate(s);
*scale = s;
// Remove scale from the matrix if it is not close to zero
Matrix clone = mat;
if (!FloatEquals(det, 0))
{
clone.m0 /= s.x;
clone.m4 /= s.x;
clone.m8 /= s.x;
clone.m1 /= s.y;
clone.m5 /= s.y;
clone.m9 /= s.y;
clone.m2 /= s.z;
clone.m6 /= s.z;
clone.m10 /= s.z;
// Extract rotation
*rotation = QuaternionFromMatrix(clone);
}
else
{
// Set to identity if close to zero
*rotation = QuaternionIdentity();
}
}
#if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)
// Optional C++ math operators
//-------------------------------------------------------------------------------
// Vector2 operators
static constexpr Vector2 Vector2Zeros = { 0, 0 };
static constexpr Vector2 Vector2Ones = { 1, 1 };
static constexpr Vector2 Vector2UnitX = { 1, 0 };
static constexpr Vector2 Vector2UnitY = { 0, 1 };
inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
{
return Vector2Add(lhs, rhs);
}
inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)
{
lhs = Vector2Add(lhs, rhs);
return lhs;
}
inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
{
return Vector2Subtract(lhs, rhs);
}
inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
{
lhs = Vector2Subtract(lhs, rhs);
return lhs;
}
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
{
return Vector2Scale(lhs, rhs);
}
inline const Vector2& operator *= (Vector2& lhs, const float& rhs)
{
lhs = Vector2Scale(lhs, rhs);
return lhs;
}
inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
{
return Vector2Multiply(lhs, rhs);
}
inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)
{
lhs = Vector2Multiply(lhs, rhs);
return lhs;
}
inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
{
return Vector2Transform(lhs, rhs);
}
inline const Vector2& operator *= (Vector2& lhs, const Matrix& rhs)
{
lhs = Vector2Transform(lhs, rhs);
return lhs;
}
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
{
return Vector2Scale(lhs, 1.0f / rhs);
}
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
{
lhs = Vector2Scale(lhs, 1.0f / rhs);
return lhs;
}
inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
{
return Vector2Divide(lhs, rhs);
}
inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)
{
lhs = Vector2Divide(lhs, rhs);
return lhs;
}
inline bool operator == (const Vector2& lhs, const Vector2& rhs)
{
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);
}
inline bool operator != (const Vector2& lhs, const Vector2& rhs)
{
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);
}
// Vector3 operators
static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };
static constexpr Vector3 Vector3Ones = { 1, 1, 1 };
static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };
static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };
static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };
inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
{
return Vector3Add(lhs, rhs);
}
inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)
{
lhs = Vector3Add(lhs, rhs);
return lhs;
}
inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
{
return Vector3Subtract(lhs, rhs);
}
inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
{
lhs = Vector3Subtract(lhs, rhs);
return lhs;
}
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
{
return Vector3Scale(lhs, rhs);
}
inline const Vector3& operator *= (Vector3& lhs, const float& rhs)
{
lhs = Vector3Scale(lhs, rhs);
return lhs;
}
inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
{
return Vector3Multiply(lhs, rhs);
}
inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)
{
lhs = Vector3Multiply(lhs, rhs);
return lhs;
}
inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
{
return Vector3Transform(lhs, rhs);
}
inline const Vector3& operator *= (Vector3& lhs, const Matrix& rhs)
{
lhs = Vector3Transform(lhs, rhs);
return lhs;
}
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
{
return Vector3Scale(lhs, 1.0f / rhs);
}
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
{
lhs = Vector3Scale(lhs, 1.0f / rhs);
return lhs;
}
inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
{
return Vector3Divide(lhs, rhs);
}
inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)
{
lhs = Vector3Divide(lhs, rhs);
return lhs;
}
inline bool operator == (const Vector3& lhs, const Vector3& rhs)
{
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);
}
inline bool operator != (const Vector3& lhs, const Vector3& rhs)
{
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);
}
// Vector4 operators
static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };
static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };
static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };
static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };
static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };
static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };
inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
{
return Vector4Add(lhs, rhs);
}
inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)
{
lhs = Vector4Add(lhs, rhs);
return lhs;
}
inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
{
return Vector4Subtract(lhs, rhs);
}
inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
{
lhs = Vector4Subtract(lhs, rhs);
return lhs;
}
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
{
return Vector4Scale(lhs, rhs);
}
inline const Vector4& operator *= (Vector4& lhs, const float& rhs)
{
lhs = Vector4Scale(lhs, rhs);
return lhs;
}
inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
{
return Vector4Multiply(lhs, rhs);
}
inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
{
lhs = Vector4Multiply(lhs, rhs);
return lhs;
}
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
{
return Vector4Scale(lhs, 1.0f / rhs);
}
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
{
lhs = Vector4Scale(lhs, 1.0f / rhs);
return lhs;
}
inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
{
return Vector4Divide(lhs, rhs);
}
inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)
{
lhs = Vector4Divide(lhs, rhs);
return lhs;
}
inline bool operator == (const Vector4& lhs, const Vector4& rhs)
{
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);
}
inline bool operator != (const Vector4& lhs, const Vector4& rhs)
{
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);
}
// Quaternion operators
static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };
static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };
static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };
inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
{
return QuaternionAddValue(lhs, rhs);
}
inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)
{
lhs = QuaternionAddValue(lhs, rhs);
return lhs;
}
inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
{
return QuaternionSubtractValue(lhs, rhs);
}
inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)
{
lhs = QuaternionSubtractValue(lhs, rhs);
return lhs;
}
inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
{
return QuaternionTransform(lhs, rhs);
}
inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)
{
lhs = QuaternionTransform(lhs, rhs);
return lhs;
}
// Matrix operators
inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
{
return MatrixAdd(lhs, rhs);
}
inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)
{
lhs = MatrixAdd(lhs, rhs);
return lhs;
}
inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
{
return MatrixSubtract(lhs, rhs);
}
inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)
{
lhs = MatrixSubtract(lhs, rhs);
return lhs;
}
inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)
{
return MatrixMultiply(lhs, rhs);
}
inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)
{
lhs = MatrixMultiply(lhs, rhs);
return lhs;
}
//-------------------------------------------------------------------------------
#endif // C++ operators
#endif // RAYMATH_H
+192 -595
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2682a70d41ec1894e060fb1bc6795dd93bf51aeee1ad779b4b0f6e82f1ff6efc
size 3140268
oid sha256:fac99ffbab698b99a47019ff02ff839f7536c32996b5e7aa827ef4820b288212
size 10630538
+17 -22
View File
@@ -4,38 +4,33 @@ set -e
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR
RAYLIB_PLATFORM="PLATFORM_DESKTOP"
ARCHNAME=$(uname -m)
if [ -f /TICI ]; then
ARCHNAME="larch64"
RAYLIB_PLATFORM="PLATFORM_COMMA"
fi
if [[ "$OSTYPE" == "darwin"* ]]; then
ARCHNAME="Darwin"
fi
if [ ! -d raylib_repo ]; then
git clone https://github.com/raysan5/raylib.git raylib_repo
fi
cd raylib_repo
git fetch --tags origin 5.0
git checkout 5.0
git clean -xdff .
mkdir build
cd build
cmake ..
make -j$(nproc)
INSTALL_DIR="$DIR/$ARCHNAME"
rm -rf $INSTALL_DIR
mkdir -p $INSTALL_DIR
INSTALL_H_DIR="$DIR/include"
rm -rf $INSTALL_H_DIR
mkdir -p $INSTALL_H_DIR
if [ ! -d raylib_repo ]; then
git clone -b master --no-tags https://github.com/commaai/raylib.git raylib_repo
fi
cd raylib_repo
COMMIT="f5b0a7237c6e45f0e8a6ff68322d19b49298d798"
git fetch origin $COMMIT
git reset --hard $COMMIT
git clean -xdff .
cd src
make -j$(nproc) PLATFORM=$RAYLIB_PLATFORM
sudo make install RAYLIB_INSTALL_PATH=$INSTALL_DIR RAYLIB_H_INSTALL_PATH=$INSTALL_H_DIR
rm -rf $DIR/include
cp $DIR/raylib_repo/build/raylib/libraylib.a $INSTALL_DIR/
cp -r $DIR/raylib_repo/build/raylib/include $DIR
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:76697e9a248b8af45e798137038fa5ec5d9e36c9b4565fa448aefbcd0d2ab113
size 2769636
oid sha256:0c07c718e411baefd74fd761d18f18fcc681ccd606d477118acff96732d21791
size 10233524
+12 -9
View File
@@ -4,9 +4,9 @@
openpilot is developed and tested on **Ubuntu 24.04**, which is the primary development target aside from the [supported embedded hardware](https://github.com/commaai/openpilot#running-on-a-dedicated-device-in-a-car).
Most of openpilot should work natively on macOS. On Windows you can use WSL for a nearly native Ubuntu experience. Running natively on any other system is not currently recommended and will likely require modifications.
Running natively on any other system is not recommended and will require modifications. On Windows you can use WSL, and on macOS or incompatible Linux systems, it is recommended to use the dev containers.
## Native setup on Ubuntu 24.04 and macOS
## Native setup on Ubuntu 24.04
**1. Clone openpilot**
@@ -24,18 +24,11 @@ git clone --recurse-submodules https://github.com/commaai/openpilot.git
**2. Run the setup script**
Ubuntu 24.04:
``` bash
cd openpilot
tools/ubuntu_setup.sh
```
macOS:
``` bash
cd openpilot
tools/mac_setup.sh
```
**3. Git LFS**
``` bash
@@ -55,6 +48,16 @@ source .venv/bin/activate
scons -u -j$(nproc)
```
## Dev Container on any Linux or macOS
openpilot supports [Dev Containers](https://containers.dev/). Dev containers provide customizable and consistent development environment wrapped inside a container. This means you can develop in a designated environment matching our primary development target, regardless of your local setup.
Dev containers are supported in [multiple editors and IDEs](https://containers.dev/supporting), including Visual Studio Code. Use the following [guide](https://code.visualstudio.com/docs/devcontainers/containers) to start using them with VSCode.
#### X11 forwarding on macOS
GUI apps like `ui` or `cabana` can also run inside the container by leveraging X11 forwarding. To make use of it on macOS, additional configuration steps must be taken. Follow [these](https://gist.github.com/sorny/969fe55d85c9b0035b0109a31cbcb088) steps to setup X11 forwarding on macOS.
## WSL on Windows
[Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about) should provide a similar experience to native Ubuntu. [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/compare-versions) specifically has been reported by several users to be a seamless experience.
+1 -3
View File
@@ -558,9 +558,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
if (can && !can->liveStreaming()) {
settings.video_splitter_state = video_splitter->saveState();
}
if (messages_widget) {
settings.message_header_state = messages_widget->saveHeaderState();
}
settings.message_header_state = messages_widget->saveHeaderState();
QWidget::closeEvent(event);
}

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