From 72c04b3eb3969c14e7418e13528184b0e026b315 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 12 Jan 2023 19:05:22 -0500 Subject: [PATCH 1/4] Create C++ Apriltag example --- photon-server/lib/libphotonlibcamera.so | Bin 145784 -> 141664 bytes photon-server/networktables.json | 1 + .../aimandrange/build.gradle | 2 +- .../aimattarget/build.gradle | 2 +- .../apriltagExample/.gitignore | 1 + .../.wpilib/wpilib_preferences.json | 6 + .../apriltagExample/WPILib-License.md | 24 ++ .../apriltagExample/build.gradle | 116 +++++++++ .../apriltagExample/gradlew | 240 ++++++++++++++++++ .../apriltagExample/gradlew.bat | 91 +++++++ .../apriltagExample/networktables.json | 1 + .../apriltagExample/settings.gradle | 30 +++ .../apriltagExample/simgui-ds.json | 102 ++++++++ .../apriltagExample/simgui-window.json | 74 ++++++ .../apriltagExample/simgui.json | 37 +++ .../src/main/cpp/Drivetrain.cpp | 92 +++++++ .../apriltagExample/src/main/cpp/Robot.cpp | 60 +++++ .../src/main/include/Drivetrain.h | 140 ++++++++++ .../src/main/include/PhotonCameraWrapper.h | 45 ++++ .../apriltagExample/src/main/include/Robot.h | 50 ++++ .../apriltagExample/src/test/cpp/main.cpp | 34 +++ photonlib-cpp-examples/examples.txt | 1 + .../getinrange/build.gradle | 2 +- .../aimandrange/build.gradle | 2 +- .../aimattarget/build.gradle | 2 +- .../apriltagExample/build.gradle | 2 +- .../getinrange/build.gradle | 2 +- .../simaimandrange/build.gradle | 2 +- .../simposeest/build.gradle | 2 +- 29 files changed, 1154 insertions(+), 9 deletions(-) create mode 100644 photon-server/networktables.json create mode 100644 photonlib-cpp-examples/apriltagExample/.gitignore create mode 100644 photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json create mode 100644 photonlib-cpp-examples/apriltagExample/WPILib-License.md create mode 100644 photonlib-cpp-examples/apriltagExample/build.gradle create mode 100755 photonlib-cpp-examples/apriltagExample/gradlew create mode 100644 photonlib-cpp-examples/apriltagExample/gradlew.bat create mode 100644 photonlib-cpp-examples/apriltagExample/networktables.json create mode 100644 photonlib-cpp-examples/apriltagExample/settings.gradle create mode 100644 photonlib-cpp-examples/apriltagExample/simgui-ds.json create mode 100644 photonlib-cpp-examples/apriltagExample/simgui-window.json create mode 100644 photonlib-cpp-examples/apriltagExample/simgui.json create mode 100644 photonlib-cpp-examples/apriltagExample/src/main/cpp/Drivetrain.cpp create mode 100644 photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp create mode 100644 photonlib-cpp-examples/apriltagExample/src/main/include/Drivetrain.h create mode 100644 photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h create mode 100644 photonlib-cpp-examples/apriltagExample/src/main/include/Robot.h create mode 100644 photonlib-cpp-examples/apriltagExample/src/test/cpp/main.cpp diff --git a/photon-server/lib/libphotonlibcamera.so b/photon-server/lib/libphotonlibcamera.so index f11ed7338aa36b6de39128cbd96cbdc37587015e..90bb006943b0cde91e730c3bd0893ce9d91e85d5 100644 GIT binary patch delta 43813 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%0D-G##bNFvzu@sn8FlqF?oy6iO~Xo@U(0O$%VE4> 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 JqpnJ=_%GTP%*6lz delta 43741 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 diff --git a/photon-server/networktables.json b/photon-server/networktables.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/photon-server/networktables.json @@ -0,0 +1 @@ +[] diff --git a/photonlib-cpp-examples/aimandrange/build.gradle b/photonlib-cpp-examples/aimandrange/build.gradle index b300429674..10e9a0f769 100644 --- a/photonlib-cpp-examples/aimandrange/build.gradle +++ b/photonlib-cpp-examples/aimandrange/build.gradle @@ -1,7 +1,7 @@ plugins { id "cpp" id "google-test-test-suite" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" id "com.dorongold.task-tree" version "2.1.0" } diff --git a/photonlib-cpp-examples/aimattarget/build.gradle b/photonlib-cpp-examples/aimattarget/build.gradle index b300429674..10e9a0f769 100644 --- a/photonlib-cpp-examples/aimattarget/build.gradle +++ b/photonlib-cpp-examples/aimattarget/build.gradle @@ -1,7 +1,7 @@ plugins { id "cpp" id "google-test-test-suite" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" id "com.dorongold.task-tree" version "2.1.0" } diff --git a/photonlib-cpp-examples/apriltagExample/.gitignore b/photonlib-cpp-examples/apriltagExample/.gitignore new file mode 100644 index 0000000000..34878ab18c --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/.gitignore @@ -0,0 +1 @@ +vendordeps diff --git a/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json b/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json new file mode 100644 index 0000000000..cf67d2d09f --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json @@ -0,0 +1,6 @@ +{ + "enableCppIntellisense": true, + "currentLanguage": "cpp", + "projectYear": "2023", + "teamNumber": 5 +} diff --git a/photonlib-cpp-examples/apriltagExample/WPILib-License.md b/photonlib-cpp-examples/apriltagExample/WPILib-License.md new file mode 100644 index 0000000000..ba35a02c5c --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/WPILib-License.md @@ -0,0 +1,24 @@ +Copyright (c) 2009-2021 FIRST and other WPILib contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of FIRST, WPILib, nor the names of other WPILib + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/photonlib-cpp-examples/apriltagExample/build.gradle b/photonlib-cpp-examples/apriltagExample/build.gradle new file mode 100644 index 0000000000..10e9a0f769 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/build.gradle @@ -0,0 +1,116 @@ +plugins { + id "cpp" + id "google-test-test-suite" + id "edu.wpi.first.GradleRIO" version "2023.3.2" + + id "com.dorongold.task-tree" version "2.1.0" +} + +repositories { + mavenLocal() + jcenter() +} + +apply from: "${rootDir}/../shared/examples_common.gradle" + +// Define my targets (RoboRIO) and artifacts (deployable files) +// This is added by GradleRIO's backing project DeployUtils. +deploy { + targets { + roborio(getTargetTypeClass('RoboRIO')) { + // Team number is loaded either from the .wpilib/wpilib_preferences.json + // or from command line. If not found an exception will be thrown. + // You can use getTeamOrDefault(team) instead of getTeamNumber if you + // want to store a team number in this file. + team = project.frc.getTeamOrDefault(5940) + debug = project.frc.getDebugOrDefault(false) + + artifacts { + // First part is artifact name, 2nd is artifact type + // getTargetTypeClass is a shortcut to get the class type using a string + + frcCpp(getArtifactTypeClass('FRCNativeArtifact')) { + } + + // Static files artifact + frcStaticFileDeploy(getArtifactTypeClass('FileTreeArtifact')) { + files = project.fileTree('src/main/deploy') + directory = '/home/lvuser/deploy' + } + } + } + } +} + +def deployArtifact = deploy.targets.roborio.artifacts.frcCpp + +// Set this to true to enable desktop support. +def includeDesktopSupport = true + +// Set to true to run simulation in debug mode +wpi.cpp.debugSimulation = false + +// Default enable simgui +wpi.sim.addGui().defaultEnabled = true +// Enable DS but not by default +wpi.sim.addDriverstation() + +model { + components { + frcUserProgram(NativeExecutableSpec) { + // We don't need to build for roborio -- if we do, we need to install + // a roborio toolchain every time we build in CI + // Ideally, we'd be able to set the roborio toolchain as optional, but + // I can't figure out how to set that environment variable from build.gradle + // (see https://github.com/wpilibsuite/native-utils/blob/2917c69fb5094e36d499c465f047dab81c68446c/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/ToolchainGraphBuildService.java#L71) + // for now, commented out + + // targetPlatform wpi.platforms.roborio + + if (includeDesktopSupport) { + targetPlatform wpi.platforms.desktop + } + + sources.cpp { + source { + srcDir 'src/main/cpp' + include '**/*.cpp', '**/*.cc' + } + exportedHeaders { + srcDir 'src/main/include' + } + } + + // Set deploy task to deploy this component + deployArtifact.component = it + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + // Enable simulation for this component + wpi.sim.enable(it) + // Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + } + } + testSuites { + frcUserProgramTest(GoogleTestTestSuiteSpec) { + testing $.components.frcUserProgram + + sources.cpp { + source { + srcDir 'src/test/cpp' + include '**/*.cpp' + } + } + + // Enable run tasks for this component + wpi.cpp.enableExternalTasks(it) + + wpi.cpp.vendor.cpp(it) + wpi.cpp.deps.wpilib(it) + wpi.cpp.deps.googleTest(it) + } + } +} diff --git a/photonlib-cpp-examples/apriltagExample/gradlew b/photonlib-cpp-examples/apriltagExample/gradlew new file mode 100755 index 0000000000..a69d9cb6c2 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/photonlib-cpp-examples/apriltagExample/gradlew.bat b/photonlib-cpp-examples/apriltagExample/gradlew.bat new file mode 100644 index 0000000000..53a6b238d4 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/photonlib-cpp-examples/apriltagExample/networktables.json b/photonlib-cpp-examples/apriltagExample/networktables.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/networktables.json @@ -0,0 +1 @@ +[] diff --git a/photonlib-cpp-examples/apriltagExample/settings.gradle b/photonlib-cpp-examples/apriltagExample/settings.gradle new file mode 100644 index 0000000000..adeb0f45c4 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/settings.gradle @@ -0,0 +1,30 @@ +import org.gradle.internal.os.OperatingSystem + +rootProject.name = 'aimattarget' + +pluginManagement { + repositories { + mavenLocal() + jcenter() + gradlePluginPortal() + String frcYear = '2023' + File frcHome + if (OperatingSystem.current().isWindows()) { + String publicFolder = System.getenv('PUBLIC') + if (publicFolder == null) { + publicFolder = "C:\\Users\\Public" + } + def homeRoot = new File(publicFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } else { + def userFolder = System.getProperty("user.home") + def homeRoot = new File(userFolder, "wpilib") + frcHome = new File(homeRoot, frcYear) + } + def frcHomeMaven = new File(frcHome, 'maven') + maven { + name 'frcHome' + url frcHomeMaven + } + } +} diff --git a/photonlib-cpp-examples/apriltagExample/simgui-ds.json b/photonlib-cpp-examples/apriltagExample/simgui-ds.json new file mode 100644 index 0000000000..7b51005024 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/simgui-ds.json @@ -0,0 +1,102 @@ +{ + "Keyboard 0 Settings": { + "window": { + "visible": true + } + }, + "keyboardJoysticks": [ + { + "axisConfig": [ + {}, + { + "decKey": 87, + "incKey": 83 + }, + { + "decayRate": 0.0, + "keyRate": 0.009999999776482582 + }, + {}, + { + "decKey": 65, + "incKey": 68 + } + ], + "axisCount": 6, + "buttonCount": 4, + "buttonKeys": [ + 90, + 88, + 67, + 86 + ], + "povConfig": [ + { + "key0": 328, + "key135": 323, + "key180": 322, + "key225": 321, + "key270": 324, + "key315": 327, + "key45": 329, + "key90": 326 + } + ], + "povCount": 1 + }, + { + "axisConfig": [ + { + "decKey": 74, + "incKey": 76 + }, + { + "decKey": 73, + "incKey": 75 + } + ], + "axisCount": 2, + "buttonCount": 4, + "buttonKeys": [ + 77, + 44, + 46, + 47 + ], + "povCount": 0 + }, + { + "axisConfig": [ + { + "decKey": 263, + "incKey": 262 + }, + { + "decKey": 265, + "incKey": 264 + } + ], + "axisCount": 2, + "buttonCount": 6, + "buttonKeys": [ + 260, + 268, + 266, + 261, + 269, + 267 + ], + "povCount": 0 + }, + { + "axisCount": 0, + "buttonCount": 0, + "povCount": 0 + } + ], + "robotJoysticks": [ + { + "guid": "Keyboard0" + } + ] +} diff --git a/photonlib-cpp-examples/apriltagExample/simgui-window.json b/photonlib-cpp-examples/apriltagExample/simgui-window.json new file mode 100644 index 0000000000..bc6ee74a73 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/simgui-window.json @@ -0,0 +1,74 @@ +{ + "Docking": { + "Data": [] + }, + "MainWindow": { + "GLOBAL": { + "fps": "120", + "height": "880", + "maximized": "0", + "style": "0", + "userScale": "2", + "width": "1652", + "xpos": "268", + "ypos": "82" + } + }, + "Window": { + "###/SmartDashboard/Field": { + "Collapsed": "0", + "Pos": "514,2", + "Size": "517,341" + }, + "###FMS": { + "Collapsed": "0", + "Pos": "36,663", + "Size": "283,146" + }, + "###Joysticks": { + "Collapsed": "0", + "Pos": "373,500", + "Size": "796,206" + }, + "###Keyboard 0 Settings": { + "Collapsed": "0", + "Pos": "149,98", + "Size": "300,560" + }, + "###NetworkTables": { + "Collapsed": "0", + "Pos": "663,464", + "Size": "750,365" + }, + "###NetworkTables Info": { + "Collapsed": "0", + "Pos": "520,330", + "Size": "750,145" + }, + "###Other Devices": { + "Collapsed": "0", + "Pos": "1025,20", + "Size": "250,695" + }, + "###System Joysticks": { + "Collapsed": "0", + "Pos": "5,350", + "Size": "192,218" + }, + "###Timing": { + "Collapsed": "0", + "Pos": "5,150", + "Size": "135,127" + }, + "Debug##Default": { + "Collapsed": "0", + "Pos": "60,60", + "Size": "400,400" + }, + "Robot State": { + "Collapsed": "0", + "Pos": "5,20", + "Size": "92,99" + } + } +} diff --git a/photonlib-cpp-examples/apriltagExample/simgui.json b/photonlib-cpp-examples/apriltagExample/simgui.json new file mode 100644 index 0000000000..e0d54bca73 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/simgui.json @@ -0,0 +1,37 @@ +{ + "NTProvider": { + "types": { + "/FMSInfo": "FMSInfo", + "/SmartDashboard/Field": "Field2d" + }, + "windows": { + "/SmartDashboard/Field": { + "window": { + "visible": true + } + } + } + }, + "NetworkTables": { + "transitory": { + "SmartDashboard": { + "open": true + }, + "photonvision": { + "open": true, + "photonvision": { + "open": true + } + } + } + }, + "NetworkTables Info": { + "Clients": { + "open": true + }, + "Server": { + "open": true + }, + "visible": true + } +} diff --git a/photonlib-cpp-examples/apriltagExample/src/main/cpp/Drivetrain.cpp b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Drivetrain.cpp new file mode 100644 index 0000000000..ad778e2544 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Drivetrain.cpp @@ -0,0 +1,92 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "Drivetrain.h" + +#include +#include + +void Drivetrain::SetSpeeds(const frc::DifferentialDriveWheelSpeeds& speeds) { + auto leftFeedforward = m_feedforward.Calculate(speeds.left); + auto rightFeedforward = m_feedforward.Calculate(speeds.right); + double leftOutput = m_leftPIDController.Calculate(m_leftEncoder.GetRate(), + speeds.left.value()); + double rightOutput = m_rightPIDController.Calculate(m_rightEncoder.GetRate(), + speeds.right.value()); + + m_leftGroup.SetVoltage(units::volt_t{leftOutput} + leftFeedforward); + m_rightGroup.SetVoltage(units::volt_t{rightOutput} + rightFeedforward); +} + +void Drivetrain::Drive(units::meters_per_second_t xSpeed, + units::radians_per_second_t rot) { + SetSpeeds(m_kinematics.ToWheelSpeeds({xSpeed, 0_mps, rot})); +} + +void Drivetrain::UpdateOdometry() { + m_poseEstimator.Update(m_gyro.GetRotation2d(), + units::meter_t{m_leftEncoder.GetDistance()}, + units::meter_t{m_rightEncoder.GetDistance()}); +} + +void Drivetrain::ResetOdometry(const frc::Pose2d& pose) { + m_leftEncoder.Reset(); + m_rightEncoder.Reset(); + m_drivetrainSimulator.SetPose(pose); + m_poseEstimator.ResetPosition( + m_gyro.GetRotation2d(), units::meter_t{m_leftEncoder.GetDistance()}, + units::meter_t{m_rightEncoder.GetDistance()}, pose); +} + +void Drivetrain::SimulationPeriodic() { + // To update our simulation, we set motor voltage inputs, update the + // simulation, and write the simulated positions and velocities to our + // simulated encoder and gyro. We negate the right side so that positive + // voltages make the right side move forward. + + m_drivetrainSimulator.SetInputs(units::volt_t{m_leftGroup.Get()} * + frc::RobotController::GetInputVoltage(), + units::volt_t{m_rightGroup.Get()} * + frc::RobotController::GetInputVoltage()); + m_drivetrainSimulator.Update(20_ms); + + m_leftEncoderSim.SetDistance(m_drivetrainSimulator.GetLeftPosition().value()); + m_leftEncoderSim.SetRate(m_drivetrainSimulator.GetLeftVelocity().value()); + m_rightEncoderSim.SetDistance( + m_drivetrainSimulator.GetRightPosition().value()); + m_rightEncoderSim.SetRate(m_drivetrainSimulator.GetRightVelocity().value()); + m_gyroSim.SetAngle(-m_drivetrainSimulator.GetHeading().Degrees().value()); +} + +void Drivetrain::Periodic() { + UpdateOdometry(); + + auto result = m_pcw.Update(m_poseEstimator.GetEstimatedPosition()); + if (result) { + m_poseEstimator.AddVisionMeasurement( + result.value().estimatedPose.ToPose2d(), result.value().timestamp); + } + + m_fieldSim.SetRobotPose(m_poseEstimator.GetEstimatedPosition()); +} diff --git a/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp new file mode 100644 index 0000000000..47e4b8bdb9 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp @@ -0,0 +1,60 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "Robot.h" + +#include +#include + +void Robot::RobotInit() { + if constexpr (frc::RobotBase::IsSimulation()) { + auto inst = nt::NetworkTableInstance::GetDefault(); + inst.StopServer(); + // Change the IP address in the below function to the IP address you use to + // connect to the PhotonVision UI. + inst.SetServer("localhost"); + inst.StartClient4("Robot Simulation"); + } +} + +void Robot::TeleopPeriodic() { + // Get the x speed. We are inverting this because Xbox controllers return + // negative values when we push forward. + const auto xSpeed = -m_controller.GetLeftY() * Drivetrain::kMaxSpeed; + + // Get the rate of angular rotation. We are inverting this because we want a + // positive value when we pull to the left (remember, CCW is positive in + // mathematics). Xbox controllers return positive values when you pull to + // the right by default. + auto rot = -m_controller.GetRightX() * Drivetrain::kMaxAngularSpeed; + + m_drive.Drive(xSpeed, rot); +} + +void Robot::RobotPeriodic() { m_drive.Periodic(); } +void Robot::SimulationPeriodic() { m_drive.SimulationPeriodic(); } + +#ifndef RUNNING_FRC_TESTS +int main() { return frc::StartRobot(); } +#endif diff --git a/photonlib-cpp-examples/apriltagExample/src/main/include/Drivetrain.h b/photonlib-cpp-examples/apriltagExample/src/main/include/Drivetrain.h new file mode 100644 index 0000000000..7995030bae --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/main/include/Drivetrain.h @@ -0,0 +1,140 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PhotonCameraWrapper.h" + +/** + * Represents a differential drive style drivetrain. + */ +class Drivetrain { + public: + Drivetrain() { + m_gyro.Reset(); + + // We need to invert one side of the drivetrain so that positive voltages + // result in both sides moving forward. Depending on how your robot's + // gearbox is constructed, you might have to invert the left side instead. + m_rightGroup.SetInverted(true); + + // Set the distance per pulse for the drive encoders. We can simply use the + // distance traveled for one rotation of the wheel divided by the encoder + // resolution. + m_leftEncoder.SetDistancePerPulse(2 * std::numbers::pi * kWheelRadius / + kEncoderResolution); + m_rightEncoder.SetDistancePerPulse(2 * std::numbers::pi * kWheelRadius / + kEncoderResolution); + + m_leftEncoder.Reset(); + m_rightEncoder.Reset(); + + m_rightGroup.SetInverted(true); + + frc::SmartDashboard::PutData("Field", &m_fieldSim); + } + + static constexpr units::meters_per_second_t kMaxSpeed = + 3.0_mps; // 3 meters per second + static constexpr units::radians_per_second_t kMaxAngularSpeed{ + std::numbers::pi}; // 1/2 rotation per second + + void SetSpeeds(const frc::DifferentialDriveWheelSpeeds& speeds); + void Drive(units::meters_per_second_t xSpeed, + units::radians_per_second_t rot); + void UpdateOdometry(); + void ResetOdometry(const frc::Pose2d& pose); + + frc::Pose2d GetPose() const { return m_poseEstimator.GetEstimatedPosition(); } + + void SimulationPeriodic(); + void Periodic(); + + private: + static constexpr units::meter_t kTrackWidth = 0.381_m * 2; + static constexpr double kWheelRadius = 0.0508; // meters + static constexpr int kEncoderResolution = 4096; + + frc::PWMSparkMax m_leftLeader{1}; + frc::PWMSparkMax m_leftFollower{2}; + frc::PWMSparkMax m_rightLeader{3}; + frc::PWMSparkMax m_rightFollower{4}; + + frc::MotorControllerGroup m_leftGroup{m_leftLeader, m_leftFollower}; + frc::MotorControllerGroup m_rightGroup{m_rightLeader, m_rightFollower}; + + frc::Encoder m_leftEncoder{0, 1}; + frc::Encoder m_rightEncoder{2, 3}; + + frc2::PIDController m_leftPIDController{8.5, 0.0, 0.0}; + frc2::PIDController m_rightPIDController{8.5, 0.0, 0.0}; + + frc::AnalogGyro m_gyro{0}; + + frc::DifferentialDriveKinematics m_kinematics{kTrackWidth}; + + frc::DifferentialDrivePoseEstimator m_poseEstimator{ + m_kinematics, m_gyro.GetRotation2d(), + units::meter_t{m_leftEncoder.GetDistance()}, + units::meter_t{m_rightEncoder.GetDistance()}, frc::Pose2d{}}; + + PhotonCameraWrapper m_pcw; + + // Gains are for example purposes only - must be determined for your own + // robot! + frc::SimpleMotorFeedforward m_feedforward{1_V, 3_V / 1_mps}; + + // Simulation classes help us simulate our robot + frc::sim::AnalogGyroSim m_gyroSim{m_gyro}; + frc::sim::EncoderSim m_leftEncoderSim{m_leftEncoder}; + frc::sim::EncoderSim m_rightEncoderSim{m_rightEncoder}; + frc::Field2d m_fieldSim; + frc::LinearSystem<2, 2, 2> m_drivetrainSystem = + frc::LinearSystemId::IdentifyDrivetrainSystem( + 1.98_V / 1_mps, 0.2_V / 1_mps_sq, 1.5_V / 1_mps, 0.3_V / 1_mps_sq); + frc::sim::DifferentialDrivetrainSim m_drivetrainSimulator{ + m_drivetrainSystem, kTrackWidth, frc::DCMotor::CIM(2), 8, 2_in}; +}; diff --git a/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h b/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h new file mode 100644 index 0000000000..46ec0a9551 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h @@ -0,0 +1,45 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include +#include + +#include +#include + +class PhotonCameraWrapper { + public: + photonlib::PhotonPoseEstimator m_poseEstimator{ + frc::LoadAprilTagLayoutField(frc::AprilTagField::k2023ChargedUp), + photonlib::LOWEST_AMBIGUITY, + std::move(photonlib::PhotonCamera{"WPI2023"}), frc::Transform3d{}}; + + inline std::optional Update( + frc::Pose2d estimatedPose) { + m_poseEstimator.SetReferencePose(frc::Pose3d(estimatedPose)); + return m_poseEstimator.Update(); + } +}; diff --git a/photonlib-cpp-examples/apriltagExample/src/main/include/Robot.h b/photonlib-cpp-examples/apriltagExample/src/main/include/Robot.h new file mode 100644 index 0000000000..9570d66f8c --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/main/include/Robot.h @@ -0,0 +1,50 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Drivetrain.h" + +class Robot : public frc::TimedRobot { + public: + void RobotInit() override; + void RobotPeriodic() override; + void TeleopPeriodic() override; + void SimulationPeriodic() override; + + private: + frc::XboxController m_controller{0}; + + Drivetrain m_drive; +}; diff --git a/photonlib-cpp-examples/apriltagExample/src/test/cpp/main.cpp b/photonlib-cpp-examples/apriltagExample/src/test/cpp/main.cpp new file mode 100644 index 0000000000..e9ee94e8b0 --- /dev/null +++ b/photonlib-cpp-examples/apriltagExample/src/test/cpp/main.cpp @@ -0,0 +1,34 @@ +/* + * MIT License + * + * Copyright (c) 2022 PhotonVision + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "gtest/gtest.h" + +int main(int argc, char** argv) { + HAL_Initialize(500, 0); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/photonlib-cpp-examples/examples.txt b/photonlib-cpp-examples/examples.txt index 54fc7fa001..25f7648520 100644 --- a/photonlib-cpp-examples/examples.txt +++ b/photonlib-cpp-examples/examples.txt @@ -1,3 +1,4 @@ aimandrange getinrange aimattarget +apriltagExample diff --git a/photonlib-cpp-examples/getinrange/build.gradle b/photonlib-cpp-examples/getinrange/build.gradle index b300429674..10e9a0f769 100644 --- a/photonlib-cpp-examples/getinrange/build.gradle +++ b/photonlib-cpp-examples/getinrange/build.gradle @@ -1,7 +1,7 @@ plugins { id "cpp" id "google-test-test-suite" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" id "com.dorongold.task-tree" version "2.1.0" } diff --git a/photonlib-java-examples/aimandrange/build.gradle b/photonlib-java-examples/aimandrange/build.gradle index a5629b00c3..a7b059a15d 100644 --- a/photonlib-java-examples/aimandrange/build.gradle +++ b/photonlib-java-examples/aimandrange/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 diff --git a/photonlib-java-examples/aimattarget/build.gradle b/photonlib-java-examples/aimattarget/build.gradle index 0c26b06332..1536aafcce 100644 --- a/photonlib-java-examples/aimattarget/build.gradle +++ b/photonlib-java-examples/aimattarget/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 diff --git a/photonlib-java-examples/apriltagExample/build.gradle b/photonlib-java-examples/apriltagExample/build.gradle index a5629b00c3..a7b059a15d 100644 --- a/photonlib-java-examples/apriltagExample/build.gradle +++ b/photonlib-java-examples/apriltagExample/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 diff --git a/photonlib-java-examples/getinrange/build.gradle b/photonlib-java-examples/getinrange/build.gradle index a5629b00c3..a7b059a15d 100644 --- a/photonlib-java-examples/getinrange/build.gradle +++ b/photonlib-java-examples/getinrange/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 diff --git a/photonlib-java-examples/simaimandrange/build.gradle b/photonlib-java-examples/simaimandrange/build.gradle index a5629b00c3..a7b059a15d 100644 --- a/photonlib-java-examples/simaimandrange/build.gradle +++ b/photonlib-java-examples/simaimandrange/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 diff --git a/photonlib-java-examples/simposeest/build.gradle b/photonlib-java-examples/simposeest/build.gradle index a5629b00c3..a7b059a15d 100644 --- a/photonlib-java-examples/simposeest/build.gradle +++ b/photonlib-java-examples/simposeest/build.gradle @@ -1,6 +1,6 @@ plugins { id "java" - id "edu.wpi.first.GradleRIO" version "2023.2.1" + id "edu.wpi.first.GradleRIO" version "2023.3.2" } sourceCompatibility = JavaVersion.VERSION_11 From 7176b4c64328cc59cc8243ae4ec7d5c0a98d9ccd Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 10 Feb 2023 09:46:31 -0500 Subject: [PATCH 2/4] Delete libphotonlibcamera.so --- photon-server/lib/libphotonlibcamera.so | Bin 141664 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 photon-server/lib/libphotonlibcamera.so diff --git a/photon-server/lib/libphotonlibcamera.so b/photon-server/lib/libphotonlibcamera.so deleted file mode 100644 index 90bb006943b0cde91e730c3bd0893ce9d91e85d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141664 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
5nZ58Z&H>Q64cNi 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 D<;kP= From 0509b6963343a7511ca6df24219ef05b8c8591dd Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 10 Feb 2023 18:47:52 -0500 Subject: [PATCH 3/4] Update PhotonCameraWrapper.h --- .../apriltagExample/src/main/include/PhotonCameraWrapper.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h b/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h index 46ec0a9551..e45517b8f9 100644 --- a/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h +++ b/photonlib-cpp-examples/apriltagExample/src/main/include/PhotonCameraWrapper.h @@ -23,10 +23,11 @@ */ #pragma once - #include #include +#include + #include #include From cd592eefea78a584e70222dbf971770510bbc685 Mon Sep 17 00:00:00 2001 From: Matthew Morley Date: Sat, 11 Feb 2023 08:50:28 -0500 Subject: [PATCH 4/4] Delete extra files Update .gitignore --- .gitignore | 2 + photon-server/networktables.json | 1 - .../.wpilib/wpilib_preferences.json | 6 -- .../apriltagExample/networktables.json | 1 - .../apriltagExample/simgui-window.json | 74 ------------------- .../apriltagExample/simgui.json | 37 ---------- .../apriltagExample/src/main/cpp/Robot.cpp | 5 +- .../src/main/java/frc/robot/Robot.java | 2 +- 8 files changed, 6 insertions(+), 122 deletions(-) delete mode 100644 photon-server/networktables.json delete mode 100644 photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json delete mode 100644 photonlib-cpp-examples/apriltagExample/networktables.json delete mode 100644 photonlib-cpp-examples/apriltagExample/simgui-window.json delete mode 100644 photonlib-cpp-examples/apriltagExample/simgui.json diff --git a/.gitignore b/.gitignore index 6d862765b1..721d1619a0 100644 --- a/.gitignore +++ b/.gitignore @@ -153,3 +153,5 @@ photon-server/src/main/resources/nativelibraries/apriltag/* photonlib-java-examples/*/vendordeps/* photonlib-cpp-examples/*/vendordeps/* + +networktables.json diff --git a/photon-server/networktables.json b/photon-server/networktables.json deleted file mode 100644 index fe51488c70..0000000000 --- a/photon-server/networktables.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json b/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json deleted file mode 100644 index cf67d2d09f..0000000000 --- a/photonlib-cpp-examples/apriltagExample/.wpilib/wpilib_preferences.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "enableCppIntellisense": true, - "currentLanguage": "cpp", - "projectYear": "2023", - "teamNumber": 5 -} diff --git a/photonlib-cpp-examples/apriltagExample/networktables.json b/photonlib-cpp-examples/apriltagExample/networktables.json deleted file mode 100644 index fe51488c70..0000000000 --- a/photonlib-cpp-examples/apriltagExample/networktables.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/photonlib-cpp-examples/apriltagExample/simgui-window.json b/photonlib-cpp-examples/apriltagExample/simgui-window.json deleted file mode 100644 index bc6ee74a73..0000000000 --- a/photonlib-cpp-examples/apriltagExample/simgui-window.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "Docking": { - "Data": [] - }, - "MainWindow": { - "GLOBAL": { - "fps": "120", - "height": "880", - "maximized": "0", - "style": "0", - "userScale": "2", - "width": "1652", - "xpos": "268", - "ypos": "82" - } - }, - "Window": { - "###/SmartDashboard/Field": { - "Collapsed": "0", - "Pos": "514,2", - "Size": "517,341" - }, - "###FMS": { - "Collapsed": "0", - "Pos": "36,663", - "Size": "283,146" - }, - "###Joysticks": { - "Collapsed": "0", - "Pos": "373,500", - "Size": "796,206" - }, - "###Keyboard 0 Settings": { - "Collapsed": "0", - "Pos": "149,98", - "Size": "300,560" - }, - "###NetworkTables": { - "Collapsed": "0", - "Pos": "663,464", - "Size": "750,365" - }, - "###NetworkTables Info": { - "Collapsed": "0", - "Pos": "520,330", - "Size": "750,145" - }, - "###Other Devices": { - "Collapsed": "0", - "Pos": "1025,20", - "Size": "250,695" - }, - "###System Joysticks": { - "Collapsed": "0", - "Pos": "5,350", - "Size": "192,218" - }, - "###Timing": { - "Collapsed": "0", - "Pos": "5,150", - "Size": "135,127" - }, - "Debug##Default": { - "Collapsed": "0", - "Pos": "60,60", - "Size": "400,400" - }, - "Robot State": { - "Collapsed": "0", - "Pos": "5,20", - "Size": "92,99" - } - } -} diff --git a/photonlib-cpp-examples/apriltagExample/simgui.json b/photonlib-cpp-examples/apriltagExample/simgui.json deleted file mode 100644 index e0d54bca73..0000000000 --- a/photonlib-cpp-examples/apriltagExample/simgui.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "NTProvider": { - "types": { - "/FMSInfo": "FMSInfo", - "/SmartDashboard/Field": "Field2d" - }, - "windows": { - "/SmartDashboard/Field": { - "window": { - "visible": true - } - } - } - }, - "NetworkTables": { - "transitory": { - "SmartDashboard": { - "open": true - }, - "photonvision": { - "open": true, - "photonvision": { - "open": true - } - } - } - }, - "NetworkTables Info": { - "Clients": { - "open": true - }, - "Server": { - "open": true - }, - "visible": true - } -} diff --git a/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp index 47e4b8bdb9..4d3742aeb4 100644 --- a/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp +++ b/photonlib-cpp-examples/apriltagExample/src/main/cpp/Robot.cpp @@ -31,8 +31,9 @@ void Robot::RobotInit() { if constexpr (frc::RobotBase::IsSimulation()) { auto inst = nt::NetworkTableInstance::GetDefault(); inst.StopServer(); - // Change the IP address in the below function to the IP address you use to - // connect to the PhotonVision UI. + // set the NT server if simulating this code. + // "localhost" for photon on desktop, or "photonvision.local" or + // "[ip-address]" for coprocessor inst.SetServer("localhost"); inst.StartClient4("Robot Simulation"); } diff --git a/photonlib-java-examples/apriltagExample/src/main/java/frc/robot/Robot.java b/photonlib-java-examples/apriltagExample/src/main/java/frc/robot/Robot.java index 3a258bc42d..184446f2ca 100644 --- a/photonlib-java-examples/apriltagExample/src/main/java/frc/robot/Robot.java +++ b/photonlib-java-examples/apriltagExample/src/main/java/frc/robot/Robot.java @@ -46,7 +46,7 @@ public void robotInit() { // set the NT server if simulating this code. // "localhost" for photon on desktop, or "photonvision.local" / "[ip-address]" for coprocessor instance.setServer("localhost"); - instance.startClient4("myRobot"); + instance.startClient4("Robot Simulation"); } m_controller = new XboxController(0);