mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e613e75db6 | ||
|
|
eca3cea82d | ||
|
|
cbbfbda59d | ||
|
|
a3e1dda3aa |
289
.github/workflows/build.yml
vendored
289
.github/workflows/build.yml
vendored
@@ -2,123 +2,14 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
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:
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 12
|
||||
@@ -188,179 +79,3 @@ jobs:
|
||||
env:
|
||||
ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }}
|
||||
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
|
||||
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.6/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.6/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 }}
|
||||
|
||||
92
.github/workflows/documentation.yml
vendored
92
.github/workflows/documentation.yml
vendored
@@ -1,92 +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]
|
||||
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
# Download literally every single artifact.
|
||||
- uses: actions/download-artifact@v4
|
||||
|
||||
- run: find .
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: '.'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
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
|
||||
@@ -13,8 +13,9 @@ allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
||||
maven { url = "https://maven.photonvision.org/repository/snapshots/" }
|
||||
maven { url = "https://maven.photonvision.org/releases" }
|
||||
maven { url = "https://maven.photonvision.org/snapshots" }
|
||||
maven { url = "https://jogamp.org/deployment/maven/" }
|
||||
}
|
||||
wpilibRepositories.addAllReleaseRepositories(it)
|
||||
wpilibRepositories.addAllDevelopmentRepositories(it)
|
||||
@@ -50,6 +51,10 @@ ext {
|
||||
println("Building for platform " + jniPlatform + " wpilib: " + wpilibNativeName)
|
||||
println("Using Wpilib: " + wpilibVersion)
|
||||
println("Using OpenCV: " + openCVversion)
|
||||
|
||||
|
||||
photonMavenURL = 'https://maven.photonvision.org/' + (isDev ? 'snapshots' : 'releases');
|
||||
println("Publishing Photonlib to " + photonMavenURL)
|
||||
}
|
||||
|
||||
spotless {
|
||||
|
||||
@@ -11,6 +11,16 @@ const currentPipelineSettings = computed<ActivePipelineSettings>(
|
||||
() => useCameraSettingsStore().currentPipelineSettings
|
||||
);
|
||||
|
||||
// TODO fix pv-range-slider so that store access doesn't need to be deferred
|
||||
const contourArea = computed<[number, number]>({
|
||||
get: () => Object.values(useCameraSettingsStore().currentPipelineSettings.contourArea) as [number, number],
|
||||
set: (v) => (useCameraSettingsStore().currentPipelineSettings.contourArea = v)
|
||||
});
|
||||
const contourRatio = computed<[number, number]>({
|
||||
get: () => Object.values(useCameraSettingsStore().currentPipelineSettings.contourRatio) as [number, number],
|
||||
set: (v) => (useCameraSettingsStore().currentPipelineSettings.contourRatio = v)
|
||||
});
|
||||
|
||||
const interactiveCols = computed(() =>
|
||||
(getCurrentInstance()?.proxy.$vuetify.breakpoint.mdAndDown || false) &&
|
||||
(!useStateStore().sidebarFolded || useCameraSettingsStore().isDriverMode)
|
||||
@@ -32,5 +42,42 @@ const interactiveCols = computed(() =>
|
||||
:step="0.01"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ confidence: value }, false)"
|
||||
/>
|
||||
<pv-range-slider
|
||||
v-model="contourArea"
|
||||
label="Area"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
:step="0.01"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourArea: value }, false)"
|
||||
/>
|
||||
<pv-range-slider
|
||||
v-model="contourRatio"
|
||||
label="Ratio (W/H)"
|
||||
tooltip="Min and max ratio between the width and height of a contour's bounding rectangle"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:slider-cols="interactiveCols"
|
||||
:step="0.01"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourRatio: value }, false)"
|
||||
/>
|
||||
<pv-select
|
||||
v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
|
||||
label="Target Orientation"
|
||||
tooltip="Used to determine how to calculate target landmarks, as well as aspect ratio"
|
||||
:items="['Portrait', 'Landscape']"
|
||||
:select-cols="interactiveCols"
|
||||
@input="
|
||||
(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourTargetOrientation: value }, false)
|
||||
"
|
||||
/>
|
||||
<pv-select
|
||||
v-model="currentPipelineSettings.contourSortMode"
|
||||
label="Target Sort"
|
||||
tooltip="Chooses the sorting mode used to determine the 'best' targets to provide to user code"
|
||||
:select-cols="interactiveCols"
|
||||
:items="['Largest', 'Smallest', 'Highest', 'Lowest', 'Rightmost', 'Leftmost', 'Centermost']"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourSortMode: value }, false)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -47,6 +47,16 @@ public class Contour implements Releasable {
|
||||
this.mat = mat;
|
||||
}
|
||||
|
||||
public Contour(Rect2d box) {
|
||||
// no easy way to convert a Rect2d to Mat, diy it. Order is tl tr br bl
|
||||
this.mat =
|
||||
new MatOfPoint(
|
||||
box.tl(),
|
||||
new Point(box.x + box.width, box.y),
|
||||
box.br(),
|
||||
new Point(box.x, box.y + box.height));
|
||||
}
|
||||
|
||||
public MatOfPoint2f getMat2f() {
|
||||
if (mat2f == null) {
|
||||
mat2f = new MatOfPoint2f(mat.toArray());
|
||||
|
||||
@@ -25,15 +25,15 @@ public enum ContourSortMode {
|
||||
Comparator.comparingDouble(PotentialTarget::getArea)
|
||||
.reversed()), // reversed so that zero index has the largest size
|
||||
Smallest(Largest.getComparator().reversed()),
|
||||
Highest(Comparator.comparingDouble(rect -> rect.getMinAreaRect().center.y)),
|
||||
Highest(Comparator.comparingDouble(tgt -> tgt.getMinAreaRect().center.y)),
|
||||
Lowest(Highest.getComparator().reversed()),
|
||||
Leftmost(Comparator.comparingDouble(target -> target.getMinAreaRect().center.x * -1)),
|
||||
Leftmost(Comparator.comparingDouble(tgt -> tgt.getMinAreaRect().center.x * -1)),
|
||||
Rightmost(Leftmost.getComparator().reversed()),
|
||||
Centermost(
|
||||
Comparator.comparingDouble(
|
||||
rect ->
|
||||
(Math.pow(rect.getMinAreaRect().center.y, 2)
|
||||
+ Math.pow(rect.getMinAreaRect().center.x, 2))));
|
||||
tgt ->
|
||||
(Math.pow(tgt.getMinAreaRect().center.y, 2)
|
||||
+ Math.pow(tgt.getMinAreaRect().center.x, 2))));
|
||||
|
||||
private final Comparator<PotentialTarget> m_comparator;
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.photonvision.vision.pipe.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.photonvision.common.util.numbers.DoubleCouple;
|
||||
import org.photonvision.vision.frame.FrameStaticProperties;
|
||||
import org.photonvision.vision.pipe.CVPipe;
|
||||
|
||||
public class FilterObjectDetectionsPipe
|
||||
extends CVPipe<
|
||||
List<NeuralNetworkPipeResult>,
|
||||
List<NeuralNetworkPipeResult>,
|
||||
FilterObjectDetectionsPipe.FilterContoursParams> {
|
||||
List<NeuralNetworkPipeResult> m_filteredContours = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected List<NeuralNetworkPipeResult> process(List<NeuralNetworkPipeResult> in) {
|
||||
m_filteredContours.clear();
|
||||
for (var contour : in) {
|
||||
filterContour(contour);
|
||||
}
|
||||
|
||||
return m_filteredContours;
|
||||
}
|
||||
|
||||
private void filterContour(NeuralNetworkPipeResult contour) {
|
||||
var boc = contour.box;
|
||||
|
||||
// Area filtering
|
||||
double areaPercentage = boc.area() / params.getFrameStaticProperties().imageArea * 100.0;
|
||||
double minAreaPercentage = params.getArea().getFirst();
|
||||
double maxAreaPercentage = params.getArea().getSecond();
|
||||
if (areaPercentage < minAreaPercentage || areaPercentage > maxAreaPercentage) return;
|
||||
|
||||
// Aspect ratio filtering; much simpler since always axis-aligned
|
||||
double aspectRatio = boc.width / boc.height;
|
||||
if (aspectRatio < params.getRatio().getFirst() || aspectRatio > params.getRatio().getSecond())
|
||||
return;
|
||||
|
||||
m_filteredContours.add(contour);
|
||||
}
|
||||
|
||||
public static class FilterContoursParams {
|
||||
private final DoubleCouple m_area;
|
||||
private final DoubleCouple m_ratio;
|
||||
private final FrameStaticProperties m_frameStaticProperties;
|
||||
public final boolean isLandscape;
|
||||
|
||||
public FilterContoursParams(
|
||||
DoubleCouple area,
|
||||
DoubleCouple ratio,
|
||||
FrameStaticProperties camProperties,
|
||||
boolean isLandscape) {
|
||||
this.m_area = area;
|
||||
this.m_ratio = ratio;
|
||||
this.m_frameStaticProperties = camProperties;
|
||||
this.isLandscape = isLandscape;
|
||||
}
|
||||
|
||||
public DoubleCouple getArea() {
|
||||
return m_area;
|
||||
}
|
||||
|
||||
public DoubleCouple getRatio() {
|
||||
return m_ratio;
|
||||
}
|
||||
|
||||
public FrameStaticProperties getFrameStaticProperties() {
|
||||
return m_frameStaticProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ public class SortContoursPipe
|
||||
if (params.getSortMode() != ContourSortMode.Centermost) {
|
||||
m_sortedContours.sort(params.getSortMode().getComparator());
|
||||
} else {
|
||||
// we need knowledge of camera properties to calculate this distance -- do it ourselves
|
||||
m_sortedContours.sort(Comparator.comparingDouble(this::calcSquareCenterDistance));
|
||||
}
|
||||
}
|
||||
@@ -50,10 +51,10 @@ public class SortContoursPipe
|
||||
m_sortedContours.subList(0, Math.min(in.size(), params.getMaxTargets())));
|
||||
}
|
||||
|
||||
private double calcSquareCenterDistance(PotentialTarget rect) {
|
||||
private double calcSquareCenterDistance(PotentialTarget tgt) {
|
||||
return Math.sqrt(
|
||||
Math.pow(params.getCamProperties().centerX - rect.getMinAreaRect().center.x, 2)
|
||||
+ Math.pow(params.getCamProperties().centerY - rect.getMinAreaRect().center.y, 2));
|
||||
Math.pow(params.getCamProperties().centerX - tgt.getMinAreaRect().center.x, 2)
|
||||
+ Math.pow(params.getCamProperties().centerY - tgt.getMinAreaRect().center.y, 2));
|
||||
}
|
||||
|
||||
public static class SortContoursParams {
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.photonvision.vision.pipeline.result.CVPipelineResult;
|
||||
|
||||
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings>
|
||||
implements Releasable {
|
||||
static final int MAX_MULTI_TARGET_RESULTS = 10;
|
||||
|
||||
protected S settings;
|
||||
protected FrameStaticProperties frameStaticProperties;
|
||||
protected QuirkyCamera cameraQuirks;
|
||||
|
||||
@@ -109,7 +109,7 @@ public class ColoredShapePipeline
|
||||
SortContoursPipe.SortContoursParams sortContoursParams =
|
||||
new SortContoursPipe.SortContoursParams(
|
||||
settings.contourSortMode,
|
||||
settings.outputShowMultipleTargets ? 5 : 1,
|
||||
settings.outputShowMultipleTargets ? MAX_MULTI_TARGET_RESULTS : 1,
|
||||
frameStaticProperties); // TODO don't hardcode?
|
||||
sortContoursPipe.setParams(sortContoursParams);
|
||||
|
||||
|
||||
@@ -17,21 +17,26 @@
|
||||
|
||||
package org.photonvision.vision.pipeline;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.photonvision.vision.frame.Frame;
|
||||
import org.photonvision.vision.frame.FrameThresholdType;
|
||||
import org.photonvision.vision.opencv.DualOffsetValues;
|
||||
import org.photonvision.vision.pipe.CVPipe.CVPipeResult;
|
||||
import org.photonvision.vision.pipe.impl.*;
|
||||
import org.photonvision.vision.pipe.impl.RknnDetectionPipe.RknnDetectionPipeParams;
|
||||
import org.photonvision.vision.pipeline.result.CVPipelineResult;
|
||||
import org.photonvision.vision.target.PotentialTarget;
|
||||
import org.photonvision.vision.target.TargetOrientation;
|
||||
import org.photonvision.vision.target.TrackedTarget;
|
||||
import org.photonvision.vision.target.TrackedTarget.TargetCalculationParameters;
|
||||
|
||||
public class ObjectDetectionPipeline
|
||||
extends CVPipeline<CVPipelineResult, ObjectDetectionPipelineSettings> {
|
||||
private final CalculateFPSPipe calculateFPSPipe = new CalculateFPSPipe();
|
||||
private final RknnDetectionPipe rknnPipe = new RknnDetectionPipe();
|
||||
private final SortContoursPipe sortContoursPipe = new SortContoursPipe();
|
||||
private final Collect2dTargetsPipe collect2dTargetsPipe = new Collect2dTargetsPipe();
|
||||
private final FilterObjectDetectionsPipe filterContoursPipe = new FilterObjectDetectionsPipe();
|
||||
|
||||
private static final FrameThresholdType PROCESSING_TYPE = FrameThresholdType.NONE;
|
||||
|
||||
@@ -52,6 +57,38 @@ public class ObjectDetectionPipeline
|
||||
params.confidence = settings.confidence;
|
||||
params.nms = settings.nms;
|
||||
rknnPipe.setParams(params);
|
||||
|
||||
DualOffsetValues dualOffsetValues =
|
||||
new DualOffsetValues(
|
||||
settings.offsetDualPointA,
|
||||
settings.offsetDualPointAArea,
|
||||
settings.offsetDualPointB,
|
||||
settings.offsetDualPointBArea);
|
||||
|
||||
SortContoursPipe.SortContoursParams sortContoursParams =
|
||||
new SortContoursPipe.SortContoursParams(
|
||||
settings.contourSortMode,
|
||||
settings.outputShowMultipleTargets ? MAX_MULTI_TARGET_RESULTS : 1,
|
||||
frameStaticProperties);
|
||||
sortContoursPipe.setParams(sortContoursParams);
|
||||
|
||||
var filterContoursParams =
|
||||
new FilterObjectDetectionsPipe.FilterContoursParams(
|
||||
settings.contourArea,
|
||||
settings.contourRatio,
|
||||
frameStaticProperties,
|
||||
settings.contourTargetOrientation == TargetOrientation.Landscape);
|
||||
filterContoursPipe.setParams(filterContoursParams);
|
||||
|
||||
Collect2dTargetsPipe.Collect2dTargetsParams collect2dTargetsParams =
|
||||
new Collect2dTargetsPipe.Collect2dTargetsParams(
|
||||
settings.offsetRobotOffsetMode,
|
||||
settings.offsetSinglePoint,
|
||||
dualOffsetValues,
|
||||
settings.contourTargetOffsetPointEdge,
|
||||
settings.contourTargetOrientation,
|
||||
frameStaticProperties);
|
||||
collect2dTargetsPipe.setParams(collect2dTargetsParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,31 +97,35 @@ public class ObjectDetectionPipeline
|
||||
|
||||
// ***************** change based on backend ***********************
|
||||
|
||||
CVPipeResult<List<NeuralNetworkPipeResult>> ret = rknnPipe.run(input_frame.colorImage);
|
||||
sumPipeNanosElapsed += ret.nanosElapsed;
|
||||
CVPipeResult<List<NeuralNetworkPipeResult>> rknnResult = rknnPipe.run(input_frame.colorImage);
|
||||
sumPipeNanosElapsed += rknnResult.nanosElapsed;
|
||||
List<NeuralNetworkPipeResult> targetList;
|
||||
|
||||
targetList = ret.output;
|
||||
var names = rknnPipe.getClassNames();
|
||||
|
||||
input_frame.colorImage.getMat().copyTo(input_frame.processedImage.getMat());
|
||||
|
||||
// ***************** change based on backend ***********************
|
||||
|
||||
List<TrackedTarget> targets = new ArrayList<>();
|
||||
var filterContoursResult = filterContoursPipe.run(rknnResult.output);
|
||||
sumPipeNanosElapsed += filterContoursResult.nanosElapsed;
|
||||
|
||||
for (var t : targetList) {
|
||||
targets.add(
|
||||
new TrackedTarget(
|
||||
t,
|
||||
new TargetCalculationParameters(
|
||||
false, null, null, null, null, frameStaticProperties)));
|
||||
}
|
||||
CVPipeResult<List<PotentialTarget>> sortContoursResult =
|
||||
sortContoursPipe.run(
|
||||
filterContoursResult.output.stream()
|
||||
.map(shape -> new PotentialTarget(shape))
|
||||
.collect(Collectors.toList()));
|
||||
sumPipeNanosElapsed += sortContoursResult.nanosElapsed;
|
||||
|
||||
CVPipeResult<List<TrackedTarget>> collect2dTargetsResult =
|
||||
collect2dTargetsPipe.run(sortContoursResult.output);
|
||||
sumPipeNanosElapsed += collect2dTargetsResult.nanosElapsed;
|
||||
|
||||
var fpsResult = calculateFPSPipe.run(null);
|
||||
var fps = fpsResult.output;
|
||||
|
||||
return new CVPipelineResult(sumPipeNanosElapsed, fps, targets, input_frame, names);
|
||||
return new CVPipelineResult(
|
||||
sumPipeNanosElapsed, fps, collect2dTargetsResult.output, input_frame, names);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,29 +64,6 @@ public class ReflectivePipeline extends CVPipeline<CVPipelineResult, ReflectiveP
|
||||
settings.offsetDualPointB,
|
||||
settings.offsetDualPointBArea);
|
||||
|
||||
// var rotateImageParams = new
|
||||
// RotateImagePipe.RotateImageParams(settings.inputImageRotationMode);
|
||||
// rotateImagePipe.setParams(rotateImageParams);
|
||||
|
||||
// if (cameraQuirks.hasQuirk(CameraQuirk.PiCam) && LibCameraJNI.isSupported()) {
|
||||
// LibCameraJNI.setThresholds(
|
||||
// settings.hsvHue.getFirst() / 180d,
|
||||
// settings.hsvSaturation.getFirst() / 255d,
|
||||
// settings.hsvValue.getFirst() / 255d,
|
||||
// settings.hsvHue.getSecond() / 180d,
|
||||
// settings.hsvSaturation.getSecond() / 255d,
|
||||
// settings.hsvValue.getSecond() / 255d);
|
||||
// // LibCameraJNI.setInvertHue(settings.hueInverted);
|
||||
// LibCameraJNI.setRotation(settings.inputImageRotationMode.value);
|
||||
// // LibCameraJNI.setShouldCopyColor(settings.inputShouldShow);
|
||||
// } else {
|
||||
// var hsvParams =
|
||||
// new HSVPipe.HSVParams(
|
||||
// settings.hsvHue, settings.hsvSaturation, settings.hsvValue,
|
||||
// settings.hueInverted);
|
||||
// hsvPipe.setParams(hsvParams);
|
||||
// }
|
||||
|
||||
var findContoursParams = new FindContoursPipe.FindContoursParams();
|
||||
findContoursPipe.setParams(findContoursParams);
|
||||
|
||||
@@ -113,7 +90,7 @@ public class ReflectivePipeline extends CVPipeline<CVPipelineResult, ReflectiveP
|
||||
var sortContoursParams =
|
||||
new SortContoursPipe.SortContoursParams(
|
||||
settings.contourSortMode,
|
||||
settings.outputShowMultipleTargets ? 8 : 1, // TODO don't hardcode?
|
||||
settings.outputShowMultipleTargets ? MAX_MULTI_TARGET_RESULTS : 1,
|
||||
frameStaticProperties);
|
||||
sortContoursPipe.setParams(sortContoursParams);
|
||||
|
||||
|
||||
@@ -98,8 +98,7 @@ public class VisionRunner {
|
||||
var pipelineResult = pipeline.run(frame, cameraQuirks);
|
||||
pipelineResultConsumer.accept(pipelineResult);
|
||||
} catch (Exception ex) {
|
||||
logger.error("Exception on loop " + loopCount);
|
||||
ex.printStackTrace();
|
||||
logger.error("Exception on loop " + loopCount, ex);
|
||||
}
|
||||
|
||||
loopCount++;
|
||||
|
||||
@@ -21,7 +21,9 @@ import java.util.List;
|
||||
import org.opencv.core.RotatedRect;
|
||||
import org.photonvision.vision.opencv.CVShape;
|
||||
import org.photonvision.vision.opencv.Contour;
|
||||
import org.photonvision.vision.opencv.ContourShape;
|
||||
import org.photonvision.vision.opencv.Releasable;
|
||||
import org.photonvision.vision.pipe.impl.NeuralNetworkPipeResult;
|
||||
|
||||
public class PotentialTarget implements Releasable {
|
||||
|
||||
@@ -29,6 +31,10 @@ public class PotentialTarget implements Releasable {
|
||||
public final List<Contour> m_subContours;
|
||||
public final CVShape shape;
|
||||
|
||||
// additional metadata about object detections we need to keep around
|
||||
public final double confidence;
|
||||
public final int clsId;
|
||||
|
||||
public PotentialTarget(Contour inputContour) {
|
||||
this(inputContour, List.of());
|
||||
}
|
||||
@@ -41,12 +47,26 @@ public class PotentialTarget implements Releasable {
|
||||
m_mainContour = inputContour;
|
||||
m_subContours = new ArrayList<>(subContours);
|
||||
this.shape = shape;
|
||||
this.clsId = -1;
|
||||
this.confidence = -1;
|
||||
}
|
||||
|
||||
public PotentialTarget(Contour inputContour, CVShape shape) {
|
||||
this(inputContour, List.of(), shape);
|
||||
}
|
||||
|
||||
public PotentialTarget(NeuralNetworkPipeResult det) {
|
||||
this.shape = new CVShape(new Contour(det.box), ContourShape.Quadrilateral);
|
||||
this.m_mainContour = this.shape.getContour();
|
||||
m_subContours = List.of();
|
||||
this.clsId = det.classIdx;
|
||||
this.confidence = det.confidence;
|
||||
}
|
||||
|
||||
public PotentialTarget(CVShape cvShape) {
|
||||
this(cvShape.getContour(), cvShape);
|
||||
}
|
||||
|
||||
public RotatedRect getMinAreaRect() {
|
||||
return m_mainContour.getMinAreaRect();
|
||||
}
|
||||
@@ -61,7 +81,7 @@ public class PotentialTarget implements Releasable {
|
||||
for (var sc : m_subContours) {
|
||||
sc.release();
|
||||
}
|
||||
m_subContours.clear();
|
||||
if (!m_subContours.isEmpty()) m_subContours.clear();
|
||||
if (shape != null) shape.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.Rect2d;
|
||||
import org.opencv.core.RotatedRect;
|
||||
import org.photonvision.common.util.SerializationUtils;
|
||||
import org.photonvision.common.util.math.MathUtils;
|
||||
@@ -39,7 +38,6 @@ import org.photonvision.vision.opencv.CVShape;
|
||||
import org.photonvision.vision.opencv.Contour;
|
||||
import org.photonvision.vision.opencv.DualOffsetValues;
|
||||
import org.photonvision.vision.opencv.Releasable;
|
||||
import org.photonvision.vision.pipe.impl.NeuralNetworkPipeResult;
|
||||
|
||||
public class TrackedTarget implements Releasable {
|
||||
public final Contour m_mainContour;
|
||||
@@ -76,6 +74,9 @@ public class TrackedTarget implements Releasable {
|
||||
this.m_subContours = origTarget.m_subContours;
|
||||
this.m_shape = shape;
|
||||
calculateValues(params);
|
||||
|
||||
this.m_classId = origTarget.clsId;
|
||||
this.m_confidence = origTarget.confidence;
|
||||
}
|
||||
|
||||
public TrackedTarget(
|
||||
@@ -159,47 +160,6 @@ public class TrackedTarget implements Releasable {
|
||||
m_robotOffsetPoint = new Point();
|
||||
}
|
||||
|
||||
public TrackedTarget(
|
||||
Rect2d box, int class_id, double confidence, TargetCalculationParameters params) {
|
||||
m_targetOffsetPoint = new Point(box.x + box.width / 2.0, box.y + box.height / 2.0);
|
||||
m_robotOffsetPoint = new Point();
|
||||
|
||||
var yawPitch =
|
||||
TargetCalculations.calculateYawPitch(
|
||||
params.cameraCenterPoint.x,
|
||||
box.x + box.width / 2.0,
|
||||
params.horizontalFocalLength,
|
||||
params.cameraCenterPoint.y,
|
||||
box.y + box.height / 2.0,
|
||||
params.verticalFocalLength);
|
||||
m_yaw = yawPitch.getFirst();
|
||||
m_pitch = yawPitch.getSecond();
|
||||
|
||||
Point[] cornerPoints =
|
||||
new Point[] {
|
||||
// Box.x/y is the top-left corner, not the center
|
||||
new Point(box.x, box.y), // tl
|
||||
new Point(box.x + box.width, box.y), // tr
|
||||
new Point(box.x + box.width, box.y + box.height), // br
|
||||
new Point(box.x, box.y + box.height), // bl
|
||||
};
|
||||
|
||||
m_targetCorners = List.of(cornerPoints);
|
||||
MatOfPoint contourMat = new MatOfPoint(cornerPoints);
|
||||
m_approximateBoundingPolygon = new MatOfPoint2f(cornerPoints);
|
||||
|
||||
m_mainContour = new Contour(contourMat);
|
||||
m_area = m_mainContour.getArea() / params.imageArea * 100;
|
||||
|
||||
m_classId = class_id;
|
||||
m_confidence = confidence;
|
||||
}
|
||||
|
||||
public TrackedTarget(
|
||||
NeuralNetworkPipeResult t, TargetCalculationParameters targetCalculationParameters) {
|
||||
this(t.box, t.classIdx, t.confidence, targetCalculationParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the confidence of the detection ranging from 0 - 1.
|
||||
*/
|
||||
|
||||
@@ -435,7 +435,7 @@ class PhotonCameraSim {
|
||||
double minTargetAreaPercent;
|
||||
|
||||
frc::AprilTagFieldLayout tagLayout{
|
||||
frc::LoadAprilTagLayoutField(frc::AprilTagField::k2023ChargedUp)};
|
||||
frc::LoadAprilTagLayoutField(frc::AprilTagField::k2024Crescendo)};
|
||||
|
||||
cs::CvSource videoSimRaw;
|
||||
cv::Mat videoSimFrameRaw{};
|
||||
|
||||
@@ -138,7 +138,6 @@ public class Server {
|
||||
app.post("/api/calibration/importFromData", RequestHandler::onDataCalibrationImportRequest);
|
||||
|
||||
app.start(port);
|
||||
System.out.println("hi");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
||||
maven { url = "https://maven.photonvision.org/releases" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,48 +35,48 @@
|
||||
|
||||
namespace constants {
|
||||
namespace Vision {
|
||||
static constexpr std::string_view kCameraName{"YOUR CAMERA NAME"};
|
||||
static const frc::Transform3d kRobotToCam{
|
||||
inline constexpr std::string_view kCameraName{"YOUR CAMERA NAME"};
|
||||
inline const frc::Transform3d kRobotToCam{
|
||||
frc::Translation3d{0.5_m, 0.0_m, 0.5_m},
|
||||
frc::Rotation3d{0_rad, 0_rad, 0_rad}};
|
||||
static const frc::AprilTagFieldLayout kTagLayout{
|
||||
frc::LoadAprilTagLayoutField(frc::AprilTagField::k2023ChargedUp)};
|
||||
inline const frc::AprilTagFieldLayout kTagLayout{
|
||||
frc::LoadAprilTagLayoutField(frc::AprilTagField::k2024Crescendo)};
|
||||
|
||||
static const Eigen::Matrix<double, 3, 1> kSingleTagStdDevs{4, 4, 8};
|
||||
static const Eigen::Matrix<double, 3, 1> kMultiTagStdDevs{0.5, 0.5, 1};
|
||||
inline const Eigen::Matrix<double, 3, 1> kSingleTagStdDevs{4, 4, 8};
|
||||
inline const Eigen::Matrix<double, 3, 1> kMultiTagStdDevs{0.5, 0.5, 1};
|
||||
} // namespace Vision
|
||||
namespace Swerve {
|
||||
|
||||
static constexpr units::meter_t kTrackWidth{18.5_in};
|
||||
static constexpr units::meter_t kTrackLength{18.5_in};
|
||||
static constexpr units::meter_t kRobotWidth{25_in + 3.25_in * 2};
|
||||
static constexpr units::meter_t kRobotLength{25_in + 3.25_in * 2};
|
||||
static constexpr units::meters_per_second_t kMaxLinearSpeed{15.5_fps};
|
||||
static constexpr units::radians_per_second_t kMaxAngularSpeed{720_deg_per_s};
|
||||
static constexpr units::meter_t kWheelDiameter{4_in};
|
||||
static constexpr units::meter_t kWheelCircumference{kWheelDiameter *
|
||||
inline constexpr units::meter_t kTrackWidth{18.5_in};
|
||||
inline constexpr units::meter_t kTrackLength{18.5_in};
|
||||
inline constexpr units::meter_t kRobotWidth{25_in + 3.25_in * 2};
|
||||
inline constexpr units::meter_t kRobotLength{25_in + 3.25_in * 2};
|
||||
inline constexpr units::meters_per_second_t kMaxLinearSpeed{15.5_fps};
|
||||
inline constexpr units::radians_per_second_t kMaxAngularSpeed{720_deg_per_s};
|
||||
inline constexpr units::meter_t kWheelDiameter{4_in};
|
||||
inline constexpr units::meter_t kWheelCircumference{kWheelDiameter *
|
||||
std::numbers::pi};
|
||||
|
||||
static constexpr double kDriveGearRatio = 6.75;
|
||||
static constexpr double kSteerGearRatio = 12.8;
|
||||
inline constexpr double kDriveGearRatio = 6.75;
|
||||
inline constexpr double kSteerGearRatio = 12.8;
|
||||
|
||||
static constexpr units::meter_t kDriveDistPerPulse =
|
||||
inline constexpr units::meter_t kDriveDistPerPulse =
|
||||
kWheelCircumference / 1024.0 / kDriveGearRatio;
|
||||
static constexpr units::radian_t kSteerRadPerPulse =
|
||||
inline constexpr units::radian_t kSteerRadPerPulse =
|
||||
units::radian_t{2 * std::numbers::pi} / 1024.0;
|
||||
|
||||
static constexpr double kDriveKP = 1.0;
|
||||
static constexpr double kDriveKI = 0.0;
|
||||
static constexpr double kDriveKD = 0.0;
|
||||
inline constexpr double kDriveKP = 1.0;
|
||||
inline constexpr double kDriveKI = 0.0;
|
||||
inline constexpr double kDriveKD = 0.0;
|
||||
|
||||
static constexpr double kSteerKP = 20.0;
|
||||
static constexpr double kSteerKI = 0.0;
|
||||
static constexpr double kSteerKD = 0.25;
|
||||
inline constexpr double kSteerKP = 20.0;
|
||||
inline constexpr double kSteerKI = 0.0;
|
||||
inline constexpr double kSteerKD = 0.25;
|
||||
|
||||
static const frc::SimpleMotorFeedforward<units::meters> kDriveFF{
|
||||
inline const frc::SimpleMotorFeedforward<units::meters> kDriveFF{
|
||||
0.25_V, 2.5_V / 1_mps, 0.3_V / 1_mps_sq};
|
||||
|
||||
static const frc::SimpleMotorFeedforward<units::radians> kSteerFF{
|
||||
inline const frc::SimpleMotorFeedforward<units::radians> kSteerFF{
|
||||
0.5_V, 0.25_V / 1_rad_per_s, 0.01_V / 1_rad_per_s_sq};
|
||||
|
||||
struct ModuleConstants {
|
||||
@@ -106,13 +106,13 @@ struct ModuleConstants {
|
||||
centerOffset(frc::Translation2d{xOffset, yOffset}) {}
|
||||
};
|
||||
|
||||
static const ModuleConstants FL_CONSTANTS{
|
||||
inline const ModuleConstants FL_CONSTANTS{
|
||||
1, 0, 0, 1, 1, 2, 3, 0, kTrackLength / 2, kTrackWidth / 2};
|
||||
static const ModuleConstants FR_CONSTANTS{
|
||||
inline const ModuleConstants FR_CONSTANTS{
|
||||
2, 2, 4, 5, 3, 6, 7, 0, kTrackLength / 2, -kTrackWidth / 2};
|
||||
static const ModuleConstants BL_CONSTANTS{
|
||||
inline const ModuleConstants BL_CONSTANTS{
|
||||
3, 4, 8, 9, 5, 10, 11, 0, -kTrackLength / 2, kTrackWidth / 2};
|
||||
static const ModuleConstants BR_CONSTANTS{
|
||||
inline const ModuleConstants BR_CONSTANTS{
|
||||
4, 6, 12, 13, 7, 14, 15, 0, -kTrackLength / 2, -kTrackWidth / 2};
|
||||
} // namespace Swerve
|
||||
} // namespace constants
|
||||
|
||||
@@ -61,7 +61,7 @@ class Vision {
|
||||
cameraSim = std::make_shared<photon::PhotonCameraSim>(camera.get(),
|
||||
*cameraProp.get());
|
||||
|
||||
visionSim->AddCamera(cameraSim.get(), robotToCam);
|
||||
visionSim->AddCamera(cameraSim.get(), constants::Vision::kRobotToCam);
|
||||
cameraSim->EnableDrawWireframe(true);
|
||||
}
|
||||
}
|
||||
@@ -138,12 +138,10 @@ class Vision {
|
||||
frc::Field2d& GetSimDebugField() { return visionSim->GetDebugField(); }
|
||||
|
||||
private:
|
||||
frc::Transform3d robotToCam{frc::Translation3d{0.5_m, 0.5_m, 0.5_m},
|
||||
frc::Rotation3d{}};
|
||||
photon::PhotonPoseEstimator photonEstimator{
|
||||
LoadAprilTagLayoutField(frc::AprilTagField::k2023ChargedUp),
|
||||
constants::Vision::kTagLayout,
|
||||
photon::PoseStrategy::MULTI_TAG_PNP_ON_COPROCESSOR,
|
||||
photon::PhotonCamera{"photonvision"}, robotToCam};
|
||||
photon::PhotonCamera{"photonvision"}, constants::Vision::kRobotToCam};
|
||||
std::shared_ptr<photon::PhotonCamera> camera{photonEstimator.GetCamera()};
|
||||
std::unique_ptr<photon::VisionSystemSim> visionSim;
|
||||
std::unique_ptr<photon::SimCameraProperties> cameraProp;
|
||||
|
||||
@@ -8,7 +8,7 @@ allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven { url = "https://maven.photonvision.org/repository/internal/" }
|
||||
maven { url = "https://maven.photonvision.org/releases" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ publishing {
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url ('https://maven.photonvision.org/repository/' + (isDev ? 'snapshots' : 'internal'))
|
||||
url(photonMavenURL)
|
||||
credentials {
|
||||
username 'ghactions'
|
||||
password System.getenv("ARTIFACTORY_API_KEY")
|
||||
|
||||
@@ -70,7 +70,7 @@ model {
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url ('https://maven.photonvision.org/repository/' + (isDev ? 'snapshots' : 'internal'))
|
||||
url(photonMavenURL)
|
||||
credentials {
|
||||
username 'ghactions'
|
||||
password System.getenv("ARTIFACTORY_API_KEY")
|
||||
|
||||
Reference in New Issue
Block a user