mirror of
https://github.com/PhotonVision/photonvision
synced 2026-07-05 03:21:40 +00:00
Compare commits
11 Commits
v2024.2.10
...
v2024.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7271c950e1 | ||
|
|
2f2b6e9693 | ||
|
|
60c9ea8892 | ||
|
|
c89acea5a6 | ||
|
|
fa5d58147a | ||
|
|
e74afb9688 | ||
|
|
5dc70e4d3f | ||
|
|
5597f5acd9 | ||
|
|
fae3116951 | ||
|
|
def37b92ba | ||
|
|
5b878fe3a3 |
366
.github/workflows/build.yml
vendored
366
.github/workflows/build.yml
vendored
@@ -2,123 +2,14 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches:
|
||||||
|
- master
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- 'v*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-client:
|
|
||||||
name: "PhotonClient Build"
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: photon-client
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: Build Production Client
|
|
||||||
run: npm run build
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: built-client
|
|
||||||
path: photon-client/dist/
|
|
||||||
build-examples:
|
|
||||||
name: "Build Examples"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Fetch tags
|
|
||||||
run: git fetch --tags --force
|
|
||||||
- name: Install Java 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
# Need to publish to maven local first, so that C++ sim can pick it up
|
|
||||||
# Still haven't figured out how to make the vendordep file be copied before trying to build examples
|
|
||||||
- name: Publish photonlib to maven local
|
|
||||||
run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew publishtomavenlocal -x check
|
|
||||||
- name: Build Java examples
|
|
||||||
working-directory: photonlib-java-examples
|
|
||||||
run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew copyPhotonlib -x check
|
|
||||||
./gradlew build -x check --max-workers 2
|
|
||||||
- name: Build C++ examples
|
|
||||||
working-directory: photonlib-cpp-examples
|
|
||||||
run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew copyPhotonlib -x check
|
|
||||||
./gradlew build -x check --max-workers 2
|
|
||||||
build-gradle:
|
|
||||||
name: "Gradle Build"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
# Checkout code.
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Fetch tags
|
|
||||||
run: git fetch --tags --force
|
|
||||||
- name: Install Java 17
|
|
||||||
uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
- name: Install mrcal deps
|
|
||||||
run: sudo apt-get update && sudo apt-get install -y libcholmod3 liblapack3 libsuitesparseconfig5
|
|
||||||
- name: Gradle Build
|
|
||||||
run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew build -x check --max-workers 2
|
|
||||||
- name: Gradle Tests
|
|
||||||
run: ./gradlew testHeadless -i --max-workers 1 --stacktrace
|
|
||||||
- name: Gradle Coverage
|
|
||||||
run: ./gradlew jacocoTestReport --max-workers 1
|
|
||||||
- name: Publish Coverage Report
|
|
||||||
uses: codecov/codecov-action@v3
|
|
||||||
with:
|
|
||||||
file: ./photon-server/build/reports/jacoco/test/jacocoTestReport.xml
|
|
||||||
- name: Publish Core Coverage Report
|
|
||||||
uses: codecov/codecov-action@v3
|
|
||||||
with:
|
|
||||||
file: ./photon-core/build/reports/jacoco/test/jacocoTestReport.xml
|
|
||||||
build-offline-docs:
|
|
||||||
name: "Build Offline Docs"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: 'PhotonVision/photonvision-docs.git'
|
|
||||||
ref: master
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.9'
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install sphinx sphinx_rtd_theme sphinx-tabs sphinxext-opengraph doc8
|
|
||||||
pip install -r requirements.txt
|
|
||||||
- name: Build the docs
|
|
||||||
run: |
|
|
||||||
make html
|
|
||||||
- uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: built-docs
|
|
||||||
path: build/html
|
|
||||||
build-photonlib-host:
|
build-photonlib-host:
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: 12
|
MACOSX_DEPLOYMENT_TARGET: 12
|
||||||
@@ -188,256 +79,3 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }}
|
ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }}
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
build-package:
|
|
||||||
needs: [build-client, build-gradle, build-offline-docs]
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: windows-latest
|
|
||||||
artifact-name: Win64
|
|
||||||
architecture: x64
|
|
||||||
arch-override: none
|
|
||||||
- os: macos-latest
|
|
||||||
artifact-name: macOS
|
|
||||||
architecture: x64
|
|
||||||
arch-override: none
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: Linux
|
|
||||||
architecture: x64
|
|
||||||
arch-override: none
|
|
||||||
- os: macos-latest
|
|
||||||
artifact-name: macOSArm
|
|
||||||
architecture: x64
|
|
||||||
arch-override: macarm64
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm32
|
|
||||||
architecture: x64
|
|
||||||
arch-override: linuxarm32
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
architecture: x64
|
|
||||||
arch-override: linuxarm64
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
name: "Build fat JAR - ${{ matrix.artifact-name }}"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Install Java 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
- run: |
|
|
||||||
rm -rf photon-server/src/main/resources/web/*
|
|
||||||
mkdir -p photon-server/src/main/resources/web/docs
|
|
||||||
if: ${{ (matrix.os) != 'windows-latest' }}
|
|
||||||
- run: |
|
|
||||||
del photon-server\src\main\resources\web\*.*
|
|
||||||
mkdir photon-server\src\main\resources\web\docs
|
|
||||||
if: ${{ (matrix.os) == 'windows-latest' }}
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: built-client
|
|
||||||
path: photon-server/src/main/resources/web/
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: built-docs
|
|
||||||
path: photon-server/src/main/resources/web/docs
|
|
||||||
- run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew photon-server:shadowJar --max-workers 2 -PArchOverride=${{ matrix.arch-override }}
|
|
||||||
if: ${{ (matrix.arch-override != 'none') }}
|
|
||||||
- run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew photon-server:shadowJar --max-workers 2
|
|
||||||
if: ${{ (matrix.arch-override == 'none') }}
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: jar-${{ matrix.artifact-name }}
|
|
||||||
path: photon-server/build/libs
|
|
||||||
|
|
||||||
run-smoketest-native:
|
|
||||||
needs: [build-package]
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: jar-Linux
|
|
||||||
extraOpts: -Djdk.lang.Process.launchMechanism=vfork
|
|
||||||
- os: windows-latest
|
|
||||||
artifact-name: jar-Win64
|
|
||||||
extraOpts: ""
|
|
||||||
- os: macos-latest
|
|
||||||
artifact-name: jar-macOS
|
|
||||||
architecture: x64
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Install Java 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.artifact-name }}
|
|
||||||
# On linux, install mrcal packages
|
|
||||||
- run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install --yes libcholmod3 liblapack3 libsuitesparseconfig5
|
|
||||||
if: ${{ (matrix.os) == 'ubuntu-latest' }}
|
|
||||||
# and actually run the jar
|
|
||||||
- run: java -jar ${{ matrix.extraOpts }} *.jar --smoketest
|
|
||||||
if: ${{ (matrix.os) != 'windows-latest' }}
|
|
||||||
- run: ls *.jar | %{ Write-Host "Running $($_.Name)"; Start-Process "java" -ArgumentList "-jar `"$($_.FullName)`" --smoketest" -NoNewWindow -Wait; break }
|
|
||||||
if: ${{ (matrix.os) == 'windows-latest' }}
|
|
||||||
|
|
||||||
run-smoketest-chroot:
|
|
||||||
needs: [build-package]
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: RaspberryPi
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.4/photonvision_raspi.img.xz
|
|
||||||
cpu: cortex-a7
|
|
||||||
image_additional_mb: 0
|
|
||||||
extraOpts: -Djdk.lang.Process.launchMechanism=vfork
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
name: smoketest-${{ matrix.image_suffix }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: jar-${{ matrix.artifact-name }}
|
|
||||||
|
|
||||||
- uses: pguyot/arm-runner-action@v2
|
|
||||||
name: Run photon smoketest
|
|
||||||
id: generate_image
|
|
||||||
with:
|
|
||||||
base_image: ${{ matrix.image_url }}
|
|
||||||
image_additional_mb: ${{ matrix.image_additional_mb }}
|
|
||||||
optimize_image: yes
|
|
||||||
cpu: ${{ matrix.cpu }}
|
|
||||||
# We do _not_ wanna copy photon into the image. Bind mount instead
|
|
||||||
bind_mount_repository: true
|
|
||||||
# our image better have java installed already
|
|
||||||
commands: |
|
|
||||||
java -jar ${{ matrix.extraOpts }} *.jar --smoketest
|
|
||||||
|
|
||||||
build-image:
|
|
||||||
needs: [build-package]
|
|
||||||
|
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: RaspberryPi
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.4/photonvision_raspi.img.xz
|
|
||||||
cpu: cortex-a7
|
|
||||||
image_additional_mb: 0
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: limelight2
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.4/photonvision_limelight.img.xz
|
|
||||||
cpu: cortex-a7
|
|
||||||
image_additional_mb: 0
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: limelight3
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.5/photonvision_limelight3.img.xz
|
|
||||||
cpu: cortex-a7
|
|
||||||
image_additional_mb: 0
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: orangepi5
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.10/photonvision_opi5.img.xz
|
|
||||||
cpu: cortex-a8
|
|
||||||
image_additional_mb: 4096
|
|
||||||
- os: ubuntu-latest
|
|
||||||
artifact-name: LinuxArm64
|
|
||||||
image_suffix: orangepi5plus
|
|
||||||
image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2024.0.10/photonvision_opi5plus.img.xz
|
|
||||||
cpu: cortex-a8
|
|
||||||
image_additional_mb: 4096
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
name: "Build image - ${{ matrix.image_url }}"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: jar-${{ matrix.artifact-name }}
|
|
||||||
- uses: pguyot/arm-runner-action@v2
|
|
||||||
name: Generate image
|
|
||||||
id: generate_image
|
|
||||||
with:
|
|
||||||
base_image: ${{ matrix.image_url }}
|
|
||||||
image_additional_mb: ${{ matrix.image_additional_mb }}
|
|
||||||
optimize_image: yes
|
|
||||||
cpu: ${{ matrix.cpu }}
|
|
||||||
# We do _not_ wanna copy photon into the image. Bind mount instead
|
|
||||||
bind_mount_repository: true
|
|
||||||
commands: |
|
|
||||||
chmod +x scripts/armrunner.sh
|
|
||||||
./scripts/armrunner.sh
|
|
||||||
- name: Compress image
|
|
||||||
run: |
|
|
||||||
new_jar=$(realpath $(find . -name photonvision\*-linuxarm64.jar))
|
|
||||||
new_image_name=$(basename "${new_jar/.jar/_${{ matrix.image_suffix }}.img}")
|
|
||||||
mv ${{ steps.generate_image.outputs.image }} $new_image_name
|
|
||||||
sudo xz -T 0 -v $new_image_name
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
name: Upload image
|
|
||||||
with:
|
|
||||||
name: image-${{ matrix.image_suffix }}
|
|
||||||
path: photonvision*.xz
|
|
||||||
release:
|
|
||||||
needs: [build-package, build-image]
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
# Download literally every single artifact. This also downloads client and docs,
|
|
||||||
# but the filtering below won't pick these up (I hope)
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
- run: find
|
|
||||||
# Push to dev release
|
|
||||||
- uses: pyTooling/Actions/releaser@r0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
tag: 'Dev'
|
|
||||||
rm: true
|
|
||||||
files: |
|
|
||||||
**/*.xz
|
|
||||||
**/*.jar
|
|
||||||
**/photonlib*.json
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
# Upload all jars and xz archives
|
|
||||||
- uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
**/*.xz
|
|
||||||
**/*.jar
|
|
||||||
**/photonlib*.json
|
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|||||||
86
.github/workflows/documentation.yml
vendored
86
.github/workflows/documentation.yml
vendored
@@ -1,86 +0,0 @@
|
|||||||
name: Documentation
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
# For now, run on all commits to master
|
|
||||||
branches: [ master ]
|
|
||||||
# and also all tags starting with v
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-client:
|
|
||||||
name: "PhotonClient Build"
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: photon-client
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: Build Production Client
|
|
||||||
run: npm run build-demo
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: built-client
|
|
||||||
path: photon-client/dist/
|
|
||||||
|
|
||||||
run_docs:
|
|
||||||
runs-on: "ubuntu-22.04"
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Fetch tags
|
|
||||||
run: git fetch --tags --force
|
|
||||||
- name: Install Java 17
|
|
||||||
uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
|
|
||||||
- name: Build javadocs/doxygen
|
|
||||||
run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew docs:generateJavaDocs docs:doxygen
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: built-docs
|
|
||||||
path: docs/build/docs
|
|
||||||
|
|
||||||
release:
|
|
||||||
needs: [build-client, run_docs]
|
|
||||||
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
|
|
||||||
# Download literally every single artifact.
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
|
|
||||||
- run: find .
|
|
||||||
- name: copy file via ssh password
|
|
||||||
uses: appleboy/scp-action@v0.1.7
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.WEBMASTER_SSH_HOST }}
|
|
||||||
username: ${{ secrets.WEBMASTER_SSH_USERNAME }}
|
|
||||||
password: ${{ secrets.WEBMASTER_SSH_KEY }}
|
|
||||||
port: ${{ secrets.WEBMASTER_SSH_PORT }}
|
|
||||||
source: "*"
|
|
||||||
target: /var/www/html/photonvision-docs/
|
|
||||||
88
.github/workflows/lint-format.yml
vendored
88
.github/workflows/lint-format.yml
vendored
@@ -1,88 +0,0 @@
|
|||||||
name: Lint and Format
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
wpiformat:
|
|
||||||
name: "wpiformat"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Fetch all history and metadata
|
|
||||||
run: |
|
|
||||||
git fetch --prune --unshallow
|
|
||||||
git checkout -b pr
|
|
||||||
git branch -f master origin/master
|
|
||||||
- name: Set up Python 3.8
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: 3.8
|
|
||||||
- name: Install wpiformat
|
|
||||||
run: pip3 install wpiformat
|
|
||||||
- name: Run
|
|
||||||
run: wpiformat
|
|
||||||
- name: Check output
|
|
||||||
run: git --no-pager diff --exit-code HEAD
|
|
||||||
- name: Generate diff
|
|
||||||
run: git diff HEAD > wpiformat-fixes.patch
|
|
||||||
if: ${{ failure() }}
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: wpiformat fixes
|
|
||||||
path: wpiformat-fixes.patch
|
|
||||||
if: ${{ failure() }}
|
|
||||||
javaformat:
|
|
||||||
name: "Java Formatting"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
distribution: temurin
|
|
||||||
- run: |
|
|
||||||
chmod +x gradlew
|
|
||||||
./gradlew spotlessCheck
|
|
||||||
|
|
||||||
client-lint-format:
|
|
||||||
name: "PhotonClient Lint and Formatting"
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: photon-client
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: Check Linting
|
|
||||||
run: npm run lint-ci
|
|
||||||
- name: Check Formatting
|
|
||||||
run: npm run format-ci
|
|
||||||
server-index:
|
|
||||||
name: "Check server index.html not changed"
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Fetch all history and metadata
|
|
||||||
run: |
|
|
||||||
git fetch --prune --unshallow
|
|
||||||
git checkout -b pr
|
|
||||||
git branch -f master origin/master
|
|
||||||
- name: Check index.html not changed
|
|
||||||
run: git --no-pager diff --exit-code origin/master photon-server/src/main/resources/web/index.html
|
|
||||||
60
.github/workflows/python.yml
vendored
60
.github/workflows/python.yml
vendored
@@ -1,60 +0,0 @@
|
|||||||
name: Build and Distribute PhotonLibPy
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
buildAndDeploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: 3.11
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
python -m pip install --upgrade pip
|
|
||||||
pip install setuptools wheel pytest
|
|
||||||
|
|
||||||
- name: Build wheel
|
|
||||||
working-directory: ./photon-lib/py
|
|
||||||
run: |
|
|
||||||
python setup.py sdist bdist_wheel
|
|
||||||
|
|
||||||
- name: Run Unit Tests
|
|
||||||
working-directory: ./photon-lib/py
|
|
||||||
run: |
|
|
||||||
pip install --no-cache-dir dist/*.whl
|
|
||||||
pytest
|
|
||||||
|
|
||||||
|
|
||||||
- name: Upload artifacts
|
|
||||||
uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: dist
|
|
||||||
path: ./photon-lib/py/dist/
|
|
||||||
|
|
||||||
- name: Publish package distributions to TestPyPI
|
|
||||||
# Only upload on tags
|
|
||||||
if: startsWith(github.ref, 'refs/tags/v')
|
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
|
||||||
with:
|
|
||||||
packages_dir: ./photon-lib/py/dist/
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
||||||
21
build.gradle
21
build.gradle
@@ -4,7 +4,7 @@ plugins {
|
|||||||
id "com.diffplug.spotless" version "6.24.0"
|
id "com.diffplug.spotless" version "6.24.0"
|
||||||
id "edu.wpi.first.NativeUtils" version "2024.6.1" apply false
|
id "edu.wpi.first.NativeUtils" version "2024.6.1" apply false
|
||||||
id "edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin" version "2020.2"
|
id "edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin" version "2020.2"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
id 'edu.wpi.first.WpilibTools' version '1.3.0'
|
id 'edu.wpi.first.WpilibTools' version '1.3.0'
|
||||||
id 'com.google.protobuf' version '0.9.4' apply false
|
id 'com.google.protobuf' version '0.9.4' apply false
|
||||||
}
|
}
|
||||||
@@ -13,8 +13,9 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
maven { url = "https://maven.photonvision.org/releases" }
|
||||||
maven { url = "https://maven.photonvision.org/repository/snapshots/" }
|
maven { url = "https://maven.photonvision.org/snapshots" }
|
||||||
|
maven { url = "https://jogamp.org/deployment/maven/" }
|
||||||
}
|
}
|
||||||
wpilibRepositories.addAllReleaseRepositories(it)
|
wpilibRepositories.addAllReleaseRepositories(it)
|
||||||
wpilibRepositories.addAllDevelopmentRepositories(it)
|
wpilibRepositories.addAllDevelopmentRepositories(it)
|
||||||
@@ -24,15 +25,15 @@ allprojects {
|
|||||||
apply from: "versioningHelper.gradle"
|
apply from: "versioningHelper.gradle"
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
wpilibVersion = "2024.3.1"
|
wpilibVersion = "2024.3.2"
|
||||||
wpimathVersion = wpilibVersion
|
wpimathVersion = wpilibVersion
|
||||||
openCVversion = "4.8.0-2"
|
openCVversion = "4.8.0-2"
|
||||||
joglVersion = "2.4.0-rc-20200307"
|
joglVersion = "2.4.0"
|
||||||
javalinVersion = "5.6.2"
|
javalinVersion = "5.6.2"
|
||||||
photonGlDriverLibVersion = "dev-v2023.1.0-9-g75fc678"
|
photonGlDriverLibVersion = "dev-v2023.1.0-11-g2b7036f"
|
||||||
rknnVersion = "dev-v2024.0.0-64-gc0836a6"
|
rknnVersion = "dev-v2024.0.1-4-g0db16ac"
|
||||||
frcYear = "2024"
|
frcYear = "2024"
|
||||||
mrcalVersion = "dev-v2024.0.0-18-gb903a09";
|
mrcalVersion = "dev-v2024.0.0-24-gc1efcf0";
|
||||||
|
|
||||||
|
|
||||||
pubVersion = versionString
|
pubVersion = versionString
|
||||||
@@ -50,6 +51,10 @@ ext {
|
|||||||
println("Building for platform " + jniPlatform + " wpilib: " + wpilibNativeName)
|
println("Building for platform " + jniPlatform + " wpilib: " + wpilibNativeName)
|
||||||
println("Using Wpilib: " + wpilibVersion)
|
println("Using Wpilib: " + wpilibVersion)
|
||||||
println("Using OpenCV: " + openCVversion)
|
println("Using OpenCV: " + openCVversion)
|
||||||
|
|
||||||
|
|
||||||
|
photonMavenURL = 'https://maven.photonvision.org/' + (isDev ? 'snapshots' : 'releases');
|
||||||
|
println("Publishing Photonlib to " + photonMavenURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
spotless {
|
spotless {
|
||||||
|
|||||||
@@ -13,11 +13,7 @@ defineProps<{
|
|||||||
|
|
||||||
const driverMode = computed<boolean>({
|
const driverMode = computed<boolean>({
|
||||||
get: () => useCameraSettingsStore().isDriverMode,
|
get: () => useCameraSettingsStore().isDriverMode,
|
||||||
set: (v) =>
|
set: (v) => useCameraSettingsStore().setDriverMode(v)
|
||||||
useCameraSettingsStore().changeCurrentPipelineIndex(
|
|
||||||
v ? -1 : useCameraSettingsStore().currentCameraSettings.lastPipelineIndex || 0,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const fpsTooLow = computed<boolean>(() => {
|
const fpsTooLow = computed<boolean>(() => {
|
||||||
|
|||||||
@@ -130,12 +130,32 @@ const interactiveCols = computed(() =>
|
|||||||
tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
|
tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
|
||||||
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraBlueGain: args }, false)"
|
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ cameraBlueGain: args }, false)"
|
||||||
/>
|
/>
|
||||||
|
<!-- Disable camera orientation as stop gap for Issue 1084 until calibration data gets rotated. https://github.com/PhotonVision/photonvision/issues/1084 -->
|
||||||
|
<v-banner
|
||||||
|
v-show="
|
||||||
|
useCameraSettingsStore().isCurrentVideoFormatCalibrated &&
|
||||||
|
useCameraSettingsStore().currentPipelineSettings.inputImageRotationMode != 0
|
||||||
|
"
|
||||||
|
rounded
|
||||||
|
dark
|
||||||
|
color="red"
|
||||||
|
text-color="white"
|
||||||
|
class="mt-3"
|
||||||
|
icon="mdi-alert-circle-outline"
|
||||||
|
>
|
||||||
|
Warning! A known bug affects rotation of calibrated camera. Turn off rotation here and rotate using
|
||||||
|
cameraToRobotTransform in your robot code.
|
||||||
|
</v-banner>
|
||||||
<pv-select
|
<pv-select
|
||||||
v-model="useCameraSettingsStore().currentPipelineSettings.inputImageRotationMode"
|
v-model="useCameraSettingsStore().currentPipelineSettings.inputImageRotationMode"
|
||||||
label="Orientation"
|
label="Orientation"
|
||||||
tooltip="Rotates the camera stream"
|
tooltip="Rotates the camera stream. Rotation not available when camera has been calibrated."
|
||||||
:items="cameraRotations"
|
:items="cameraRotations"
|
||||||
:select-cols="interactiveCols"
|
:select-cols="interactiveCols"
|
||||||
|
:disabled="
|
||||||
|
useCameraSettingsStore().isCurrentVideoFormatCalibrated &&
|
||||||
|
useCameraSettingsStore().currentPipelineSettings.inputImageRotationMode == 0
|
||||||
|
"
|
||||||
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ inputImageRotationMode: args }, false)"
|
@input="(args) => useCameraSettingsStore().changeCurrentPipelineSetting({ inputImageRotationMode: args }, false)"
|
||||||
/>
|
/>
|
||||||
<pv-select
|
<pv-select
|
||||||
|
|||||||
@@ -236,6 +236,13 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
|
|||||||
}
|
}
|
||||||
useStateStore().websocket?.send(payload, true);
|
useStateStore().websocket?.send(payload, true);
|
||||||
},
|
},
|
||||||
|
setDriverMode(isDriverMode: boolean, cameraIndex: number = useStateStore().currentCameraIndex) {
|
||||||
|
const payload = {
|
||||||
|
driverMode: isDriverMode,
|
||||||
|
cameraIndex: cameraIndex
|
||||||
|
};
|
||||||
|
useStateStore().websocket?.send(payload, true);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Change the currently selected pipeline of the provided camera.
|
* Change the currently selected pipeline of the provided camera.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
import org.photonvision.common.logging.LogGroup;
|
import org.photonvision.common.logging.LogGroup;
|
||||||
import org.photonvision.common.logging.Logger;
|
import org.photonvision.common.logging.Logger;
|
||||||
import org.photonvision.common.util.TestUtils;
|
import org.photonvision.common.util.TestUtils;
|
||||||
import org.photonvision.rknn.RknnJNI;
|
import org.photonvision.rknn.RknnJNI;
|
||||||
import org.photonvision.rknn.RknnJNI.RknnResult;
|
import org.photonvision.rknn.RknnJNI.RknnResult;
|
||||||
import org.photonvision.vision.opencv.CVMat;
|
|
||||||
import org.photonvision.vision.pipe.impl.NeuralNetworkPipeResult;
|
import org.photonvision.vision.pipe.impl.NeuralNetworkPipeResult;
|
||||||
|
|
||||||
public class RknnDetectorJNI extends PhotonJNICommon {
|
public class RknnDetectorJNI extends PhotonJNICommon {
|
||||||
@@ -65,16 +65,38 @@ public class RknnDetectorJNI extends PhotonJNICommon {
|
|||||||
long objPointer = -1;
|
long objPointer = -1;
|
||||||
private List<String> labels;
|
private List<String> labels;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
private static final CopyOnWriteArrayList<Long> detectors = new CopyOnWriteArrayList<>();
|
private static final CopyOnWriteArrayList<RknnObjectDetector> detectors =
|
||||||
|
new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
static volatile boolean hook = false;
|
||||||
|
|
||||||
public RknnObjectDetector(String modelPath, List<String> labels, RknnJNI.ModelVersion version) {
|
public RknnObjectDetector(String modelPath, List<String> labels, RknnJNI.ModelVersion version) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
objPointer = RknnJNI.create(modelPath, labels.size(), version.ordinal(), -1);
|
objPointer = RknnJNI.create(modelPath, labels.size(), version.ordinal(), -1);
|
||||||
detectors.add(objPointer);
|
detectors.add(this);
|
||||||
System.out.println(
|
logger.debug(
|
||||||
"Created " + objPointer + "! Detectors: " + Arrays.toString(detectors.toArray()));
|
"Created detector "
|
||||||
|
+ objPointer
|
||||||
|
+ " from path "
|
||||||
|
+ modelPath
|
||||||
|
+ "! Detectors: "
|
||||||
|
+ Arrays.toString(detectors.toArray()));
|
||||||
}
|
}
|
||||||
this.labels = labels;
|
this.labels = labels;
|
||||||
|
|
||||||
|
// the kernel should probably alredy deal with this for us, but I'm gunna be paranoid anyways.
|
||||||
|
if (!hook) {
|
||||||
|
Runtime.getRuntime()
|
||||||
|
.addShutdownHook(
|
||||||
|
new Thread(
|
||||||
|
() -> {
|
||||||
|
System.err.println("Shutdown hook rknn");
|
||||||
|
for (var d : detectors) {
|
||||||
|
d.release();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
hook = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getClasses() {
|
public List<String> getClasses() {
|
||||||
@@ -89,14 +111,14 @@ public class RknnDetectorJNI extends PhotonJNICommon {
|
|||||||
* @param boxThresh Minimum confidence for a box to be added. Basically just confidence
|
* @param boxThresh Minimum confidence for a box to be added. Basically just confidence
|
||||||
* threshold
|
* threshold
|
||||||
*/
|
*/
|
||||||
public List<NeuralNetworkPipeResult> detect(CVMat in, double nmsThresh, double boxThresh) {
|
public List<NeuralNetworkPipeResult> detect(Mat in, double nmsThresh, double boxThresh) {
|
||||||
RknnResult[] ret;
|
RknnResult[] ret;
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
// We can technically be asked to detect and the lock might be acquired _after_ release has
|
// We can technically be asked to detect and the lock might be acquired _after_ release has
|
||||||
// been called. This would mean objPointer would be invalid which would call everything to
|
// been called. This would mean objPointer would be invalid which would call everything to
|
||||||
// explode.
|
// explode.
|
||||||
if (objPointer > 0) {
|
if (objPointer > 0) {
|
||||||
ret = RknnJNI.detect(objPointer, in.getMat().getNativeObjAddr(), nmsThresh, boxThresh);
|
ret = RknnJNI.detect(objPointer, in.getNativeObjAddr(), nmsThresh, boxThresh);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Detect called after destroy -- giving up");
|
logger.warn("Detect called after destroy -- giving up");
|
||||||
return List.of();
|
return List.of();
|
||||||
@@ -114,7 +136,7 @@ public class RknnDetectorJNI extends PhotonJNICommon {
|
|||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (objPointer > 0) {
|
if (objPointer > 0) {
|
||||||
RknnJNI.destroy(objPointer);
|
RknnJNI.destroy(objPointer);
|
||||||
detectors.remove(objPointer);
|
detectors.remove(this);
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"Killed " + objPointer + "! Detectors: " + Arrays.toString(detectors.toArray()));
|
"Killed " + objPointer + "! Detectors: " + Arrays.toString(detectors.toArray()));
|
||||||
objPointer = -1;
|
objPointer = -1;
|
||||||
@@ -124,14 +146,4 @@ public class RknnDetectorJNI extends PhotonJNICommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static void createRknnDetector() {
|
|
||||||
// objPointer =
|
|
||||||
// RknnJNI.create(
|
|
||||||
// NeuralNetworkModelManager.getInstance()
|
|
||||||
// .getDefaultRknnModel()
|
|
||||||
// .getAbsolutePath()
|
|
||||||
// .toString(),
|
|
||||||
// NeuralNetworkModelManager.getInstance().getLabels().size());
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,9 +270,13 @@ public class USBCameraSource extends VisionSource {
|
|||||||
if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV9281)) {
|
if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV9281)) {
|
||||||
propMin = 1;
|
propMin = 1;
|
||||||
propMax = 75;
|
propMax = 75;
|
||||||
|
} else if (getCameraConfiguration().cameraQuirks.hasQuirk(CameraQuirk.ArduOV2311)) {
|
||||||
|
propMin = 1;
|
||||||
|
propMax = 140;
|
||||||
}
|
}
|
||||||
|
|
||||||
var exposure_manual_val = MathUtils.map(Math.round(exposure), 0, 100, propMin, propMax);
|
var exposure_manual_val = MathUtils.map(Math.round(exposure), 0, 100, propMin, propMax);
|
||||||
|
logger.debug("Setting camera exposure to " + exposure_manual_val);
|
||||||
prop.set((int) exposure_manual_val);
|
prop.set((int) exposure_manual_val);
|
||||||
} else {
|
} else {
|
||||||
scaledExposure = (int) Math.round(exposure);
|
scaledExposure = (int) Math.round(exposure);
|
||||||
|
|||||||
@@ -189,15 +189,15 @@ public class Calibrate3dPipe
|
|||||||
int imageWidth = (int) in.get(0).size.width;
|
int imageWidth = (int) in.get(0).size.width;
|
||||||
int imageHeight = (int) in.get(0).size.height;
|
int imageHeight = (int) in.get(0).size.height;
|
||||||
|
|
||||||
MrCalResult result =
|
MrCalResult result = null;
|
||||||
MrCalJNI.calibrateCamera(
|
// MrCalJNI.calibrateCamera(
|
||||||
corner_locations,
|
// corner_locations,
|
||||||
params.boardWidth,
|
// params.boardWidth,
|
||||||
params.boardHeight,
|
// params.boardHeight,
|
||||||
params.squareSize,
|
// params.squareSize,
|
||||||
imageWidth,
|
// imageWidth,
|
||||||
imageHeight,
|
// imageHeight,
|
||||||
(fxGuess + fyGuess) / 2.0);
|
// (fxGuess + fyGuess) / 2.0);
|
||||||
|
|
||||||
// intrinsics are fx fy cx cy from mrcal
|
// intrinsics are fx fy cx cy from mrcal
|
||||||
JsonMatOfDouble cameraMatrixMat =
|
JsonMatOfDouble cameraMatrixMat =
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class FilterObjectDetectionsPipe
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void filterContour(NeuralNetworkPipeResult contour) {
|
private void filterContour(NeuralNetworkPipeResult contour) {
|
||||||
var boc = contour.box;
|
var boc = contour.bbox;
|
||||||
|
|
||||||
// Area filtering
|
// Area filtering
|
||||||
double areaPercentage = boc.area() / params.getFrameStaticProperties().imageArea * 100.0;
|
double areaPercentage = boc.area() / params.getFrameStaticProperties().imageArea * 100.0;
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ package org.photonvision.vision.pipe.impl;
|
|||||||
import org.opencv.core.Rect2d;
|
import org.opencv.core.Rect2d;
|
||||||
|
|
||||||
public class NeuralNetworkPipeResult {
|
public class NeuralNetworkPipeResult {
|
||||||
public NeuralNetworkPipeResult(Rect2d box2, Integer classIdx, Float confidence) {
|
public NeuralNetworkPipeResult(Rect2d boundingBox, int classIdx, double confidence) {
|
||||||
box = box2;
|
bbox = boundingBox;
|
||||||
this.classIdx = classIdx;
|
this.classIdx = classIdx;
|
||||||
this.confidence = confidence;
|
this.confidence = confidence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int classIdx;
|
public final int classIdx;
|
||||||
public final Rect2d box;
|
public final Rect2d bbox;
|
||||||
public final double confidence;
|
public final double confidence;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,17 @@
|
|||||||
|
|
||||||
package org.photonvision.vision.pipe.impl;
|
package org.photonvision.vision.pipe.impl;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.core.Rect2d;
|
||||||
|
import org.opencv.core.Scalar;
|
||||||
|
import org.opencv.core.Size;
|
||||||
|
import org.opencv.imgproc.Imgproc;
|
||||||
import org.photonvision.common.configuration.NeuralNetworkModelManager;
|
import org.photonvision.common.configuration.NeuralNetworkModelManager;
|
||||||
|
import org.photonvision.common.util.ColorHelper;
|
||||||
import org.photonvision.jni.RknnDetectorJNI.RknnObjectDetector;
|
import org.photonvision.jni.RknnDetectorJNI.RknnObjectDetector;
|
||||||
import org.photonvision.vision.opencv.CVMat;
|
import org.photonvision.vision.opencv.CVMat;
|
||||||
import org.photonvision.vision.opencv.Releasable;
|
import org.photonvision.vision.opencv.Releasable;
|
||||||
@@ -30,8 +39,10 @@ public class RknnDetectionPipe
|
|||||||
private RknnObjectDetector detector;
|
private RknnObjectDetector detector;
|
||||||
|
|
||||||
public RknnDetectionPipe() {
|
public RknnDetectionPipe() {
|
||||||
// For now this is hard-coded to defaults. Should be refactored into set pipe params, though.
|
// For now this is hard-coded to defaults. Should be refactored into set pipe
|
||||||
// And ideally a little wrapper helper for only changing native stuff on content change created.
|
// params, though.
|
||||||
|
// And ideally a little wrapper helper for only changing native stuff on content
|
||||||
|
// change created.
|
||||||
this.detector =
|
this.detector =
|
||||||
new RknnObjectDetector(
|
new RknnObjectDetector(
|
||||||
NeuralNetworkModelManager.getInstance().getDefaultRknnModel().getAbsolutePath(),
|
NeuralNetworkModelManager.getInstance().getDefaultRknnModel().getAbsolutePath(),
|
||||||
@@ -39,6 +50,18 @@ public class RknnDetectionPipe
|
|||||||
NeuralNetworkModelManager.getInstance().getModelVersion());
|
NeuralNetworkModelManager.getInstance().getModelVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Letterbox {
|
||||||
|
double dx;
|
||||||
|
double dy;
|
||||||
|
double scale;
|
||||||
|
|
||||||
|
public Letterbox(double dx, double dy, double scale) {
|
||||||
|
this.dx = dx;
|
||||||
|
this.dy = dy;
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<NeuralNetworkPipeResult> process(CVMat in) {
|
protected List<NeuralNetworkPipeResult> process(CVMat in) {
|
||||||
var frame = in.getMat();
|
var frame = in.getMat();
|
||||||
@@ -48,7 +71,67 @@ public class RknnDetectionPipe
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
return detector.detect(in, params.nms, params.confidence);
|
// letterbox
|
||||||
|
var letterboxed = new Mat();
|
||||||
|
var scale =
|
||||||
|
letterbox(frame, letterboxed, new Size(640, 640), ColorHelper.colorToScalar(Color.GRAY));
|
||||||
|
|
||||||
|
if (letterboxed.width() != 640 || letterboxed.height() != 640) {
|
||||||
|
// huh whack give up lol
|
||||||
|
throw new RuntimeException("RGA bugged but still wrong size");
|
||||||
|
}
|
||||||
|
var ret = detector.detect(letterboxed, params.nms, params.confidence);
|
||||||
|
letterboxed.release();
|
||||||
|
|
||||||
|
return resizeDetections(ret, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<NeuralNetworkPipeResult> resizeDetections(
|
||||||
|
List<NeuralNetworkPipeResult> unscaled, Letterbox letterbox) {
|
||||||
|
var ret = new ArrayList<NeuralNetworkPipeResult>();
|
||||||
|
|
||||||
|
for (var t : unscaled) {
|
||||||
|
var scale = 1.0 / letterbox.scale;
|
||||||
|
var boundingBox = t.bbox;
|
||||||
|
double x = (boundingBox.x - letterbox.dx) * scale;
|
||||||
|
double y = (boundingBox.y - letterbox.dy) * scale;
|
||||||
|
double width = boundingBox.width * scale;
|
||||||
|
double height = boundingBox.height * scale;
|
||||||
|
|
||||||
|
ret.add(
|
||||||
|
new NeuralNetworkPipeResult(new Rect2d(x, y, width, height), t.classIdx, t.confidence));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Letterbox letterbox(Mat frame, Mat letterboxed, Size newShape, Scalar color) {
|
||||||
|
// from https://github.com/ultralytics/yolov5/issues/8427#issuecomment-1172469631
|
||||||
|
var frameSize = frame.size();
|
||||||
|
var r = Math.min(newShape.height / frameSize.height, newShape.width / frameSize.width);
|
||||||
|
|
||||||
|
var newUnpad = new Size(Math.round(frameSize.width * r), Math.round(frameSize.height * r));
|
||||||
|
|
||||||
|
if (!(frameSize.equals(newUnpad))) {
|
||||||
|
Imgproc.resize(frame, letterboxed, newUnpad, Imgproc.INTER_LINEAR);
|
||||||
|
} else {
|
||||||
|
frame.copyTo(letterboxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dw = newShape.width - newUnpad.width;
|
||||||
|
var dh = newShape.height - newUnpad.height;
|
||||||
|
|
||||||
|
dw /= 2;
|
||||||
|
dh /= 2;
|
||||||
|
|
||||||
|
int top = (int) (Math.round(dh - 0.1f));
|
||||||
|
int bottom = (int) (Math.round(dh + 0.1f));
|
||||||
|
int left = (int) (Math.round(dw - 0.1f));
|
||||||
|
int right = (int) (Math.round(dw + 0.1f));
|
||||||
|
Core.copyMakeBorder(
|
||||||
|
letterboxed, letterboxed, top, bottom, left, right, Core.BORDER_CONSTANT, color);
|
||||||
|
|
||||||
|
return new Letterbox(dw, dh, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RknnDetectionPipeParams {
|
public static class RknnDetectionPipeParams {
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ public class PipelineManager {
|
|||||||
PipelineManager(
|
PipelineManager(
|
||||||
DriverModePipelineSettings driverSettings,
|
DriverModePipelineSettings driverSettings,
|
||||||
List<CVPipelineSettings> userPipelines,
|
List<CVPipelineSettings> userPipelines,
|
||||||
String uniqueName) {
|
String uniqueName,
|
||||||
|
int defaultIndex) {
|
||||||
this.userPipelineSettings = new ArrayList<>(userPipelines);
|
this.userPipelineSettings = new ArrayList<>(userPipelines);
|
||||||
// This is to respect the default res idx for vendor cameras
|
// This is to respect the default res idx for vendor cameras
|
||||||
|
|
||||||
@@ -70,10 +71,19 @@ public class PipelineManager {
|
|||||||
if (userPipelines.isEmpty()) addPipeline(PipelineType.Reflective);
|
if (userPipelines.isEmpty()) addPipeline(PipelineType.Reflective);
|
||||||
|
|
||||||
calibration3dPipeline = new Calibrate3dPipeline(uniqueName);
|
calibration3dPipeline = new Calibrate3dPipeline(uniqueName);
|
||||||
|
|
||||||
|
// We know that at this stage, VisionRunner hasn't yet started so we're good to do this from
|
||||||
|
// this thread
|
||||||
|
this.setIndex(defaultIndex);
|
||||||
|
updatePipelineFromRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PipelineManager(CameraConfiguration config) {
|
public PipelineManager(CameraConfiguration config) {
|
||||||
this(config.driveModeSettings, config.pipelineSettings, config.uniqueName);
|
this(
|
||||||
|
config.driveModeSettings,
|
||||||
|
config.pipelineSettings,
|
||||||
|
config.uniqueName,
|
||||||
|
config.currentPipelineIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,6 +183,14 @@ public class PipelineManager {
|
|||||||
|
|
||||||
private volatile int requestedIndex = 0;
|
private volatile int requestedIndex = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grab the currently requested pipeline index. The VisionRunner may not have changed over to this
|
||||||
|
* pipeline yet.
|
||||||
|
*/
|
||||||
|
public int getRequestedIndex() {
|
||||||
|
return requestedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal method for setting the active pipeline. <br>
|
* Internal method for setting the active pipeline. <br>
|
||||||
* <br>
|
* <br>
|
||||||
@@ -208,44 +226,10 @@ public class PipelineManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup potential old native resources before swapping over for user pipelines
|
|
||||||
if (currentUserPipeline != null && !(newIndex < 0)) {
|
|
||||||
currentUserPipeline.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPipelineIndex = newIndex;
|
currentPipelineIndex = newIndex;
|
||||||
if (newIndex >= 0) {
|
|
||||||
var desiredPipelineSettings = userPipelineSettings.get(currentPipelineIndex);
|
|
||||||
switch (desiredPipelineSettings.pipelineType) {
|
|
||||||
case Reflective:
|
|
||||||
logger.debug("Creating Reflective pipeline");
|
|
||||||
currentUserPipeline =
|
|
||||||
new ReflectivePipeline((ReflectivePipelineSettings) desiredPipelineSettings);
|
|
||||||
break;
|
|
||||||
case ColoredShape:
|
|
||||||
logger.debug("Creating ColoredShape pipeline");
|
|
||||||
currentUserPipeline =
|
|
||||||
new ColoredShapePipeline((ColoredShapePipelineSettings) desiredPipelineSettings);
|
|
||||||
break;
|
|
||||||
case AprilTag:
|
|
||||||
logger.debug("Creating AprilTag pipeline");
|
|
||||||
currentUserPipeline =
|
|
||||||
new AprilTagPipeline((AprilTagPipelineSettings) desiredPipelineSettings);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Aruco:
|
if (newIndex >= 0) {
|
||||||
logger.debug("Creating Aruco Pipeline");
|
recreateUserPipeline();
|
||||||
currentUserPipeline = new ArucoPipeline((ArucoPipelineSettings) desiredPipelineSettings);
|
|
||||||
break;
|
|
||||||
case ObjectDetection:
|
|
||||||
logger.debug("Creating ObjectDetection Pipeline");
|
|
||||||
currentUserPipeline =
|
|
||||||
new ObjectDetectionPipeline(
|
|
||||||
(ObjectDetectionPipelineSettings) desiredPipelineSettings);
|
|
||||||
default:
|
|
||||||
// Can be calib3d or drivermode, both of which are special cases
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataChangeService.getInstance()
|
DataChangeService.getInstance()
|
||||||
@@ -254,6 +238,48 @@ public class PipelineManager {
|
|||||||
"fullsettings", ConfigManager.getInstance().getConfig().toHashMap()));
|
"fullsettings", ConfigManager.getInstance().getConfig().toHashMap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recreate the current user pipeline with the current pipeline index. Useful to force a
|
||||||
|
* recreation after changing pipeline type
|
||||||
|
*/
|
||||||
|
private void recreateUserPipeline() {
|
||||||
|
// Cleanup potential old native resources before swapping over from a user pipeline
|
||||||
|
if (currentUserPipeline != null && !(currentPipelineIndex < 0)) {
|
||||||
|
currentUserPipeline.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
var desiredPipelineSettings = userPipelineSettings.get(currentPipelineIndex);
|
||||||
|
switch (desiredPipelineSettings.pipelineType) {
|
||||||
|
case Reflective:
|
||||||
|
logger.debug("Creating Reflective pipeline");
|
||||||
|
currentUserPipeline =
|
||||||
|
new ReflectivePipeline((ReflectivePipelineSettings) desiredPipelineSettings);
|
||||||
|
break;
|
||||||
|
case ColoredShape:
|
||||||
|
logger.debug("Creating ColoredShape pipeline");
|
||||||
|
currentUserPipeline =
|
||||||
|
new ColoredShapePipeline((ColoredShapePipelineSettings) desiredPipelineSettings);
|
||||||
|
break;
|
||||||
|
case AprilTag:
|
||||||
|
logger.debug("Creating AprilTag pipeline");
|
||||||
|
currentUserPipeline =
|
||||||
|
new AprilTagPipeline((AprilTagPipelineSettings) desiredPipelineSettings);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Aruco:
|
||||||
|
logger.debug("Creating Aruco Pipeline");
|
||||||
|
currentUserPipeline = new ArucoPipeline((ArucoPipelineSettings) desiredPipelineSettings);
|
||||||
|
break;
|
||||||
|
case ObjectDetection:
|
||||||
|
logger.debug("Creating ObjectDetection Pipeline");
|
||||||
|
currentUserPipeline =
|
||||||
|
new ObjectDetectionPipeline((ObjectDetectionPipelineSettings) desiredPipelineSettings);
|
||||||
|
default:
|
||||||
|
// Can be calib3d or drivermode, both of which are special cases
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enters or exits calibration mode based on the parameter. <br>
|
* Enters or exits calibration mode based on the parameter. <br>
|
||||||
* <br>
|
* <br>
|
||||||
@@ -484,5 +510,6 @@ public class PipelineManager {
|
|||||||
userPipelineSettings.set(idx, newSettings);
|
userPipelineSettings.set(idx, newSettings);
|
||||||
setPipelineInternal(idx);
|
setPipelineInternal(idx);
|
||||||
reassignIndexes();
|
reassignIndexes();
|
||||||
|
recreateUserPipeline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public class VisionModule {
|
|||||||
ntConsumer =
|
ntConsumer =
|
||||||
new NTDataPublisher(
|
new NTDataPublisher(
|
||||||
visionSource.getSettables().getConfiguration().nickname,
|
visionSource.getSettables().getConfiguration().nickname,
|
||||||
pipelineManager::getCurrentPipelineIndex,
|
pipelineManager::getRequestedIndex,
|
||||||
this::setPipeline,
|
this::setPipeline,
|
||||||
pipelineManager::getDriverMode,
|
pipelineManager::getDriverMode,
|
||||||
this::setDriverMode);
|
this::setDriverMode);
|
||||||
@@ -156,6 +156,7 @@ public class VisionModule {
|
|||||||
(result) ->
|
(result) ->
|
||||||
lastPipelineResultBestTarget = result.hasTargets() ? result.targets.get(0) : null);
|
lastPipelineResultBestTarget = result.hasTargets() ? result.targets.get(0) : null);
|
||||||
|
|
||||||
|
// Sync VisionModule state with the first pipeline index
|
||||||
setPipeline(visionSource.getSettables().getConfiguration().currentPipelineIndex);
|
setPipeline(visionSource.getSettables().getConfiguration().currentPipelineIndex);
|
||||||
|
|
||||||
// Set vendor FOV
|
// Set vendor FOV
|
||||||
@@ -321,7 +322,7 @@ public class VisionModule {
|
|||||||
|
|
||||||
void changePipelineType(int newType) {
|
void changePipelineType(int newType) {
|
||||||
pipelineManager.changePipelineType(newType);
|
pipelineManager.changePipelineType(newType);
|
||||||
setPipeline(pipelineManager.getCurrentPipelineIndex());
|
setPipeline(pipelineManager.getRequestedIndex());
|
||||||
saveAndBroadcastAll();
|
saveAndBroadcastAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,9 +330,7 @@ public class VisionModule {
|
|||||||
pipelineManager.setDriverMode(isDriverMode);
|
pipelineManager.setDriverMode(isDriverMode);
|
||||||
setVisionLEDs(!isDriverMode);
|
setVisionLEDs(!isDriverMode);
|
||||||
setPipeline(
|
setPipeline(
|
||||||
isDriverMode
|
isDriverMode ? PipelineManager.DRIVERMODE_INDEX : pipelineManager.getRequestedIndex());
|
||||||
? PipelineManager.DRIVERMODE_INDEX
|
|
||||||
: pipelineManager.getCurrentPipelineIndex());
|
|
||||||
saveAndBroadcastAll();
|
saveAndBroadcastAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,7 +384,7 @@ public class VisionModule {
|
|||||||
var ret = pipelineManager.calibration3dPipeline.tryCalibration();
|
var ret = pipelineManager.calibration3dPipeline.tryCalibration();
|
||||||
pipelineManager.setCalibrationMode(false);
|
pipelineManager.setCalibrationMode(false);
|
||||||
|
|
||||||
setPipeline(pipelineManager.getCurrentPipelineIndex());
|
setPipeline(pipelineManager.getRequestedIndex());
|
||||||
|
|
||||||
if (ret != null) {
|
if (ret != null) {
|
||||||
logger.debug("Saving calibration...");
|
logger.debug("Saving calibration...");
|
||||||
@@ -447,7 +446,7 @@ public class VisionModule {
|
|||||||
setVisionLEDs(pipelineSettings.ledMode);
|
setVisionLEDs(pipelineSettings.ledMode);
|
||||||
|
|
||||||
visionSource.getSettables().getConfiguration().currentPipelineIndex =
|
visionSource.getSettables().getConfiguration().currentPipelineIndex =
|
||||||
pipelineManager.getCurrentPipelineIndex();
|
pipelineManager.getRequestedIndex();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -511,7 +510,7 @@ public class VisionModule {
|
|||||||
ret.uniqueName = visionSource.getSettables().getConfiguration().uniqueName;
|
ret.uniqueName = visionSource.getSettables().getConfiguration().uniqueName;
|
||||||
ret.currentPipelineSettings =
|
ret.currentPipelineSettings =
|
||||||
SerializationUtils.objectToHashMap(pipelineManager.getCurrentPipelineSettings());
|
SerializationUtils.objectToHashMap(pipelineManager.getCurrentPipelineSettings());
|
||||||
ret.currentPipelineIndex = pipelineManager.getCurrentPipelineIndex();
|
ret.currentPipelineIndex = pipelineManager.getRequestedIndex();
|
||||||
ret.pipelineNicknames = pipelineManager.getPipelineNicknames();
|
ret.pipelineNicknames = pipelineManager.getPipelineNicknames();
|
||||||
ret.cameraQuirks = visionSource.getSettables().getConfiguration().cameraQuirks;
|
ret.cameraQuirks = visionSource.getSettables().getConfiguration().cameraQuirks;
|
||||||
|
|
||||||
@@ -553,7 +552,7 @@ public class VisionModule {
|
|||||||
var config = visionSource.getSettables().getConfiguration();
|
var config = visionSource.getSettables().getConfiguration();
|
||||||
config.setPipelineSettings(pipelineManager.userPipelineSettings);
|
config.setPipelineSettings(pipelineManager.userPipelineSettings);
|
||||||
config.driveModeSettings = pipelineManager.driverModePipeline.getSettings();
|
config.driveModeSettings = pipelineManager.driverModePipeline.getSettings();
|
||||||
config.currentPipelineIndex = Math.max(pipelineManager.getCurrentPipelineIndex(), -1);
|
config.currentPipelineIndex = Math.max(pipelineManager.getRequestedIndex(), -1);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
|||||||
parentModule.saveAndBroadcastAll();
|
parentModule.saveAndBroadcastAll();
|
||||||
return;
|
return;
|
||||||
case "deleteCurrPipeline":
|
case "deleteCurrPipeline":
|
||||||
var indexToDelete = parentModule.pipelineManager.getCurrentPipelineIndex();
|
var indexToDelete = parentModule.pipelineManager.getRequestedIndex();
|
||||||
logger.info("Deleting current pipe at index " + indexToDelete);
|
logger.info("Deleting current pipe at index " + indexToDelete);
|
||||||
int newIndex = parentModule.pipelineManager.removePipeline(indexToDelete);
|
int newIndex = parentModule.pipelineManager.removePipeline(indexToDelete);
|
||||||
parentModule.setPipeline(newIndex);
|
parentModule.setPipeline(newIndex);
|
||||||
@@ -96,7 +96,7 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
|||||||
return;
|
return;
|
||||||
case "changePipeline": // change active pipeline
|
case "changePipeline": // change active pipeline
|
||||||
var index = (Integer) newPropValue;
|
var index = (Integer) newPropValue;
|
||||||
if (index == parentModule.pipelineManager.getCurrentPipelineIndex()) {
|
if (index == parentModule.pipelineManager.getRequestedIndex()) {
|
||||||
logger.debug("Skipping pipeline change, index " + index + " already active");
|
logger.debug("Skipping pipeline change, index " + index + " already active");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -181,6 +181,9 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
|||||||
parentModule.changePipelineType((Integer) newPropValue);
|
parentModule.changePipelineType((Integer) newPropValue);
|
||||||
parentModule.saveAndBroadcastAll();
|
parentModule.saveAndBroadcastAll();
|
||||||
return;
|
return;
|
||||||
|
case "isDriverMode":
|
||||||
|
parentModule.setDriverMode((Boolean) newPropValue);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for camera settables
|
// special case for camera settables
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class PotentialTarget implements Releasable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PotentialTarget(NeuralNetworkPipeResult det) {
|
public PotentialTarget(NeuralNetworkPipeResult det) {
|
||||||
this.shape = new CVShape(new Contour(det.box), ContourShape.Quadrilateral);
|
this.shape = new CVShape(new Contour(det.bbox), ContourShape.Quadrilateral);
|
||||||
this.m_mainContour = this.shape.getContour();
|
this.m_mainContour = this.shape.getContour();
|
||||||
m_subContours = List.of();
|
m_subContours = List.of();
|
||||||
this.clsId = det.classIdx;
|
this.clsId = det.classIdx;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class PipelineManagerTest {
|
|||||||
public void testUniqueName() {
|
public void testUniqueName() {
|
||||||
TestUtils.loadLibraries();
|
TestUtils.loadLibraries();
|
||||||
PipelineManager manager =
|
PipelineManager manager =
|
||||||
new PipelineManager(new DriverModePipelineSettings(), List.of(), "meme_name");
|
new PipelineManager(new DriverModePipelineSettings(), List.of(), "meme_name", -1);
|
||||||
manager.addPipeline(PipelineType.Reflective, "Another");
|
manager.addPipeline(PipelineType.Reflective, "Another");
|
||||||
|
|
||||||
// We now have ["New Pipeline", "Another"]
|
// We now have ["New Pipeline", "Another"]
|
||||||
|
|||||||
34
photon-lib/src/generate/native/cpp/PhotonVersion.cpp
Normal file
34
photon-lib/src/generate/native/cpp/PhotonVersion.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Photon Vision.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Autogenerated file! Do not manually edit this file. This version is
|
||||||
|
* regenerated any time the publish task is run, or when this file is deleted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char* dev_ = "dev";
|
||||||
|
|
||||||
|
namespace photon {
|
||||||
|
namespace PhotonVersion {
|
||||||
|
const char* versionString = "dev-v2024.3.1-22-g38e2fdef";
|
||||||
|
const char* buildDate = "2024-5-29 10:05:11";
|
||||||
|
const bool isRelease = strncmp(dev_, versionString, strlen(dev_)) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,12 +96,12 @@ class SimCameraProperties {
|
|||||||
units::radian_t{std::numbers::pi / 2.0}})
|
units::radian_t{std::numbers::pi / 2.0}})
|
||||||
.Radians()}},
|
.Radians()}},
|
||||||
frc::Translation3d{
|
frc::Translation3d{
|
||||||
1_m, frc::Rotation3d{0_rad,
|
1_m,
|
||||||
(GetPixelPitch(0) +
|
frc::Rotation3d{0_rad,
|
||||||
frc::Rotation2d{
|
(GetPixelPitch(0) + frc::Rotation2d{units::radian_t{
|
||||||
units::radian_t{std::numbers::pi / 2.0}})
|
std::numbers::pi / 2.0}})
|
||||||
.Radians(),
|
.Radians(),
|
||||||
0_rad}},
|
0_rad}},
|
||||||
frc::Translation3d{
|
frc::Translation3d{
|
||||||
1_m, frc::Rotation3d{0_rad,
|
1_m, frc::Rotation3d{0_rad,
|
||||||
(GetPixelPitch(height) +
|
(GetPixelPitch(height) +
|
||||||
|
|||||||
@@ -131,18 +131,16 @@ public class DataSocketHandler {
|
|||||||
case SMT_DRIVERMODE:
|
case SMT_DRIVERMODE:
|
||||||
{
|
{
|
||||||
// TODO: what is this event?
|
// TODO: what is this event?
|
||||||
var data = (HashMap<String, Object>) entryValue;
|
var data = (Boolean) entryValue;
|
||||||
var dmExpEvent =
|
|
||||||
new IncomingWebSocketEvent<Integer>(
|
|
||||||
DataChangeDestination.DCD_ACTIVEMODULE, "driverExposure", data);
|
|
||||||
var dmBrightEvent =
|
|
||||||
new IncomingWebSocketEvent<Integer>(
|
|
||||||
DataChangeDestination.DCD_ACTIVEMODULE, "driverBrightness", data);
|
|
||||||
var dmIsDriverEvent =
|
var dmIsDriverEvent =
|
||||||
new IncomingWebSocketEvent<Boolean>(
|
new IncomingWebSocketEvent<Boolean>(
|
||||||
DataChangeDestination.DCD_ACTIVEMODULE, "isDriver", data);
|
DataChangeDestination.DCD_ACTIVEMODULE,
|
||||||
|
"isDriverMode",
|
||||||
|
data,
|
||||||
|
cameraIndex,
|
||||||
|
context);
|
||||||
|
|
||||||
dcService.publishEvents(dmExpEvent, dmBrightEvent, dmIsDriverEvent);
|
dcService.publishEvents(dmIsDriverEvent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMT_CHANGECAMERANAME:
|
case SMT_CHANGECAMERANAME:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "cpp"
|
id "cpp"
|
||||||
id "google-test-test-suite"
|
id "google-test-test-suite"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
|
|
||||||
id "com.dorongold.task-tree" version "2.1.0"
|
id "com.dorongold.task-tree" version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "cpp"
|
id "cpp"
|
||||||
id "google-test-test-suite"
|
id "google-test-test-suite"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
|
|
||||||
id "com.dorongold.task-tree" version "2.1.0"
|
id "com.dorongold.task-tree" version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "cpp"
|
id "cpp"
|
||||||
id "google-test-test-suite"
|
id "google-test-test-suite"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
|
|
||||||
id "com.dorongold.task-tree" version "2.1.0"
|
id "com.dorongold.task-tree" version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
maven { url = "https://maven.photonvision.org/releases" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "cpp"
|
id "cpp"
|
||||||
id "google-test-test-suite"
|
id "google-test-test-suite"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
|
|
||||||
id "com.dorongold.task-tree" version "2.1.0"
|
id "com.dorongold.task-tree" version "2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "cpp"
|
id "cpp"
|
||||||
id "google-test-test-suite"
|
id "google-test-test-suite"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
|
|
||||||
id "com.dorongold.task-tree" version "2.1.0"
|
id "com.dorongold.task-tree" version "2.1.0"
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,8 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wpi.maven.useDevelopment = true
|
wpi.maven.useDevelopment = true
|
||||||
wpi.versions.wpilibVersion = "2024.3.1"
|
wpi.versions.wpilibVersion = "2024.3.2"
|
||||||
wpi.versions.wpimathVersion = "2024.3.1"
|
wpi.versions.wpimathVersion = "2024.3.2"
|
||||||
|
|
||||||
apply from: "${rootDir}/../shared/examples_common.gradle"
|
apply from: "${rootDir}/../shared/examples_common.gradle"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
maven { url = "https://maven.photonvision.org/releases" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "edu.wpi.first.GradleRIO" version "2024.3.1"
|
id "edu.wpi.first.GradleRIO" version "2024.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
@@ -11,8 +11,8 @@ apply from: "${rootDir}/../shared/examples_common.gradle"
|
|||||||
def ROBOT_MAIN_CLASS = "frc.robot.Main"
|
def ROBOT_MAIN_CLASS = "frc.robot.Main"
|
||||||
|
|
||||||
wpi.maven.useDevelopment = true
|
wpi.maven.useDevelopment = true
|
||||||
wpi.versions.wpilibVersion = "2024.3.1"
|
wpi.versions.wpilibVersion = "2024.3.2"
|
||||||
wpi.versions.wpimathVersion = "2024.3.1"
|
wpi.versions.wpimathVersion = "2024.3.2"
|
||||||
|
|
||||||
|
|
||||||
// Define my targets (RoboRIO) and artifacts (deployable files)
|
// Define my targets (RoboRIO) and artifacts (deployable files)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ publishing {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url ('https://maven.photonvision.org/repository/' + (isDev ? 'snapshots' : 'internal'))
|
url(photonMavenURL)
|
||||||
credentials {
|
credentials {
|
||||||
username 'ghactions'
|
username 'ghactions'
|
||||||
password System.getenv("ARTIFACTORY_API_KEY")
|
password System.getenv("ARTIFACTORY_API_KEY")
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ model {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url ('https://maven.photonvision.org/repository/' + (isDev ? 'snapshots' : 'internal'))
|
url(photonMavenURL)
|
||||||
credentials {
|
credentials {
|
||||||
username 'ghactions'
|
username 'ghactions'
|
||||||
password System.getenv("ARTIFACTORY_API_KEY")
|
password System.getenv("ARTIFACTORY_API_KEY")
|
||||||
|
|||||||
Reference in New Issue
Block a user