diff --git a/.classpath b/.classpath index 0d2758f..e16509f 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,12 @@ - - - - - - + + + + + + + + + diff --git a/.gitignore b/.gitignore index ebb2475..61f25ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,46 +1,160 @@ -.metadata -.loadpath -tmp/ -*.tmp +# Created by https://www.gitignore.io/api/c++,java,linux,macos,gradle,windows,visualstudiocode -# External tool builders -.externalToolBuilders/ +### C++ ### +# Prerequisites +*.d -# Locally stored "Eclipse launch configurations" -*.launch +# Compiled Object files +*.slo +*.lo +*.o +*.obj -# CDT-specific -.cproject +# Precompiled Headers +*.gch +*.pch -# sbteclipse plugin -.target +# Compiled Dynamic libraries +*.so +*.dylib +*.dll -# TeXlipse plugin -.texlipse +# Fortran module files +*.mod +*.smod -# Compiled Files # +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Java ### +# Compiled class file *.class -doc/ -bin/ -build/ -dist/ -sysProps.xml -# Text Backup Files # -*.sw[a-z] +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### *~ -\#*\# -.\#* -*.bak -# OS X Files # +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General .DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails ._* -.Spotlight* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems .Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent -# Windows Files # +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files Thumbs.db ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# # VS Code Specific Java Settings +.classpath +.project +.settings/ +bin/ + -logs.txt +# End of https://www.gitignore.io/api/c++,java,linux,macos,gradle,windows,visualstudiocode diff --git a/.project b/.project index 9cba1ad..da5021d 100644 --- a/.project +++ b/.project @@ -1,7 +1,7 @@ DEStiny - + Project DEStiny created by Buildship. @@ -10,9 +10,14 @@ + + org.eclipse.buildship.core.gradleprojectbuilder + + + org.eclipse.jdt.core.javanature - edu.wpi.first.wpilib.plugins.core.nature.FRCProjectNature + org.eclipse.buildship.core.gradleprojectnature diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c9c9713 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "wpilib", + "name": "WPILib Desktop Debug", + "request": "launch", + "desktop": true, + }, + { + "type": "wpilib", + "name": "WPILib roboRIO Debug", + "request": "launch", + "desktop": false, + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..860e319 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "bin/": true, + ".classpath": true, + ".project": true + }, + "wpilib.online": true +} diff --git a/.wpilib/wpilib_preferences.json b/.wpilib/wpilib_preferences.json new file mode 100644 index 0000000..21967ee --- /dev/null +++ b/.wpilib/wpilib_preferences.json @@ -0,0 +1,6 @@ +{ + "enableCppIntellisense": false, + "currentLanguage": "java", + "projectYear": "2019", + "teamNumber": 694 +} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index f0557e2..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# DEStiny -## Team 694, StuyPulse -### Code for the 2016 (Stronghold) robot diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..a2bd5c7 --- /dev/null +++ b/build.gradle @@ -0,0 +1,61 @@ +plugins { + id "java" + id "edu.wpi.first.GradleRIO" version "2019.3.2" +} + +def ROBOT_MAIN_CLASS = "edu.stuy.robot.Main" + +// Define my targets (RoboRIO) and artifacts (deployable files) +// This is added by GradleRIO's backing project EmbeddedTools. +deploy { + targets { + roboRIO("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 = frc.getTeamNumber() + } + } + artifacts { + frcJavaArtifact('frcJava') { + targets << "roborio" + // Debug can be overridden by command line, for use with VSCode + debug = frc.getDebugOrDefault(false) + } + // Built in artifact to deploy arbitrary files to the roboRIO. + fileTreeArtifact('frcStaticFileDeploy') { + // The directory below is the local directory to deploy + files = fileTree(dir: 'src/main/deploy') + // Deploy to RoboRIO target, into /home/lvuser/deploy + targets << "roborio" + directory = '/home/lvuser/deploy' + } + } +} + +// Set this to true to enable desktop support. +def includeDesktopSupport = true + +// Maven central needed for JUnit +repositories { + mavenCentral() +} + +// Defining my dependencies. In this case, WPILib (+ friends), and vendor libraries. +// Also defines JUnit 4. +dependencies { + compile wpi.deps.wpilib() + compile wpi.deps.vendor.java() + nativeZip wpi.deps.vendor.jni(wpi.platforms.roborio) + nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop) + testCompile 'junit:junit:4.12' +} + +// Setting up my Jar File. In this case, adding all libraries into the main jar ('fat jar') +// in order to make them all available at runtime. Also adding the manifest so WPILib +// knows where to look for our Robot Class. +jar { + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) +} diff --git a/build.properties b/build.properties deleted file mode 100644 index 0644b64..0000000 --- a/build.properties +++ /dev/null @@ -1,10 +0,0 @@ -# Project specific information -package=edu.stuy.robot -robot.class=${package}.Robot -simulation.world.file=/usr/share/frcsim/worlds/GearsBotDemo.world -libs.dir=${src.dir}\\..\\lib -userLibs=/usr/local/share/OpenCV/java/opencv-310.jar -# userLibs points to the opencv jar on the roborio. It also, however, -# needs to point to a valid opencv jar on the machine on which DEStiny -# is being built/deployed. On Windows, like on Justin Time, this can -# be put at C:/usr/local/... and be treated as /usr/local/... diff --git a/build.xml b/build.xml deleted file mode 100644 index 76fd29a..0000000 --- a/build.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..457aad0 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d08253c --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=permwrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=permwrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..af6708f --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@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 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" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b0f4d48 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,25 @@ +import org.gradle.internal.os.OperatingSystem + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + String frcYear = '2019' + File frcHome + if (OperatingSystem.current().isWindows()) { + String publicFolder = System.getenv('PUBLIC') + if (publicFolder == null) { + publicFolder = "C:\\Users\\Public" + } + frcHome = new File(publicFolder, "frc${frcYear}") + } else { + def userFolder = System.getProperty("user.home") + frcHome = new File(userFolder, "frc${frcYear}") + } + def frcHomeMaven = new File(frcHome, 'maven') + maven { + name 'frcHome' + url frcHomeMaven + } + } +} diff --git a/src/edu/stuy/robot/commands/CVReadAndPrintCommand.java b/src/edu/stuy/robot/commands/CVReadAndPrintCommand.java deleted file mode 100644 index 252ebe0..0000000 --- a/src/edu/stuy/robot/commands/CVReadAndPrintCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -package edu.stuy.robot.commands; - -import java.util.Arrays; - -import edu.stuy.robot.Robot; -import edu.stuy.robot.cv.StuyVision; -import edu.wpi.first.wpilibj.command.Command; -import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; - -/** - * - */ -public class CVReadAndPrintCommand extends Command { - boolean tryToSaveFile; - public CVReadAndPrintCommand() { - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - } - public CVReadAndPrintCommand(boolean save) { - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - tryToSaveFile = save; - } - - // Called just before this Command runs the first time - protected void initialize() { - try { - long start = System.currentTimeMillis(); - double[] cvReading = null; - cvReading = Robot.vision.processImage(Robot.isDebugModeOn() && tryToSaveFile); - System.out.println("\n\n\n\n\n\n\n\n\n\nprocessImage took " + (System.currentTimeMillis() - start) + "ms"); - System.out.println(new StuyVision.Report(cvReading)); - boolean canProceed = cvReading != null; - SmartDashboard.putString("cv-reading", Arrays.toString(cvReading)); - if (canProceed) { - double desiredAngle = StuyVision.frameXPxToDegrees(cvReading[0]); - SmartDashboard.putNumber("cv-angle", desiredAngle); - System.out.println("Desired Angle Delta: " + desiredAngle); - } - SmartDashboard.putBoolean("cv-visible", canProceed); - } catch (Exception e) { - System.err.println("\n\n\n\nGeneric exception caught in CVReadAndPrintCommand:"); - e.printStackTrace(); - System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); - } - } - - // Called repeatedly when this Command is scheduled to run - protected void execute() { - } - - // Make this return true when this Command no longer needs to run execute() - protected boolean isFinished() { - return true; - } - - // Called once after isFinished returns true - protected void end() { - } - - // Called when another command which requires one or more of the same - // subsystems is scheduled to run - protected void interrupted() { - } -} diff --git a/src/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java b/src/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java deleted file mode 100644 index 8a225a0..0000000 --- a/src/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java +++ /dev/null @@ -1,34 +0,0 @@ -package edu.stuy.robot.commands; - -import static edu.stuy.robot.RobotMap.COURTYARD_SHOOTING_DISTANCE; - -import edu.stuy.robot.Robot; -import edu.stuy.robot.cv.StuyVision; - -/** - * - */ -public class DriveToCourtyardRangeCommand extends EncoderDrivingCommand { - - public DriveToCourtyardRangeCommand() { - super(Robot.stopAutoMovement); - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - requires(Robot.drivetrain); - } - - protected void setInchesToMove() { - double[] cvReading = Robot.vision.processImage(); - if (cvReading != null) { - double curDistance = StuyVision.findBotDistanceToGoal(cvReading[1]); - initialInchesToMove = curDistance - COURTYARD_SHOOTING_DISTANCE; - } else { - // CV failed! - cancelCommand = true; - } - System.out.println(new StuyVision.Report(cvReading)); - if (cvReading != null) { - System.out.println(StuyVision.findBotDistanceToGoal(cvReading[1])); - } - } -} diff --git a/src/edu/stuy/robot/commands/DriveToLayupRangeCommand.java b/src/edu/stuy/robot/commands/DriveToLayupRangeCommand.java deleted file mode 100644 index bccc958..0000000 --- a/src/edu/stuy/robot/commands/DriveToLayupRangeCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package edu.stuy.robot.commands; - -import static edu.stuy.robot.RobotMap.LAYUP_SHOOTING_DISTANCE; - -import edu.stuy.robot.Robot; -import edu.stuy.robot.cv.StuyVision; -import edu.stuy.util.BoolBox; - -/** - * - */ -public class DriveToLayupRangeCommand extends EncoderDrivingCommand { - - public DriveToLayupRangeCommand() { - super(Robot.stopAutoMovement); - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - requires(Robot.drivetrain); - } - - protected void setInchesToMove() { - double[] cvReading = Robot.vision.processImage(); - if (cvReading != null) { - double curDistance = StuyVision.findBotDistanceToGoal(cvReading[1]); - initialInchesToMove = curDistance - LAYUP_SHOOTING_DISTANCE; - } else { - // CV failed! - cancelCommand = true; - } - System.out.println(new StuyVision.Report(cvReading)); - if (cvReading != null) { - System.out.println(StuyVision.findBotDistanceToGoal(cvReading[1])); - } - } -} diff --git a/src/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java b/src/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java deleted file mode 100644 index 22df168..0000000 --- a/src/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package edu.stuy.robot.commands; - -import edu.wpi.first.wpilibj.command.CommandGroup; - -/** - * - */ -public class DriveToLayupRangeMultiCommand extends CommandGroup { - - public DriveToLayupRangeMultiCommand() { - // Add Commands here: - // e.g. addSequential(new Command1()); - // addSequential(new Command2()); - // these will run in order. - - // To run multiple commands at the same time, - // use addParallel() - // e.g. addParallel(new Command1()); - // addSequential(new Command2()); - // Command1 and Command2 will run in parallel. - - // A command group will require all of the subsystems that each member - // would require. - // e.g. if Command1 requires chassis, and Command2 requires arm, - // a CommandGroup containing them would require both the chassis and the - // arm. - - // This is a janky way of doing this. Urgency calls. - - // First movement: - addSequential(new DriveToLayupRangeCommand()); - // Refine to account for mistakes: - addSequential(new DriveToLayupRangeCommand()); - } -} diff --git a/src/edu/stuy/robot/commands/RotateToAimCommand.java b/src/edu/stuy/robot/commands/RotateToAimCommand.java deleted file mode 100644 index 1a55b75..0000000 --- a/src/edu/stuy/robot/commands/RotateToAimCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -package edu.stuy.robot.commands; - -import java.util.Arrays; - -import edu.stuy.robot.Robot; -import edu.stuy.robot.cv.StuyVision; -import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; - -/** - * - */ -public class RotateToAimCommand extends GyroRotationalCommand { - - public RotateToAimCommand() { - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - super(Robot.stopAutoMovement, false); - } - - public RotateToAimCommand(boolean gentle) { - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - super(Robot.stopAutoMovement, gentle); - } - - public RotateToAimCommand(boolean gentle, double tolerance) { - // Use requires() here to declare subsystem dependencies - // eg. requires(chassis); - super(Robot.stopAutoMovement, gentle, tolerance); - } - - private double[] cvReading; - - protected void setDesiredAngle() { - cvReading = Robot.vision.processImage(); - canProceed = cvReading != null; - SmartDashboard.putString("cv-reading", Arrays.toString(cvReading)); - if (canProceed) { - desiredAngle = StuyVision.frameXPxToDegrees(cvReading[0]); - SmartDashboard.putNumber("cv-angle", desiredAngle); - } - SmartDashboard.putBoolean("cv-visible", canProceed); - // For auton: - Robot.cvFoundGoal = canProceed; - } - - protected void onEnd() { - System.out.println(new StuyVision.Report(cvReading)); - } -} diff --git a/src/edu/stuy/robot/commands/RotateToAimMultiCommand.java b/src/edu/stuy/robot/commands/RotateToAimMultiCommand.java deleted file mode 100644 index 7b63e82..0000000 --- a/src/edu/stuy/robot/commands/RotateToAimMultiCommand.java +++ /dev/null @@ -1,27 +0,0 @@ -package edu.stuy.robot.commands; - -import edu.wpi.first.wpilibj.command.CommandGroup; - -/** - * - */ -public class RotateToAimMultiCommand extends CommandGroup { - - public RotateToAimMultiCommand() { - // First rotation: - addSequential(new RotateToAimCommand()); - // Refine: - GyroRotationalCommand finalRot = new RotateToAimCommand(true); - finalRot.setUseSignalLights(true); - addSequential(finalRot); - } - - public RotateToAimMultiCommand(double tolerance) { - // First rotation: - addSequential(new RotateToAimCommand(false, tolerance)); - // Refine: - GyroRotationalCommand finalRot = new RotateToAimCommand(true); - finalRot.setUseSignalLights(true); - addSequential(finalRot); - } -} diff --git a/src/edu/stuy/robot/commands/SetupForShotCommand.java b/src/edu/stuy/robot/commands/SetupForShotCommand.java deleted file mode 100644 index f6f1263..0000000 --- a/src/edu/stuy/robot/commands/SetupForShotCommand.java +++ /dev/null @@ -1,41 +0,0 @@ -package edu.stuy.robot.commands; - -import edu.wpi.first.wpilibj.command.CommandGroup; - -/** - * - */ -public class SetupForShotCommand extends CommandGroup { - - public SetupForShotCommand() { - // Add Commands here: - // e.g. addSequential(new Command1()); - // addSequential(new Command2()); - // these will run in order. - - // To run multiple commands at the same time, - // use addParallel() - // e.g. addParallel(new Command1()); - // addSequential(new Command2()); - // Command1 and Command2 will run in parallel. - - // A command group will require all of the subsystems that each member - // would require. - // e.g. if Command1 requires chassis, and Command2 requires arm, - // a CommandGroup containing them would require both the chassis and the - // arm. - - addSequential(new ResetForceStopCommand()); - - addSequential(new RotateToAimCommand(false, 1.5)); // Coarse rotation - addSequential(new RotateToAimCommand(true)); // Refining rotation - - addSequential(new DriveToLayupRangeCommand()); - - GyroRotationalCommand finalRotation = new RotateToAimCommand(false, 1.7); - finalRotation.setUseSignalLights(true); - addSequential(finalRotation); - - addSequential(new ResetForceStopCommand()); - } -} diff --git a/src/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java b/src/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java deleted file mode 100644 index 374b0f0..0000000 --- a/src/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java +++ /dev/null @@ -1,53 +0,0 @@ -package edu.stuy.robot.commands.auton; - -import edu.stuy.robot.commands.DrivetrainStopCommand; -import edu.stuy.robot.commands.FlashlightOnCommand; -import edu.stuy.robot.commands.LowGearCommand; -import edu.stuy.robot.commands.SetupForShotCommand; -import edu.stuy.robot.commands.ShooterSetLayupCommand; -import edu.wpi.first.wpilibj.command.Command; -import edu.wpi.first.wpilibj.command.CommandGroup; - -/** - * - */ -public class CrossObstacleThenShootCommand extends CommandGroup { - - public CrossObstacleThenShootCommand(Command obstacle, int position) { - // Add Commands here: - // e.g. addSequential(new Command1()); - // addSequential(new Command2()); - // these will run in order. - - // To run multiple commands at the same time, - // use addParallel() - // e.g. addParallel(new Command1()); - // addSequential(new Command2()); - // Command1 and Command2 will run in parallel. - - // A command group will require all of the subsystems that each member - // would require. - // e.g. if Command1 requires chassis, and Command2 requires arm, - // a CommandGroup containing them would require both the chassis and the - // arm. - - addSequential(obstacle); - addSequential(new LowGearCommand()); - addSequential(new DrivetrainStopCommand()); - addParallel(new ShooterSetLayupCommand()); - addSequential(new DropDownMoveToAngleCommand(0), 2.0); - if (position != 3 && position != 4) { - // RotateDrivetrainCommand will, at runtime, decide angle - // based on Robot.autonPositionChooser.getSelected() - addSequential(new RotateDrivetrainCommand()); - } - addParallel(new FlashlightOnCommand()); // So we can see where it is aiming - addSequential(new SetupForShotCommand()); - - // The following only runs the hopper if goal was in frame for CV - addSequential(new HandleAutonShotCommand(), 3.0); - - // Drivetrain returns to high gear in teleopInit, where - // also shooter, hopper and flashlight are turned off. - } -} diff --git a/src/edu/stuy/robot/cv/StuyVision.java b/src/edu/stuy/robot/cv/StuyVision.java deleted file mode 100644 index c5f869b..0000000 --- a/src/edu/stuy/robot/cv/StuyVision.java +++ /dev/null @@ -1,411 +0,0 @@ -package edu.stuy.robot.cv; - -import static edu.stuy.robot.RobotMap.CAMERA_DIST_TO_BOT_FRONT; -import static edu.stuy.robot.RobotMap.CAMERA_FRAME_PX_HEIGHT; -import static edu.stuy.robot.RobotMap.CAMERA_FRAME_PX_WIDTH; -import static edu.stuy.robot.RobotMap.CAMERA_HEIGHT_FROM_GROUND; -import static edu.stuy.robot.RobotMap.CAMERA_TILT_ANGLE; -import static edu.stuy.robot.RobotMap.CAMERA_VIEWING_ANGLE_X; -import static edu.stuy.robot.RobotMap.CAMERA_VIEWING_ANGLE_Y; -import static edu.stuy.robot.RobotMap.HIGH_GOAL_HEIGHT; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; - -import org.opencv.core.Core; -import org.opencv.core.CvType; -import org.opencv.core.Mat; -import org.opencv.core.MatOfPoint; -import org.opencv.core.MatOfPoint2f; -import org.opencv.core.Point; -import org.opencv.core.RotatedRect; -import org.opencv.core.Scalar; -import org.opencv.core.Size; -import org.opencv.imgcodecs.Imgcodecs; -import org.opencv.imgproc.Imgproc; -import org.opencv.videoio.Videoio; - -import edu.stuy.robot.cv.capture.CaptureSource; -import edu.stuy.robot.cv.capture.DeviceCaptureSource; -import edu.stuy.robot.cv.gui.DoubleSV; -import edu.stuy.robot.cv.gui.IntegerSV; -import edu.stuy.robot.cv.gui.Main; -import edu.stuy.robot.cv.gui.VisionModule; - -public class StuyVision extends VisionModule { - - // The following can be left in even in production, as the overhead - // of using .value() is negligible - public IntegerSV minH_GREEN = IntegerSV.mkColor(36, "Min Hue"); - public IntegerSV maxH_GREEN = IntegerSV.mkColor(94, "Max Hue"); - - public IntegerSV minS_GREEN = IntegerSV.mkColor(225, "Min Saturation"); - public IntegerSV maxS_GREEN = IntegerSV.mkColor(255, "Max Saturation"); - - public IntegerSV minV_GREEN = IntegerSV.mkColor(30, "Min Value"); - public IntegerSV maxV_GREEN = IntegerSV.mkColor(255, "Max Value"); - - // Thresholds regarding the geometry of the bounding box of the region found - // by the HSV filtering - public DoubleSV minGoalArea = new DoubleSV(200.0, 0.0, 10000.0, "Min Goal Area"); - public DoubleSV maxGoalArea = new DoubleSV(30720.0, 0.0, 10000.0, "Max Goal Area"); - public DoubleSV minGoalRatio = new DoubleSV(1.1, 1.0, 10.0, "Min Goal Ratio"); - public DoubleSV maxGoalRatio = new DoubleSV(3.0, 1.0, 10.0, "Max Goal Ratio"); - - private static final int outerUSBPort = 0; - private int cameraPort; - private DeviceCaptureSource camera; - - private static PrintWriter logWriter; - - // Reused across processImage() calls - private Mat rawFrame; - private Mat resizedFrame; - - public StuyVision() { - try { - // Ensure native libraries are loaded - loadOpenCV(); - // Assume the camera is plugged into port `outerUSBPort` - cameraPort = outerUSBPort; - initializeCamera(); - rawFrame = new Mat(); - resizedFrame = new Mat(); - } catch (Exception e) { - System.out.println("Failed to create camera at " + cameraPort + ". Error was: " + e); - } - try { - logWriter = new PrintWriter("logs.txt"); - } catch (Exception e) { - } - } - - public static void loadOpenCV() { - // Load opencv native library - String dir = StuyVision.class.getClassLoader().getResource("").getPath(); - if (System.getProperty("os.name").toLowerCase().contains("windows")) { - System.load(dir.substring(1).replaceAll("\\%20", " ") - + "..\\lib\\opencv-3.0.0\\build\\java\\x64\\opencv_java300.dll"); - } else { - // This is the .so's location on the roboRio - System.load("/usr/local/share/OpenCV/java/libopencv_java310.so"); - } - } - - private void initializeCamera() { - Runtime rt = Runtime.getRuntime(); - try { - rt.exec("/usr/bin/v4l2-ctl -c exposure_auto=1,exposure_absolute=5,brightness=30,contrast=10,saturation=200,white_balance_temperature_auto=0,sharpness=50").waitFor(); - rt.exec("/usr/bin/v4l2-ctl -c white_balance_temperature=4624").waitFor(); - } catch (Exception e) { - System.err.println("Setting v4l settings crashed!"); - } - camera = new DeviceCaptureSource(cameraPort); - System.out.println("Made camera"); - camera.capture.set(Videoio.CV_CAP_PROP_BUFFERSIZE, 2); - } - - /** - * Given the dimensions of a rectangle, return whether the ratio of these - * rectangle's dimensions suggests it may be a valid goal. - * - * @param height - * @param width - * @return - */ - private boolean aspectRatioThreshold(double height, double width) { - double ratio = width / height; - return (minGoalRatio.value() < ratio && ratio < maxGoalRatio.value()) - || (1 / maxGoalRatio.value() < ratio && ratio < 1 / minGoalRatio.value()); - } - - private double[] getLargestGoal(Mat originalFrame, Mat filteredImage, Main app) { - boolean withGui = app != null; - Mat drawn = null; - if (withGui) { - drawn = originalFrame.clone(); - } - - ArrayList contours = new ArrayList(); - Imgproc.findContours(filteredImage, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); - double largestArea = 0.0; - RotatedRect largestRect = null; - - for (int i = 0; i < contours.size(); i++) { - double currArea = Imgproc.contourArea(contours.get(i)); - if (currArea < minGoalArea.value() || currArea > maxGoalArea.value()) { - continue; - } - MatOfPoint2f tmp = new MatOfPoint2f(); - contours.get(i).convertTo(tmp, CvType.CV_32FC1); - RotatedRect r = Imgproc.minAreaRect(tmp); - if (!aspectRatioThreshold(r.size.height, r.size.width)) { - continue; - } - if (withGui) { - Point[] points = new Point[4]; - r.points(points); - for (int j = 0; j < points.length; j++) { - Imgproc.line(drawn, points[j], points[(j + 1) % 4], new Scalar(0, 255, 0)); - } - } - if (currArea > largestArea) { - largestArea = currArea; - largestRect = r; - } - } - - if (largestRect == null) { - if (withGui) { - // Post the unchanged image anyway for visual consistency - app.postImage(originalFrame, "Goals", this); - } - // Return null to signify no goal found - return null; - } - - double[] vector = new double[3]; - vector[0] = largestRect.center.x - originalFrame.width() / 2.0; - vector[1] = largestRect.center.y - originalFrame.height() / 2.0; - vector[2] = largestRect.angle; - - if (withGui) { - Imgproc.circle(drawn, largestRect.center, 1, new Scalar(0, 0, 255), 2); - double w = drawn.width(); - double h = drawn.height(); - Imgproc.line(drawn, new Point(w / 2, h / 2), largestRect.center, new Scalar(0, 0, 255)); - app.postImage(drawn, "Goals", this); - } - - return vector; - } - - public double[] getLargestGoal(Mat orig, Mat f) { - return getLargestGoal(orig, f, null); - } - - /** - * Process an image to look for a goal, and, if a app is - * passed, post two intermediate states of the image from during processing - * to the gui - * - * @param frame - * The image to process - * - * @param app - * (Optional: pass null to ignore) The Main to - * post intermediate states of the processed image to. - * - * @return Three doubles, in a double[3], ordered as such:

- * index 0: The x-offset, in pixels, of the center of the - * bounding rectangle of the found goal from the center of the image

- *

index 1: The y-offset, in pixels, of the center of the - * bounding rectangle of the found goal form the center of the image

- *

index 2: The angle at which the bounding rectangle is - * tilted

- */ - public double[] hsvThresholding(Mat frame, Main app) { - boolean withGui = app != null; - - // Convert BGR camera image to HSV for processing - Mat hsv = new Mat(); - Imgproc.cvtColor(frame, hsv, Imgproc.COLOR_BGR2HSV); - - // Split HSV channels and process each channel - ArrayList greenFilterChannels = new ArrayList(); - Core.split(hsv, greenFilterChannels); - Core.inRange(greenFilterChannels.get(0), new Scalar(minH_GREEN.value()), new Scalar(maxH_GREEN.value()), - greenFilterChannels.get(0)); - if (withGui) { - app.postImage(greenFilterChannels.get(0), "After H", this); - } - Core.inRange(greenFilterChannels.get(1), new Scalar(minS_GREEN.value()), new Scalar(maxS_GREEN.value()), - greenFilterChannels.get(1)); - if (withGui) { - app.postImage(greenFilterChannels.get(1), "After S", this); - } - Core.inRange(greenFilterChannels.get(2), new Scalar(minV_GREEN.value()), new Scalar(maxV_GREEN.value()), - greenFilterChannels.get(2)); - if (withGui) { - app.postImage(greenFilterChannels.get(2), "After V", this); - } - - // Merge filtered H, S and V back into one binarized image - Mat greenFiltered = new Mat(); - Core.bitwise_and(greenFilterChannels.get(0), greenFilterChannels.get(1), greenFiltered); - Core.bitwise_and(greenFilterChannels.get(2), greenFiltered, greenFiltered); - if (withGui) { - app.postImage(greenFiltered, "After filtering H, S, V", this); - } - - // Erode and dilate to remove noise - Mat erodeKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)); - Mat dilateKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9, 9)); - Imgproc.erode(greenFiltered, greenFiltered, erodeKernel); - Imgproc.dilate(greenFiltered, greenFiltered, dilateKernel); - if (withGui) { - app.postImage(greenFiltered, "After erode/dilate", this); - } - - double[] output = getLargestGoal(frame, greenFiltered, app); - try { - logWriter.println(new Report(output)); - logWriter.flush(); - } catch (Exception e) { - } - return output; - } - - public double[] hsvThresholding(Mat frame) { - return hsvThresholding(frame, null); - } - - public double[] processImage(boolean save) { - if (camera == null) { - System.out.println("Camera object is uninitialized or frame not taken!"); - return null; - } - // To prevent buffer repeat frames from being used: - for (int i = 0; i < 5; i++) { - camera.readFrame(rawFrame); - } - // Now read and resize updated frame: - Mat frame = camera.readSized(rawFrame, resizedFrame); - System.out.println("Got frame from camera"); - if (frame == null) { - System.out.println("FRAME WAS NULL"); - return null; - } - double[] result = hsvThresholding(frame); - if (save) { - String homeDir = System.getProperty("user.home"); - String path = homeDir + "/save.png"; - Imgcodecs.imwrite(path, frame); - System.out.println("Successfully saved"); - } - return result; - } - - public double[] processImage() { - return processImage(false); - } - - /** - * Tests time taken to process iters frames read from - * cs - * - * @param cs - * The CaptureSource from which to read frames - * @param iters - * The number of frames to read from cs and to process and time - * @return The average time taken by hsvThresholding to process - * one of the frames - */ - public double testProcessingTime(CaptureSource cs, int iters) { - int total = 0; - double[] vec; - for (int i = 0; i < iters; i++) { - long start = System.currentTimeMillis(); - vec = processImage(); - total += (int) (System.currentTimeMillis() - start); - } - return total / (double) iters; - } - - // Calculation methods: - public static double frameXPxToDegrees(double px) { - return CAMERA_VIEWING_ANGLE_X * px / CAMERA_FRAME_PX_WIDTH; - } - - public static double frameYPxToDegrees(double dy) { - return dy / CAMERA_FRAME_PX_HEIGHT * CAMERA_VIEWING_ANGLE_Y; - } - - public static double yInFrameToDegreesFromHorizon(double height) { - return CAMERA_TILT_ANGLE - frameYPxToDegrees(height); - } - - public static double findCameraDistanceToGoal(double frameY) { - double angle = yInFrameToDegreesFromHorizon(frameY); - return (HIGH_GOAL_HEIGHT - CAMERA_HEIGHT_FROM_GROUND) / Math.tan(Math.toRadians(angle)); - } - - public static double findBotDistanceToGoal(double frameY) { - return findCameraDistanceToGoal(frameY) - CAMERA_DIST_TO_BOT_FRONT; - } - - public static double findDistanceToGoal(double[] vec) { - if (vec == null) { - return -1; - } - return findCameraDistanceToGoal(vec[1]); - } - - public static class Report { - double[] reading; - double goalDegsY; - double goalDegsX; - double inchesAway; - double degsUp; - - public Report(double[] visionReading) { - if (visionReading == null) { - return; - } - reading = visionReading; - goalDegsX = frameXPxToDegrees(reading[0]); - goalDegsY = frameXPxToDegrees(reading[1]); - degsUp = yInFrameToDegreesFromHorizon(reading[1]); - inchesAway = findCameraDistanceToGoal(reading[1]); - // let null pointer exception occur if data is null - } - - public String formattedReading() { - if (reading == null) { - return "null"; - } - return "[" + fmt(reading[0]) + ", " + fmt(reading[1]) + ", " + fmt(reading[2]) + "]"; - } - - private static final String blank = "------------------------------------"; - - public String toString() { - boolean none = false; - if (reading == null) { - // return "| CV read no goals in frame\n" + blank + blank + - // blank + blank + blank; - none = true; - } - return "| CV Read: " + Arrays.toString(reading) + "\n" + "| Data: " - + (none ? blank : formattedReading()) + "\n" + "| Angle X: " - + (none ? blank : (fmt(goalDegsX) + "\u00B0 right from center")) + "\n" + "| Angle Y: " - + (none ? blank : (fmt(goalDegsY) + "\u00B0 down from center")) + "\n" + "| Elevation: " - + (none ? blank : (fmt(degsUp) + "\u00B0 up from horizon")) + "\n" + "| Cam Dist: " - + (none ? blank : fmtDist(inchesAway)) + "\n" + "| (Time: " + System.currentTimeMillis() + ")\n"; - } - - private static String fmtDist(double d) { - int inches = (int) d; - return (inches / 12) + " ft, " + (inches % 12) + " in"; - } - - private static String fmt(double d) { - return String.format("%.0f", d); - } - } - - public static void main(String[] args) { - System.out.println("Running test: read from frame and determine angle to rotate"); - StuyVision sv = new StuyVision(); - double[] reading = sv.processImage(); - System.out.println(new Report(reading)); - } - - public void run(Main app, Mat frame) { - app.postImage(frame, "Video", this); - double[] reading = hsvThresholding(frame, app); - System.out.println("\n\n" + new Report(reading)); - } -} diff --git a/src/edu/stuy/robot/cv/gui/ControlsController.java b/src/edu/stuy/robot/cv/gui/ControlsController.java deleted file mode 100644 index d699a26..0000000 --- a/src/edu/stuy/robot/cv/gui/ControlsController.java +++ /dev/null @@ -1,170 +0,0 @@ -package edu.stuy.robot.cv.gui; - -import java.lang.reflect.Field; -import java.text.DecimalFormat; -import java.util.ArrayList; - -import edu.stuy.robot.cv.util.DebugPrinter; -import javafx.application.Platform; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.fxml.FXML; -import javafx.geometry.Pos; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.Slider; -import javafx.scene.layout.FlowPane; -import javafx.scene.layout.VBox; -import javafx.scene.text.Text; - -public class ControlsController { - - @FXML - FlowPane flowPane; - @FXML - VBox controlsContainer; - @FXML - Button restoreDefaults; - - final DecimalFormat formatter = new DecimalFormat("#.###"); - - public void setup(VisionModule module) { - ArrayList variables = new ArrayList<>(); - restoreDefaults.setOnAction((event) -> { - for (VariableWrapper var : variables) { - var.restoreDefault(); - } - }); - ArrayList variableContainers = new ArrayList<>(); - for (Field f : module.getClass().getFields()) { - Class fType = f.getType(); - if (fType.isAssignableFrom(IntegerSV.class)) { - DebugPrinter.println("Found IntegerSV: " + f.getName()); - IntegerSV isv = null; - try { - isv = (IntegerSV) f.get(module); - } - catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - VBox sliderContainer = new VBox(); - sliderContainer.setAlignment(Pos.CENTER); - Slider slider = new Slider(isv.MIN, isv.MAX, isv.DEFAULT); - slider.setShowTickMarks(true); - Text value = new Text(Integer.toString(isv.DEFAULT)); - value.getStyleClass().add("slider-value"); - Text label = new Text(isv.LABEL); - label.getStyleClass().add("slider-label"); - final IntegerSV finalIsv = isv; - sliderContainer.getChildren().addAll(slider, value, label); - slider.valueProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Number oldValue, - Number newValue) { - int intValue = newValue.intValue(); - finalIsv.set(intValue); - value.setText(Integer.toString(intValue)); - } - }); - variables.add(new SliderVariableWrapper(slider, isv)); - variableContainers.add(sliderContainer); - } - else if (fType.isAssignableFrom(DoubleSV.class)) { - DebugPrinter.println("Found DoubleSV: " + f.getName()); - DoubleSV dsv = null; - try { - dsv = (DoubleSV) f.get(module); - } - catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - VBox sliderContainer = new VBox(); - sliderContainer.setAlignment(Pos.CENTER); - Slider slider = new Slider(dsv.MIN, dsv.MAX, dsv.DEFAULT); - slider.setShowTickMarks(true); - Text value = new Text(formatter.format(dsv.DEFAULT)); - value.getStyleClass().add("slider-value"); - Text label = new Text(dsv.LABEL); - label.getStyleClass().add("slider-label"); - final DoubleSV finalDsv = dsv; - sliderContainer.getChildren().addAll(slider, value, label); - slider.valueProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Number oldValue, - Number newValue) { - double doubleValue = newValue.doubleValue(); - finalDsv.set(doubleValue); - value.setText(formatter.format(doubleValue)); - } - }); - variables.add(new SliderVariableWrapper(slider, finalDsv)); - variableContainers.add(sliderContainer); - } - else if (fType.isAssignableFrom(BooleanVariable.class)) { - DebugPrinter.println("Found BooleanVariable: " + f.getName()); - BooleanVariable bv = null; - try { - bv = (BooleanVariable) f.get(module); - } - catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - VBox checkBoxContainer = new VBox(); - checkBoxContainer.setAlignment(Pos.CENTER); - CheckBox checkBox = new CheckBox(bv.LABEL); - checkBox.setSelected(bv.DEFAULT); - checkBox.getStyleClass().add("boolean-label"); - final BooleanVariable finalBv = bv; - checkBoxContainer.getChildren().addAll(checkBox); - checkBox.selectedProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, Boolean oldValue, - Boolean newValue) { - boolean booleanValue = newValue.booleanValue(); - finalBv.setValue(booleanValue); - } - }); - variables.add(new BooleanVariableWrapper(checkBox, finalBv)); - variableContainers.add(checkBoxContainer); - } - } - Platform.runLater(() -> { - controlsContainer.getChildren().addAll(variableContainers); - }); - } - - private abstract class VariableWrapper { - public abstract void restoreDefault(); - } - - private class SliderVariableWrapper extends VariableWrapper { - private Slider slider; - private NumberVariable sliderVariable; - - private SliderVariableWrapper(Slider slider, NumberVariable sliderVariable) { - this.slider = slider; - this.sliderVariable = sliderVariable; - } - - public void restoreDefault() { - sliderVariable.restoreDefault(); - slider.setValue(sliderVariable.getValue().doubleValue()); - } - } - - private class BooleanVariableWrapper extends VariableWrapper { - private CheckBox checkBox; - private BooleanVariable booleanVariable; - - private BooleanVariableWrapper(CheckBox checkBox, BooleanVariable booleanVariable) { - this.checkBox = checkBox; - this.booleanVariable = booleanVariable; - } - - public void restoreDefault() { - booleanVariable.restoreDefault(); - checkBox.setSelected(booleanVariable.getValue()); - } - } -} diff --git a/src/edu/stuy/robot/cv/gui/ImageViewer.java b/src/edu/stuy/robot/cv/gui/ImageViewer.java deleted file mode 100644 index 6a5a5ae..0000000 --- a/src/edu/stuy/robot/cv/gui/ImageViewer.java +++ /dev/null @@ -1,58 +0,0 @@ -package edu.stuy.robot.cv.gui; - -import java.util.HashMap; - -import javafx.application.Platform; -import javafx.scene.Scene; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Pane; -import javafx.stage.Stage; - -public class ImageViewer { - - private static ImageViewer instance; - private HashMap windows = new HashMap<>(); - - private ImageViewer() {} - - public static ImageViewer getInstance() { - if (instance == null) { - instance = new ImageViewer(); - } - return instance; - } - - public void showImage(String label, ImageView image) { - Stage imageWindow = windows.get(image); - if (imageWindow != null) { - final Stage finalImageWindow = imageWindow; - Platform.runLater(() -> { - finalImageWindow.toFront(); - }); - } - else { - imageWindow = new Stage(); - double imageWidth = image.getImage().getWidth(); - double imageHeight = image.getImage().getHeight(); - double resizeRatio = (double) 960 / Math.max(imageWidth, imageHeight); - ImageView resizedView = new ImageView(image.getImage()); - // blow up image size to max of 960px - resizedView.setFitWidth(imageWidth * resizeRatio); - resizedView.setFitHeight(imageHeight * resizeRatio); - resizedView.imageProperty().bind(image.imageProperty()); - imageWindow.setTitle(label); - imageWindow.setWidth(imageWidth * resizeRatio); - imageWindow.setHeight(imageHeight * resizeRatio); - imageWindow.setScene(new Scene(new Pane(resizedView))); - imageWindow.setOnCloseRequest((event) -> { - windows.remove(image); - }); - final Stage finalImageWindow = imageWindow; - Platform.runLater(() -> { - finalImageWindow.show(); - }); - windows.put(image, imageWindow); - } - } - -} diff --git a/src/edu/stuy/robot/cv/gui/Main.java b/src/edu/stuy/robot/cv/gui/Main.java deleted file mode 100644 index 1bcd82e..0000000 --- a/src/edu/stuy/robot/cv/gui/Main.java +++ /dev/null @@ -1,145 +0,0 @@ -package edu.stuy.robot.cv.gui; - -import java.io.ByteArrayInputStream; -import java.util.HashMap; - -import org.opencv.core.Mat; -import org.opencv.core.MatOfByte; -import org.opencv.imgcodecs.Imgcodecs; -import org.opencv.videoio.Videoio; - -import edu.stuy.robot.cv.StuyVision; -import edu.stuy.robot.cv.capture.CaptureSource; -import edu.stuy.robot.cv.capture.DeviceCaptureSource; -import edu.stuy.robot.cv.util.DebugPrinter; -import javafx.application.Application; -import javafx.application.Platform; -import javafx.fxml.FXMLLoader; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.SplitPane; -import javafx.scene.control.Tab; -import javafx.scene.control.TabPane; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.input.MouseButton; -import javafx.scene.layout.VBox; -import javafx.scene.text.Text; -import javafx.stage.Stage; - -public class Main extends Application { - private TabPane root; - private Scene scene; - private HashMap tabs = new HashMap(); - private HashMap images = new HashMap(); - - @Override - public void start(Stage primaryStage) { - try { - FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/main.fxml")); - root = loader.load(); - scene = new Scene(root); - scene.getStylesheets().add(getClass().getResource("css/main.css").toString()); - // Initialize ModuleRunner with VisionModuleSuite - VisionModule module = new StuyVision(); - { - FXMLLoader tabLoader = new FXMLLoader(getClass().getResource("fxml/module_main.fxml")); - final SplitPane moduleContainer = tabLoader.load(); - ControlsController controlsController = tabLoader.getController(); - controlsController.setup(module); - tabs.put(module.hashCode(), controlsController); - root.getTabs().add(new Tab(module.getName(), moduleContainer)); - } - Main self = this; - DeviceCaptureSource cs = new DeviceCaptureSource(0); - { - Thread t = new Thread(new Runnable() { - private Mat rawFrame; - private Mat resizedFrame; - @Override - public void run() { - rawFrame = new Mat(); - resizedFrame = new Mat(); - for (;;) { - try { - long start = System.currentTimeMillis(); - Mat frame = cs.readSized(rawFrame, resizedFrame); - module.run(self, frame); - long duration = System.currentTimeMillis() - start; - DebugPrinter.println(module.getName() + ": " + duration + " ms"); - Thread.sleep(1000 / 30); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - }, module.getName() + " Thread"); - t.setDaemon(true); - t.start(); - } - primaryStage.setOnCloseRequest((event) -> quit()); - primaryStage.setTitle("Java Vision GUI"); - primaryStage.setScene(scene); - primaryStage.show(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - private void quit() { - Platform.exit(); - System.exit(0); - } - - public synchronized void postImage(Mat m, String label, VisionModule requester) { - String key = requester.hashCode() + label; - // Convert raw image to PNG - MatOfByte buffer = new MatOfByte(); - Imgcodecs.imencode(".png", m, buffer); - Image image = new Image(new ByteArrayInputStream(buffer.toArray())); - // Check if an ImageFrame already exists - ImageFrame existingFrame = images.get(key); - if (existingFrame == null) { - VBox container = new VBox(); - container.setAlignment(Pos.CENTER); - ImageView imageView = new ImageView(image); - Text text = new Text(label); - text.getStyleClass().add("image-label"); - container.getChildren().addAll(imageView, text); - images.put(key, new ImageFrame(imageView, text)); - Platform.runLater(() -> { - tabs.get(requester.hashCode()).flowPane.getChildren().add(container); - }); - container.setOnMouseClicked((event) -> { - if (event.getButton().equals(MouseButton.PRIMARY)) { - if (event.getClickCount() == 2) { - ImageViewer.getInstance().showImage(label, imageView); - } - } - }); - } - else { - // Update the existing ImageFrame - Platform.runLater(() -> { - existingFrame.imageView.setImage(image); - existingFrame.imageView.toFront(); - existingFrame.label.toFront(); - }); - } - } - - public static void main(String[] args) { - launch(args); - } - - private class ImageFrame { - private ImageView imageView; - private Text label; - - public ImageFrame(ImageView imageView, Text label) { - this.imageView = imageView; - this.label = label; - } - } -} diff --git a/src/edu/stuy/robot/cv/gui/VisionModule.java b/src/edu/stuy/robot/cv/gui/VisionModule.java deleted file mode 100644 index 9d4c723..0000000 --- a/src/edu/stuy/robot/cv/gui/VisionModule.java +++ /dev/null @@ -1,12 +0,0 @@ -package edu.stuy.robot.cv.gui; - -import org.opencv.core.Mat; - -public abstract class VisionModule { - - public abstract void run(Main app, Mat frame); - - public String getName() { - return getClass().getSimpleName(); - } -} diff --git a/src/edu/stuy/util/Gamepad.java b/src/edu/stuy/util/Gamepad.java deleted file mode 100644 index 11a50b0..0000000 --- a/src/edu/stuy/util/Gamepad.java +++ /dev/null @@ -1,294 +0,0 @@ -package edu.stuy.util; - -import edu.wpi.first.wpilibj.Joystick; -import edu.wpi.first.wpilibj.buttons.Button; -import edu.wpi.first.wpilibj.buttons.JoystickButton; - -/** - * Class for both the Logitech Dual Action 2 Gamepad and the Logitech Gamepad - * F310. The Logitech Gamepad F310 must have the switch on the back set to "D" - * for this class to work. This class probably also works with the Logitech - * Wireless Gamepad F710 (untested, but it has the exact same layout as the - * F310). - * - * @author wangmeister - */ -public class Gamepad extends Joystick { - - public Gamepad(int port) { - super(port); - } - - /** - * The left analog stick x-axis. - * - * @return value of left analog x-axis - */ - public double getLeftX() { - return getRawAxis(0); - } - - /** - * The left analog stick y-axis. - * - * @return value of left analog y-axis - */ - public double getLeftY() { - return getRawAxis(1); - } - - /** - * The right analog stick x-axis. - * - * @return value of right analog x-axis - */ - public double getRightX() { - return getRawAxis(2); - } - - /** - * The right analog stick y-axis. - * - * @return value of right analog y-axis - */ - public double getRightY() { - return getRawAxis(3); - } - - /** - * The upper d-pad button. - * - * @return if upper d-pad button is pressed - */ - public boolean getRawDPadUp() { - return getPOV() == 0; - } - - public DPadButton getDPadUp() { - return new DPadButton(this, DPadButton.Direction.UP); - } - - /** - * The lower d-pad button. - * - * @return if the lower d-pad button is pressed - */ - public boolean getRawDPadDown() { - return getPOV() == 180; - } - - public DPadButton getDPadDown() { - return new DPadButton(this, DPadButton.Direction.DOWN); - } - - /** - * The left d-pad button. - * - * @return if the left d-pad button is pressed - */ - public boolean getRawDPadLeft() { - return getPOV() == 270; - } - - public DPadButton getDPadLeft() { - return new DPadButton(this, DPadButton.Direction.LEFT); - } - - /** - * The right d-pad button. - * - * @return if the right d-pad button is pressed - */ - public boolean getRawDPadRight() { - return getPOV() == 90; - } - - public DPadButton getDPadRight() { - return new DPadButton(this, DPadButton.Direction.RIGHT); - } - - /** - * The left bumper. - * - * @return if the left bumper is pressed - */ - public boolean getRawLeftBumper() { - return getRawButton(5); - } - - public JoystickButton getLeftBumper() { - return new JoystickButton(this, 5); - } - - /** - * The right bumper. - * - * @return if the right bumper is pressed - */ - public boolean getRawRightBumper() { - return getRawButton(6); - } - - public JoystickButton getRightBumper() { - return new JoystickButton(this, 6); - } - - /** - * The left trigger. - * - * @return if the left trigger is pressed - */ - public boolean getRawLeftTrigger() { - return getRawButton(7); - } - - public JoystickButton getLeftTrigger() { - return new JoystickButton(this, 7); - } - - /** - * The right trigger. - * - * @return if the right trigger is pressed - */ - public boolean getRawRightTrigger() { - return getRawButton(8); - } - - public JoystickButton getRightTrigger() { - return new JoystickButton(this, 8); - } - - /** - * The left button of the button group. On some gamepads this is X. - * - * @return if the left button is pressed - */ - public boolean getRawLeftButton() { - return getRawButton(1); - } - - public JoystickButton getLeftButton() { - return new JoystickButton(this, 1); - } - - /** - * The bottom button of the button group. On some gamepads this is A. - * - * @return if the bottom button is pressed - */ - public boolean getRawBottomButton() { - return getRawButton(2); - } - - public JoystickButton getBottomButton() { - return new JoystickButton(this, 2); - } - - /** - * The right button of the button group. On some gamepads this is B. - * - * @return if the right button is pressed - */ - public boolean getRawRightButton() { - return getRawButton(3); - } - - public JoystickButton getRightButton() { - return new JoystickButton(this, 3); - } - - /** - * The top button of the button group. On some gamepads this is Y. - * - * @return if the top button is pressed - */ - public boolean getRawTopButton() { - return getRawButton(4); - } - - public JoystickButton getTopButton() { - return new JoystickButton(this, 4); - } - - /** - * The central left button. On some gamepads this is the select button. - * - * @return if the back button is pressed - */ - public boolean getRawSelectButton() { - return getRawButton(9); - } - - public JoystickButton getSelectButton() { - return new JoystickButton(this, 9); - } - - /** - * The central right button. On some gamepads this is the start button. - * - * @return if the start button is pressed - */ - public boolean getRawStartButton() { - return getRawButton(10); - } - - public JoystickButton getStartButton() { - return new JoystickButton(this, 10); - } - - /** - * The click-function of the left analog stick. - * - * @return if the left analog stick is being clicked down - */ - public boolean getRawLeftAnalogButton() { - return getRawButton(11); - } - - public JoystickButton getLeftAnalogButton() { - return new JoystickButton(this, 11); - } - - /** - * The click-function of the right analog stick. - * - * @return if the right analog stick is being clicked down - */ - public boolean getRawRightAnalogButton() { - return getRawButton(12); - } - - public JoystickButton getRightAnalogButton() { - return new JoystickButton(this, 12); - } - - public static class DPadButton extends Button { - public static enum Direction { - UP, DOWN, LEFT, RIGHT - } - - private Gamepad gamepad; - private Direction direction; - - public DPadButton(Gamepad gamepad, Direction direction) { - this.gamepad = gamepad; - this.direction = direction; - } - - public boolean get() { - switch (direction) { - case UP: - return gamepad.getRawDPadUp(); - case DOWN: - return gamepad.getRawDPadDown(); - case LEFT: - return gamepad.getRawDPadLeft(); - case RIGHT: - return gamepad.getRawDPadRight(); - default: // Never reached - return false; - } - } - } -} diff --git a/src/main/deploy/example.txt b/src/main/deploy/example.txt new file mode 100644 index 0000000..70c79b6 --- /dev/null +++ b/src/main/deploy/example.txt @@ -0,0 +1,3 @@ +Files placed in this directory will be deployed to the RoboRIO into the +'deploy' directory in the home folder. Use the 'FileUtilities.getFilePath' wpilib function +to get a proper path relative to the deploy directory. \ No newline at end of file diff --git a/src/main/java/edu/stuy/robot/Main.java b/src/main/java/edu/stuy/robot/Main.java new file mode 100644 index 0000000..4c1116d --- /dev/null +++ b/src/main/java/edu/stuy/robot/Main.java @@ -0,0 +1,22 @@ +package edu.stuy.robot; + +import edu.wpi.first.wpilibj.RobotBase; + +/** + * Do NOT add any static variables to this class, or any initialization at all. + * Unless you know what you are doing, do not modify this file except to + * change the parameter class to the startRobot call. + */ +public final class Main { + private Main() { + } + + /** + * Main initialization function. Do not perform any initialization here. + * + *

If you change your main robot class, change the parameter type. + */ + public static void main(String... args) { + RobotBase.startRobot(Robot::new); + } +} diff --git a/src/edu/stuy/robot/OI.java b/src/main/java/edu/stuy/robot/OI.java similarity index 82% rename from src/edu/stuy/robot/OI.java rename to src/main/java/edu/stuy/robot/OI.java index b571536..4559b18 100644 --- a/src/edu/stuy/robot/OI.java +++ b/src/main/java/edu/stuy/robot/OI.java @@ -15,10 +15,10 @@ import edu.stuy.robot.commands.HoodUpCommand; import edu.stuy.robot.commands.HopperRunCommand; import edu.stuy.robot.commands.JionDriveCommand; -import edu.stuy.robot.commands.RotateToAimCommand; -import edu.stuy.robot.commands.RotateToAimMultiCommand; +//import edu.stuy.robot.commands.RotateToAimCommand; +//import edu.stuy.robot.commands.RotateToAimMultiCommand; import edu.stuy.robot.commands.RunInLowGearCommand; -import edu.stuy.robot.commands.SetupForShotCommand; +//import edu.stuy.robot.commands.SetupForShotCommand; import edu.stuy.robot.commands.ShooterHopperBackwardsCommand; import edu.stuy.robot.commands.ShooterHopperStopCommand; import edu.stuy.robot.commands.ShooterSetLayupCommand; @@ -77,20 +77,20 @@ public OI() { driverGamepad.getLeftBumper().whenPressed(new FlashlightOnCommand()); driverGamepad.getLeftBumper().whenReleased(new FlashlightOffCommand()); - // CV controls - GyroRotationalCommand singleRotationTrigger = new RotateToAimCommand(false, 1.7); - singleRotationTrigger.setUseSignalLights(true); - driverGamepad.getRightTrigger().whenPressed(new RunInLowGearCommand(singleRotationTrigger)); - - driverGamepad.getBottomButton().whenPressed(new RunInLowGearCommand(new RotateToAimMultiCommand())); - driverGamepad.getTopButton().whenPressed(new RunInLowGearCommand(new SetupForShotCommand())); - GyroRotationalCommand singleRotationLeft = new RotateToAimCommand(false, 1.7); - singleRotationLeft.setUseSignalLights(true); - GyroRotationalCommand singleRotationRight = new RotateToAimCommand(false, 1.7); - singleRotationRight.setUseSignalLights(true); - driverGamepad.getRightButton().whenPressed(new RunInLowGearCommand(singleRotationLeft)); - driverGamepad.getLeftButton().whenPressed(new RunInLowGearCommand(singleRotationRight)); - +// // CV controls +// GyroRotationalCommand singleRotationTrigger = new RotateToAimCommand(false, 1.7); +// singleRotationTrigger.setUseSignalLights(true); +// driverGamepad.getRightTrigger().whenPressed(new RunInLowGearCommand(singleRotationTrigger)); +// +// driverGamepad.getBottomButton().whenPressed(new RunInLowGearCommand(new RotateToAimMultiCommand())); +// driverGamepad.getTopButton().whenPressed(new RunInLowGearCommand(new SetupForShotCommand())); +// GyroRotationalCommand singleRotationLeft = new RotateToAimCommand(false, 1.7); +// singleRotationLeft.setUseSignalLights(true); +// GyroRotationalCommand singleRotationRight = new RotateToAimCommand(false, 1.7); +// singleRotationRight.setUseSignalLights(true); +// driverGamepad.getRightButton().whenPressed(new RunInLowGearCommand(singleRotationLeft)); +// driverGamepad.getLeftButton().whenPressed(new RunInLowGearCommand(singleRotationRight)); +// // OPERATOR BINDINGS operatorGamepad.getLeftTrigger().whileHeld(new HopperRunCommand(true)); operatorGamepad.getLeftBumper().whileHeld(new HopperRunCommand(false)); diff --git a/src/edu/stuy/robot/Robot.java b/src/main/java/edu/stuy/robot/Robot.java similarity index 95% rename from src/edu/stuy/robot/Robot.java rename to src/main/java/edu/stuy/robot/Robot.java index 73c05b4..335d065 100644 --- a/src/edu/stuy/robot/Robot.java +++ b/src/main/java/edu/stuy/robot/Robot.java @@ -7,7 +7,7 @@ import static edu.stuy.robot.RobotMap.SIGNAL_LIGHT_YELLOW_PORT; import static edu.stuy.robot.RobotMap.YUBIN_ID; -import edu.stuy.robot.commands.auton.CrossObstacleThenShootCommand; +//import edu.stuy.robot.commands.auton.CrossObstacleThenShootCommand; import edu.stuy.robot.commands.auton.GoOverMoatCommand; import edu.stuy.robot.commands.auton.GoOverRampartsCommand; import edu.stuy.robot.commands.auton.GoOverRockWallBackwardsCommand; @@ -16,7 +16,7 @@ import edu.stuy.robot.commands.auton.PassChevalCommand; import edu.stuy.robot.commands.auton.PassPortcullisCommand; import edu.stuy.robot.commands.auton.ReachObstacleCommand; -import edu.stuy.robot.cv.StuyVision; +//import edu.stuy.robot.cv.StuyVision; import edu.stuy.robot.subsystems.Acquirer; import edu.stuy.robot.subsystems.Drivetrain; import edu.stuy.robot.subsystems.DropDown; @@ -69,7 +69,7 @@ public class Robot extends IterativeRobot { private double autonStartTime; private static boolean debugMode; - public static StuyVision vision; +// public static StuyVision vision; public static BoolBox stopAutoMovement = new BoolBox(false); // Used to not waste a ball in a shooting auton if CV doesn't @@ -120,7 +120,7 @@ public void robotInit() { flashlight = new Flashlight(); oi = new OI(); - vision = new StuyVision(); +// vision = new StuyVision(); drivetrain.setDrivetrainBrakeMode(true); shooter.setShooterBrakeMode(false); @@ -199,9 +199,13 @@ private void setupShootChooser() { public void disabledPeriodic() { Scheduler.getInstance().run(); + oi.driverGamepad.resetGamepadType(); + oi.operatorGamepad.resetGamepadType(); } public void autonomousInit() { + oi.driverGamepad.resetGamepadType(); + oi.operatorGamepad.resetGamepadType(); try { Robot.cvSignalLight.stayOff(); debugMode = (Boolean) debugChooser.getSelected(); @@ -211,7 +215,7 @@ public void autonomousInit() { boolean shoot = (Boolean) autonShootChooser.getSelected(); selectedAutonomousCommand = selected; if (shoot) { - autonomousCommand = new CrossObstacleThenShootCommand(selectedAutonomousCommand, autonPosition); +// autonomousCommand = new CrossObstacleThenShootCommand(selectedAutonomousCommand, autonPosition); } else { autonomousCommand = selectedAutonomousCommand; } @@ -252,6 +256,8 @@ public void autonomousPeriodic() { } public void teleopInit() { + oi.operatorGamepad.resetGamepadType(); + oi.driverGamepad.resetGamepadType(); try { // This makes sure that the autonomous stops running when // teleop starts running. If you want the autonomous to diff --git a/src/edu/stuy/robot/RobotMap.java b/src/main/java/edu/stuy/robot/RobotMap.java similarity index 93% rename from src/edu/stuy/robot/RobotMap.java rename to src/main/java/edu/stuy/robot/RobotMap.java index 1297159..f822652 100644 --- a/src/edu/stuy/robot/RobotMap.java +++ b/src/main/java/edu/stuy/robot/RobotMap.java @@ -12,16 +12,16 @@ public interface RobotMap { int DRIVER_GAMEPAD = 0; int OPERATOR_GAMEPAD = 1; - // Drivetrain CANTalon channels - int FRONT_RIGHT_MOTOR_CHANNEL = 1; + // Drivetrain TalonSRX channels + int FRONT_RIGHT_MOTOR_CHANNEL = 3; int REAR_RIGHT_MOTOR_CHANNEL = 2; - int REAR_LEFT_MOTOR_CHANNEL = 3; - int FRONT_LEFT_MOTOR_CHANNEL = 4; + int REAR_LEFT_MOTOR_CHANNEL = 4; + int FRONT_LEFT_MOTOR_CHANNEL = 1; - // CANTalon channels for other subsystems + // TalonSRX channels for other subsystems int HOPPER_MOTOR_CHANNEL = 5; int ACQUIRER_MOTOR_CHANNEL = 6; - int SHOOTER_MOTOR_CHANNEL = 7; + int SHOOTER_MOTOR_CHANNEL = 13; int DROPDOWN_MOTOR_CHANNEL = 8; // Solenoid ports diff --git a/src/edu/stuy/robot/commands/AcquirerAcquireCommand.java b/src/main/java/edu/stuy/robot/commands/AcquirerAcquireCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/AcquirerAcquireCommand.java rename to src/main/java/edu/stuy/robot/commands/AcquirerAcquireCommand.java diff --git a/src/edu/stuy/robot/commands/AcquirerDeacquireCommand.java b/src/main/java/edu/stuy/robot/commands/AcquirerDeacquireCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/AcquirerDeacquireCommand.java rename to src/main/java/edu/stuy/robot/commands/AcquirerDeacquireCommand.java diff --git a/src/edu/stuy/robot/commands/AcquirerStopCommand.java b/src/main/java/edu/stuy/robot/commands/AcquirerStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/AcquirerStopCommand.java rename to src/main/java/edu/stuy/robot/commands/AcquirerStopCommand.java diff --git a/src/edu/stuy/robot/commands/AutoMovementCommand.java b/src/main/java/edu/stuy/robot/commands/AutoMovementCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/AutoMovementCommand.java rename to src/main/java/edu/stuy/robot/commands/AutoMovementCommand.java diff --git a/src/main/java/edu/stuy/robot/commands/CVReadAndPrintCommand.java b/src/main/java/edu/stuy/robot/commands/CVReadAndPrintCommand.java new file mode 100644 index 0000000..098fba3 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/CVReadAndPrintCommand.java @@ -0,0 +1,65 @@ +//package edu.stuy.robot.commands; +// +//import java.util.Arrays; +// +//import edu.stuy.robot.Robot; +//import edu.stuy.robot.cv.StuyVision; +//import edu.wpi.first.wpilibj.command.Command; +//import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +// +///** +// * +// */ +//public class CVReadAndPrintCommand extends Command { +// boolean tryToSaveFile; +// public CVReadAndPrintCommand() { +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// } +// public CVReadAndPrintCommand(boolean save) { +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// tryToSaveFile = save; +// } +// +// // Called just before this Command runs the first time +// protected void initialize() { +// try { +// long start = System.currentTimeMillis(); +// double[] cvReading = null; +// cvReading = Robot.vision.processImage(Robot.isDebugModeOn() && tryToSaveFile); +// System.out.println("\n\n\n\n\n\n\n\n\n\nprocessImage took " + (System.currentTimeMillis() - start) + "ms"); +// System.out.println(new StuyVision.Report(cvReading)); +// boolean canProceed = cvReading != null; +// SmartDashboard.putString("cv-reading", Arrays.toString(cvReading)); +// if (canProceed) { +// double desiredAngle = StuyVision.frameXPxToDegrees(cvReading[0]); +// SmartDashboard.putNumber("cv-angle", desiredAngle); +// System.out.println("Desired Angle Delta: " + desiredAngle); +// } +// SmartDashboard.putBoolean("cv-visible", canProceed); +// } catch (Exception e) { +// System.err.println("\n\n\n\nGeneric exception caught in CVReadAndPrintCommand:"); +// e.printStackTrace(); +// System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); +// } +// } +// +// // Called repeatedly when this Command is scheduled to run +// protected void execute() { +// } +// +// // Make this return true when this Command no longer needs to run execute() +// protected boolean isFinished() { +// return true; +// } +// +// // Called once after isFinished returns true +// protected void end() { +// } +// +// // Called when another command which requires one or more of the same +// // subsystems is scheduled to run +// protected void interrupted() { +// } +//} diff --git a/src/edu/stuy/robot/commands/ChangeGearCommand.java b/src/main/java/edu/stuy/robot/commands/ChangeGearCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ChangeGearCommand.java rename to src/main/java/edu/stuy/robot/commands/ChangeGearCommand.java diff --git a/src/edu/stuy/robot/commands/DisableAutoGearShiftCommand.java b/src/main/java/edu/stuy/robot/commands/DisableAutoGearShiftCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DisableAutoGearShiftCommand.java rename to src/main/java/edu/stuy/robot/commands/DisableAutoGearShiftCommand.java diff --git a/src/main/java/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java b/src/main/java/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java new file mode 100644 index 0000000..b3fbc31 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/DriveToCourtyardRangeCommand.java @@ -0,0 +1,34 @@ +//package edu.stuy.robot.commands; +// +//import static edu.stuy.robot.RobotMap.COURTYARD_SHOOTING_DISTANCE; +// +//import edu.stuy.robot.Robot; +//import edu.stuy.robot.cv.StuyVision; +// +///** +// * +// */ +//public class DriveToCourtyardRangeCommand extends EncoderDrivingCommand { +// +// public DriveToCourtyardRangeCommand() { +// super(Robot.stopAutoMovement); +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// requires(Robot.drivetrain); +// } +// +// protected void setInchesToMove() { +// double[] cvReading = Robot.vision.processImage(); +// if (cvReading != null) { +// double curDistance = StuyVision.findBotDistanceToGoal(cvReading[1]); +// initialInchesToMove = curDistance - COURTYARD_SHOOTING_DISTANCE; +// } else { +// // CV failed! +// cancelCommand = true; +// } +// System.out.println(new StuyVision.Report(cvReading)); +// if (cvReading != null) { +// System.out.println(StuyVision.findBotDistanceToGoal(cvReading[1])); +// } +// } +//} diff --git a/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeCommand.java b/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeCommand.java new file mode 100644 index 0000000..49e914e --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeCommand.java @@ -0,0 +1,35 @@ +//package edu.stuy.robot.commands; +// +//import static edu.stuy.robot.RobotMap.LAYUP_SHOOTING_DISTANCE; +// +//import edu.stuy.robot.Robot; +//import edu.stuy.robot.cv.StuyVision; +//import edu.stuy.util.BoolBox; +// +///** +// * +// */ +//public class DriveToLayupRangeCommand extends EncoderDrivingCommand { +// +// public DriveToLayupRangeCommand() { +// super(Robot.stopAutoMovement); +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// requires(Robot.drivetrain); +// } +// +// protected void setInchesToMove() { +// double[] cvReading = Robot.vision.processImage(); +// if (cvReading != null) { +// double curDistance = StuyVision.findBotDistanceToGoal(cvReading[1]); +// initialInchesToMove = curDistance - LAYUP_SHOOTING_DISTANCE; +// } else { +// // CV failed! +// cancelCommand = true; +// } +// System.out.println(new StuyVision.Report(cvReading)); +// if (cvReading != null) { +// System.out.println(StuyVision.findBotDistanceToGoal(cvReading[1])); +// } +// } +//} diff --git a/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java b/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java new file mode 100644 index 0000000..fad94a2 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/DriveToLayupRangeMultiCommand.java @@ -0,0 +1,35 @@ +//package edu.stuy.robot.commands; +// +//import edu.wpi.first.wpilibj.command.CommandGroup; +// +///** +// * +// */ +//public class DriveToLayupRangeMultiCommand extends CommandGroup { +// +// public DriveToLayupRangeMultiCommand() { +// // Add Commands here: +// // e.g. addSequential(new Command1()); +// // addSequential(new Command2()); +// // these will run in order. +// +// // To run multiple commands at the same time, +// // use addParallel() +// // e.g. addParallel(new Command1()); +// // addSequential(new Command2()); +// // Command1 and Command2 will run in parallel. +// +// // A command group will require all of the subsystems that each member +// // would require. +// // e.g. if Command1 requires chassis, and Command2 requires arm, +// // a CommandGroup containing them would require both the chassis and the +// // arm. +// +// // This is a janky way of doing this. Urgency calls. +// +// // First movement: +// addSequential(new DriveToLayupRangeCommand()); +// // Refine to account for mistakes: +// addSequential(new DriveToLayupRangeCommand()); +// } +//} diff --git a/src/edu/stuy/robot/commands/DrivetrainDriveStraightCommand.java b/src/main/java/edu/stuy/robot/commands/DrivetrainDriveStraightCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DrivetrainDriveStraightCommand.java rename to src/main/java/edu/stuy/robot/commands/DrivetrainDriveStraightCommand.java diff --git a/src/edu/stuy/robot/commands/DrivetrainStopCommand.java b/src/main/java/edu/stuy/robot/commands/DrivetrainStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DrivetrainStopCommand.java rename to src/main/java/edu/stuy/robot/commands/DrivetrainStopCommand.java diff --git a/src/edu/stuy/robot/commands/DrivetrainTankDriveCommand.java b/src/main/java/edu/stuy/robot/commands/DrivetrainTankDriveCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DrivetrainTankDriveCommand.java rename to src/main/java/edu/stuy/robot/commands/DrivetrainTankDriveCommand.java diff --git a/src/edu/stuy/robot/commands/DropDownDefaultCommand.java b/src/main/java/edu/stuy/robot/commands/DropDownDefaultCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DropDownDefaultCommand.java rename to src/main/java/edu/stuy/robot/commands/DropDownDefaultCommand.java diff --git a/src/edu/stuy/robot/commands/DropDownMoveCommand.java b/src/main/java/edu/stuy/robot/commands/DropDownMoveCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/DropDownMoveCommand.java rename to src/main/java/edu/stuy/robot/commands/DropDownMoveCommand.java diff --git a/src/edu/stuy/robot/commands/EnableAutoGearShiftCommand.java b/src/main/java/edu/stuy/robot/commands/EnableAutoGearShiftCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/EnableAutoGearShiftCommand.java rename to src/main/java/edu/stuy/robot/commands/EnableAutoGearShiftCommand.java diff --git a/src/edu/stuy/robot/commands/EncoderDrivingCommand.java b/src/main/java/edu/stuy/robot/commands/EncoderDrivingCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/EncoderDrivingCommand.java rename to src/main/java/edu/stuy/robot/commands/EncoderDrivingCommand.java diff --git a/src/edu/stuy/robot/commands/FlashlightOffCommand.java b/src/main/java/edu/stuy/robot/commands/FlashlightOffCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/FlashlightOffCommand.java rename to src/main/java/edu/stuy/robot/commands/FlashlightOffCommand.java diff --git a/src/edu/stuy/robot/commands/FlashlightOnCommand.java b/src/main/java/edu/stuy/robot/commands/FlashlightOnCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/FlashlightOnCommand.java rename to src/main/java/edu/stuy/robot/commands/FlashlightOnCommand.java diff --git a/src/edu/stuy/robot/commands/FlashlightToggleCommand.java b/src/main/java/edu/stuy/robot/commands/FlashlightToggleCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/FlashlightToggleCommand.java rename to src/main/java/edu/stuy/robot/commands/FlashlightToggleCommand.java diff --git a/src/edu/stuy/robot/commands/GyroRotationalCommand.java b/src/main/java/edu/stuy/robot/commands/GyroRotationalCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/GyroRotationalCommand.java rename to src/main/java/edu/stuy/robot/commands/GyroRotationalCommand.java diff --git a/src/edu/stuy/robot/commands/HighGearCommand.java b/src/main/java/edu/stuy/robot/commands/HighGearCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/HighGearCommand.java rename to src/main/java/edu/stuy/robot/commands/HighGearCommand.java diff --git a/src/edu/stuy/robot/commands/HoodDownCommand.java b/src/main/java/edu/stuy/robot/commands/HoodDownCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/HoodDownCommand.java rename to src/main/java/edu/stuy/robot/commands/HoodDownCommand.java diff --git a/src/edu/stuy/robot/commands/HoodUpCommand.java b/src/main/java/edu/stuy/robot/commands/HoodUpCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/HoodUpCommand.java rename to src/main/java/edu/stuy/robot/commands/HoodUpCommand.java diff --git a/src/edu/stuy/robot/commands/HopperRunCommand.java b/src/main/java/edu/stuy/robot/commands/HopperRunCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/HopperRunCommand.java rename to src/main/java/edu/stuy/robot/commands/HopperRunCommand.java diff --git a/src/edu/stuy/robot/commands/HopperStopCommand.java b/src/main/java/edu/stuy/robot/commands/HopperStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/HopperStopCommand.java rename to src/main/java/edu/stuy/robot/commands/HopperStopCommand.java diff --git a/src/edu/stuy/robot/commands/JionDriveCommand.java b/src/main/java/edu/stuy/robot/commands/JionDriveCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/JionDriveCommand.java rename to src/main/java/edu/stuy/robot/commands/JionDriveCommand.java diff --git a/src/edu/stuy/robot/commands/LowGearCommand.java b/src/main/java/edu/stuy/robot/commands/LowGearCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/LowGearCommand.java rename to src/main/java/edu/stuy/robot/commands/LowGearCommand.java diff --git a/src/edu/stuy/robot/commands/ResetForceStopCommand.java b/src/main/java/edu/stuy/robot/commands/ResetForceStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ResetForceStopCommand.java rename to src/main/java/edu/stuy/robot/commands/ResetForceStopCommand.java diff --git a/src/edu/stuy/robot/commands/RotateDegreesGyroCommand.java b/src/main/java/edu/stuy/robot/commands/RotateDegreesGyroCommand.java similarity index 95% rename from src/edu/stuy/robot/commands/RotateDegreesGyroCommand.java rename to src/main/java/edu/stuy/robot/commands/RotateDegreesGyroCommand.java index c3f3c39..2395246 100644 --- a/src/edu/stuy/robot/commands/RotateDegreesGyroCommand.java +++ b/src/main/java/edu/stuy/robot/commands/RotateDegreesGyroCommand.java @@ -22,7 +22,7 @@ public RotateDegreesGyroCommand(double angle) { } protected void setDesiredAngle() { - desiredAngle = notSet ? SmartDashboard.getNumber("gyro-rotate-degs") : _angle; + desiredAngle = notSet ? SmartDashboard.getNumber("gyro-rotate-degs", 0) : _angle; } protected void onEnd() {} diff --git a/src/main/java/edu/stuy/robot/commands/RotateToAimCommand.java b/src/main/java/edu/stuy/robot/commands/RotateToAimCommand.java new file mode 100644 index 0000000..54b5309 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/RotateToAimCommand.java @@ -0,0 +1,50 @@ +//package edu.stuy.robot.commands; +// +//import java.util.Arrays; +// +//import edu.stuy.robot.Robot; +//import edu.stuy.robot.cv.StuyVision; +//import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; +// +///** +// * +// */ +//public class RotateToAimCommand extends GyroRotationalCommand { +// +// public RotateToAimCommand() { +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// super(Robot.stopAutoMovement, false); +// } +// +// public RotateToAimCommand(boolean gentle) { +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// super(Robot.stopAutoMovement, gentle); +// } +// +// public RotateToAimCommand(boolean gentle, double tolerance) { +// // Use requires() here to declare subsystem dependencies +// // eg. requires(chassis); +// super(Robot.stopAutoMovement, gentle, tolerance); +// } +// +// private double[] cvReading; +// +// protected void setDesiredAngle() { +// cvReading = Robot.vision.processImage(); +// canProceed = cvReading != null; +// SmartDashboard.putString("cv-reading", Arrays.toString(cvReading)); +// if (canProceed) { +// desiredAngle = StuyVision.frameXPxToDegrees(cvReading[0]); +// SmartDashboard.putNumber("cv-angle", desiredAngle); +// } +// SmartDashboard.putBoolean("cv-visible", canProceed); +// // For auton: +// Robot.cvFoundGoal = canProceed; +// } +// +// protected void onEnd() { +// System.out.println(new StuyVision.Report(cvReading)); +// } +//} diff --git a/src/main/java/edu/stuy/robot/commands/RotateToAimMultiCommand.java b/src/main/java/edu/stuy/robot/commands/RotateToAimMultiCommand.java new file mode 100644 index 0000000..b03927b --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/RotateToAimMultiCommand.java @@ -0,0 +1,27 @@ +//package edu.stuy.robot.commands; +// +//import edu.wpi.first.wpilibj.command.CommandGroup; +// +///** +// * +// */ +//public class RotateToAimMultiCommand extends CommandGroup { +// +// public RotateToAimMultiCommand() { +// // First rotation: +// addSequential(new RotateToAimCommand()); +// // Refine: +// GyroRotationalCommand finalRot = new RotateToAimCommand(true); +// finalRot.setUseSignalLights(true); +// addSequential(finalRot); +// } +// +// public RotateToAimMultiCommand(double tolerance) { +// // First rotation: +// addSequential(new RotateToAimCommand(false, tolerance)); +// // Refine: +// GyroRotationalCommand finalRot = new RotateToAimCommand(true); +// finalRot.setUseSignalLights(true); +// addSequential(finalRot); +// } +//} diff --git a/src/edu/stuy/robot/commands/RunInLowGearCommand.java b/src/main/java/edu/stuy/robot/commands/RunInLowGearCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/RunInLowGearCommand.java rename to src/main/java/edu/stuy/robot/commands/RunInLowGearCommand.java diff --git a/src/main/java/edu/stuy/robot/commands/SetupForShotCommand.java b/src/main/java/edu/stuy/robot/commands/SetupForShotCommand.java new file mode 100644 index 0000000..3d3ade5 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/SetupForShotCommand.java @@ -0,0 +1,41 @@ +//package edu.stuy.robot.commands; +// +//import edu.wpi.first.wpilibj.command.CommandGroup; +// +///** +// * +// */ +//public class SetupForShotCommand extends CommandGroup { +// +// public SetupForShotCommand() { +// // Add Commands here: +// // e.g. addSequential(new Command1()); +// // addSequential(new Command2()); +// // these will run in order. +// +// // To run multiple commands at the same time, +// // use addParallel() +// // e.g. addParallel(new Command1()); +// // addSequential(new Command2()); +// // Command1 and Command2 will run in parallel. +// +// // A command group will require all of the subsystems that each member +// // would require. +// // e.g. if Command1 requires chassis, and Command2 requires arm, +// // a CommandGroup containing them would require both the chassis and the +// // arm. +// +// addSequential(new ResetForceStopCommand()); +// +// addSequential(new RotateToAimCommand(false, 1.5)); // Coarse rotation +// addSequential(new RotateToAimCommand(true)); // Refining rotation +// +// addSequential(new DriveToLayupRangeCommand()); +// +// GyroRotationalCommand finalRotation = new RotateToAimCommand(false, 1.7); +// finalRotation.setUseSignalLights(true); +// addSequential(finalRotation); +// +// addSequential(new ResetForceStopCommand()); +// } +//} diff --git a/src/edu/stuy/robot/commands/ShooterBackwardsCommand.java b/src/main/java/edu/stuy/robot/commands/ShooterBackwardsCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterBackwardsCommand.java rename to src/main/java/edu/stuy/robot/commands/ShooterBackwardsCommand.java diff --git a/src/edu/stuy/robot/commands/ShooterHopperBackwardsCommand.java b/src/main/java/edu/stuy/robot/commands/ShooterHopperBackwardsCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterHopperBackwardsCommand.java rename to src/main/java/edu/stuy/robot/commands/ShooterHopperBackwardsCommand.java diff --git a/src/edu/stuy/robot/commands/ShooterHopperStopCommand.java b/src/main/java/edu/stuy/robot/commands/ShooterHopperStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterHopperStopCommand.java rename to src/main/java/edu/stuy/robot/commands/ShooterHopperStopCommand.java diff --git a/src/edu/stuy/robot/commands/ShooterLowerSpeed.java b/src/main/java/edu/stuy/robot/commands/ShooterLowerSpeed.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterLowerSpeed.java rename to src/main/java/edu/stuy/robot/commands/ShooterLowerSpeed.java diff --git a/src/edu/stuy/robot/commands/ShooterRaiseSpeed.java b/src/main/java/edu/stuy/robot/commands/ShooterRaiseSpeed.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterRaiseSpeed.java rename to src/main/java/edu/stuy/robot/commands/ShooterRaiseSpeed.java diff --git a/src/edu/stuy/robot/commands/ShooterSetLayupCommand.java b/src/main/java/edu/stuy/robot/commands/ShooterSetLayupCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterSetLayupCommand.java rename to src/main/java/edu/stuy/robot/commands/ShooterSetLayupCommand.java diff --git a/src/edu/stuy/robot/commands/ShooterSetMaxSpeed.java b/src/main/java/edu/stuy/robot/commands/ShooterSetMaxSpeed.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterSetMaxSpeed.java rename to src/main/java/edu/stuy/robot/commands/ShooterSetMaxSpeed.java diff --git a/src/edu/stuy/robot/commands/ShooterSetOutWorksSpeed.java b/src/main/java/edu/stuy/robot/commands/ShooterSetOutWorksSpeed.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterSetOutWorksSpeed.java rename to src/main/java/edu/stuy/robot/commands/ShooterSetOutWorksSpeed.java diff --git a/src/edu/stuy/robot/commands/ShooterStopCommand.java b/src/main/java/edu/stuy/robot/commands/ShooterStopCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/ShooterStopCommand.java rename to src/main/java/edu/stuy/robot/commands/ShooterStopCommand.java diff --git a/src/edu/stuy/robot/commands/auton/AlignWithWallCommand.java b/src/main/java/edu/stuy/robot/commands/auton/AlignWithWallCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/AlignWithWallCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/AlignWithWallCommand.java diff --git a/src/edu/stuy/robot/commands/auton/AutonHopperCommand.java b/src/main/java/edu/stuy/robot/commands/auton/AutonHopperCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/AutonHopperCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/AutonHopperCommand.java diff --git a/src/main/java/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java b/src/main/java/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java new file mode 100644 index 0000000..20f8054 --- /dev/null +++ b/src/main/java/edu/stuy/robot/commands/auton/CrossObstacleThenShootCommand.java @@ -0,0 +1,53 @@ +//package edu.stuy.robot.commands.auton; +// +//import edu.stuy.robot.commands.DrivetrainStopCommand; +//import edu.stuy.robot.commands.FlashlightOnCommand; +//import edu.stuy.robot.commands.LowGearCommand; +//import edu.stuy.robot.commands.SetupForShotCommand; +//import edu.stuy.robot.commands.ShooterSetLayupCommand; +//import edu.wpi.first.wpilibj.command.Command; +//import edu.wpi.first.wpilibj.command.CommandGroup; +// +///** +// * +// */ +//public class CrossObstacleThenShootCommand extends CommandGroup { +// +// public CrossObstacleThenShootCommand(Command obstacle, int position) { +// // Add Commands here: +// // e.g. addSequential(new Command1()); +// // addSequential(new Command2()); +// // these will run in order. +// +// // To run multiple commands at the same time, +// // use addParallel() +// // e.g. addParallel(new Command1()); +// // addSequential(new Command2()); +// // Command1 and Command2 will run in parallel. +// +// // A command group will require all of the subsystems that each member +// // would require. +// // e.g. if Command1 requires chassis, and Command2 requires arm, +// // a CommandGroup containing them would require both the chassis and the +// // arm. +// +// addSequential(obstacle); +// addSequential(new LowGearCommand()); +// addSequential(new DrivetrainStopCommand()); +// addParallel(new ShooterSetLayupCommand()); +// addSequential(new DropDownMoveToAngleCommand(0), 2.0); +// if (position != 3 && position != 4) { +// // RotateDrivetrainCommand will, at runtime, decide angle +// // based on Robot.autonPositionChooser.getSelected() +// addSequential(new RotateDrivetrainCommand()); +// } +// addParallel(new FlashlightOnCommand()); // So we can see where it is aiming +// addSequential(new SetupForShotCommand()); +// +// // The following only runs the hopper if goal was in frame for CV +// addSequential(new HandleAutonShotCommand(), 3.0); +// +// // Drivetrain returns to high gear in teleopInit, where +// // also shooter, hopper and flashlight are turned off. +// } +//} diff --git a/src/edu/stuy/robot/commands/auton/DriveBackwardCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveBackwardCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/DriveBackwardCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveBackwardCommand.java diff --git a/src/edu/stuy/robot/commands/auton/DriveForwardCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveForwardCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/DriveForwardCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveForwardCommand.java diff --git a/src/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java similarity index 91% rename from src/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java index a5adc77..b06df29 100644 --- a/src/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java +++ b/src/main/java/edu/stuy/robot/commands/auton/DriveOverMoatCommand.java @@ -9,7 +9,7 @@ public class DriveOverMoatCommand extends DriveForwardCommand { private static final double SPEED = 0.9; public DriveOverMoatCommand() { - super(SmartDashboard.getNumber("Moat"), MAX_TIME_IN_SECONDS, SPEED); + super(SmartDashboard.getNumber("Moat", 0), MAX_TIME_IN_SECONDS, SPEED); } @Override diff --git a/src/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java similarity index 90% rename from src/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java index d30602f..d0ca283 100644 --- a/src/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java +++ b/src/main/java/edu/stuy/robot/commands/auton/DriveOverRampartsCommand.java @@ -9,7 +9,7 @@ public class DriveOverRampartsCommand extends DriveForwardCommand { private static final double SPEED = 1.0; public DriveOverRampartsCommand() { - super(SmartDashboard.getNumber("Ramparts"), MAX_TIME_IN_SECONDS, SPEED); + super(SmartDashboard.getNumber("Ramparts", 0), MAX_TIME_IN_SECONDS, SPEED); } @Override diff --git a/src/edu/stuy/robot/commands/auton/DriveOverRockWallCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveOverRockWallCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/DriveOverRockWallCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveOverRockWallCommand.java diff --git a/src/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java similarity index 91% rename from src/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java index b674cd1..b18acb5 100644 --- a/src/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java +++ b/src/main/java/edu/stuy/robot/commands/auton/DriveOverRoughTerrainCommand.java @@ -9,7 +9,7 @@ public class DriveOverRoughTerrainCommand extends DriveForwardCommand { private static final double SPEED = 1.0; public DriveOverRoughTerrainCommand() { - super(SmartDashboard.getNumber("Rough"), MAX_TIME_IN_SECONDS, SPEED); + super(SmartDashboard.getNumber("Rough", 0), MAX_TIME_IN_SECONDS, SPEED); } @Override diff --git a/src/edu/stuy/robot/commands/auton/DropDownMoveToAngleCommand.java b/src/main/java/edu/stuy/robot/commands/auton/DropDownMoveToAngleCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/DropDownMoveToAngleCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/DropDownMoveToAngleCommand.java diff --git a/src/edu/stuy/robot/commands/auton/GoOverMoatCommand.java b/src/main/java/edu/stuy/robot/commands/auton/GoOverMoatCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/GoOverMoatCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/GoOverMoatCommand.java diff --git a/src/edu/stuy/robot/commands/auton/GoOverRampartsCommand.java b/src/main/java/edu/stuy/robot/commands/auton/GoOverRampartsCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/GoOverRampartsCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/GoOverRampartsCommand.java diff --git a/src/edu/stuy/robot/commands/auton/GoOverRockWallBackwardsCommand.java b/src/main/java/edu/stuy/robot/commands/auton/GoOverRockWallBackwardsCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/GoOverRockWallBackwardsCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/GoOverRockWallBackwardsCommand.java diff --git a/src/edu/stuy/robot/commands/auton/GoOverRockWallCommand.java b/src/main/java/edu/stuy/robot/commands/auton/GoOverRockWallCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/GoOverRockWallCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/GoOverRockWallCommand.java diff --git a/src/edu/stuy/robot/commands/auton/GoOverRoughTerrainCommand.java b/src/main/java/edu/stuy/robot/commands/auton/GoOverRoughTerrainCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/GoOverRoughTerrainCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/GoOverRoughTerrainCommand.java diff --git a/src/edu/stuy/robot/commands/auton/HandleAutonShotCommand.java b/src/main/java/edu/stuy/robot/commands/auton/HandleAutonShotCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/HandleAutonShotCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/HandleAutonShotCommand.java diff --git a/src/edu/stuy/robot/commands/auton/PassChevalCommand.java b/src/main/java/edu/stuy/robot/commands/auton/PassChevalCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/PassChevalCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/PassChevalCommand.java diff --git a/src/edu/stuy/robot/commands/auton/PassPortcullisCommand.java b/src/main/java/edu/stuy/robot/commands/auton/PassPortcullisCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/PassPortcullisCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/PassPortcullisCommand.java diff --git a/src/edu/stuy/robot/commands/auton/ReachObstacleCommand.java b/src/main/java/edu/stuy/robot/commands/auton/ReachObstacleCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/ReachObstacleCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/ReachObstacleCommand.java diff --git a/src/edu/stuy/robot/commands/auton/RotateDrivetrainCommand.java b/src/main/java/edu/stuy/robot/commands/auton/RotateDrivetrainCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/RotateDrivetrainCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/RotateDrivetrainCommand.java diff --git a/src/edu/stuy/robot/commands/auton/SetDistanceFromWallCommand.java b/src/main/java/edu/stuy/robot/commands/auton/SetDistanceFromWallCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/SetDistanceFromWallCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/SetDistanceFromWallCommand.java diff --git a/src/edu/stuy/robot/commands/auton/ShootOuterworkCommand.java b/src/main/java/edu/stuy/robot/commands/auton/ShootOuterworkCommand.java similarity index 100% rename from src/edu/stuy/robot/commands/auton/ShootOuterworkCommand.java rename to src/main/java/edu/stuy/robot/commands/auton/ShootOuterworkCommand.java diff --git a/src/main/java/edu/stuy/robot/cv/StuyVision.java b/src/main/java/edu/stuy/robot/cv/StuyVision.java new file mode 100644 index 0000000..a5ab54c --- /dev/null +++ b/src/main/java/edu/stuy/robot/cv/StuyVision.java @@ -0,0 +1,411 @@ +//package edu.stuy.robot.cv; +// +//import static edu.stuy.robot.RobotMap.CAMERA_DIST_TO_BOT_FRONT; +//import static edu.stuy.robot.RobotMap.CAMERA_FRAME_PX_HEIGHT; +//import static edu.stuy.robot.RobotMap.CAMERA_FRAME_PX_WIDTH; +//import static edu.stuy.robot.RobotMap.CAMERA_HEIGHT_FROM_GROUND; +//import static edu.stuy.robot.RobotMap.CAMERA_TILT_ANGLE; +//import static edu.stuy.robot.RobotMap.CAMERA_VIEWING_ANGLE_X; +//import static edu.stuy.robot.RobotMap.CAMERA_VIEWING_ANGLE_Y; +//import static edu.stuy.robot.RobotMap.HIGH_GOAL_HEIGHT; +// +//import java.io.IOException; +//import java.io.PrintWriter; +//import java.util.ArrayList; +//import java.util.Arrays; +// +//import org.opencv.core.Core; +//import org.opencv.core.CvType; +//import org.opencv.core.Mat; +//import org.opencv.core.MatOfPoint; +//import org.opencv.core.MatOfPoint2f; +//import org.opencv.core.Point; +//import org.opencv.core.RotatedRect; +//import org.opencv.core.Scalar; +//import org.opencv.core.Size; +//import org.opencv.imgcodecs.Imgcodecs; +//import org.opencv.imgproc.Imgproc; +//import org.opencv.videoio.Videoio; +// +//import edu.stuy.robot.cv.capture.CaptureSource; +//import edu.stuy.robot.cv.capture.DeviceCaptureSource; +//import edu.stuy.robot.cv.gui.DoubleSV; +//import edu.stuy.robot.cv.gui.IntegerSV; +//import edu.stuy.robot.cv.gui.Main; +//import edu.stuy.robot.cv.gui.VisionModule; +// +//public class StuyVision extends VisionModule { +// +// // The following can be left in even in production, as the overhead +// // of using .value() is negligible +// public IntegerSV minH_GREEN = IntegerSV.mkColor(36, "Min Hue"); +// public IntegerSV maxH_GREEN = IntegerSV.mkColor(94, "Max Hue"); +// +// public IntegerSV minS_GREEN = IntegerSV.mkColor(225, "Min Saturation"); +// public IntegerSV maxS_GREEN = IntegerSV.mkColor(255, "Max Saturation"); +// +// public IntegerSV minV_GREEN = IntegerSV.mkColor(30, "Min Value"); +// public IntegerSV maxV_GREEN = IntegerSV.mkColor(255, "Max Value"); +// +// // Thresholds regarding the geometry of the bounding box of the region found +// // by the HSV filtering +// public DoubleSV minGoalArea = new DoubleSV(200.0, 0.0, 10000.0, "Min Goal Area"); +// public DoubleSV maxGoalArea = new DoubleSV(30720.0, 0.0, 10000.0, "Max Goal Area"); +// public DoubleSV minGoalRatio = new DoubleSV(1.1, 1.0, 10.0, "Min Goal Ratio"); +// public DoubleSV maxGoalRatio = new DoubleSV(3.0, 1.0, 10.0, "Max Goal Ratio"); +// +// private static final int outerUSBPort = 0; +// private int cameraPort; +// private DeviceCaptureSource camera; +// +// private static PrintWriter logWriter; +// +// // Reused across processImage() calls +// private Mat rawFrame; +// private Mat resizedFrame; +// +// public StuyVision() { +// try { +// // Ensure native libraries are loaded +// loadOpenCV(); +// // Assume the camera is plugged into port `outerUSBPort` +// cameraPort = outerUSBPort; +// initializeCamera(); +// rawFrame = new Mat(); +// resizedFrame = new Mat(); +// } catch (Exception e) { +// System.out.println("Failed to create camera at " + cameraPort + ". Error was: " + e); +// } +// try { +// logWriter = new PrintWriter("logs.txt"); +// } catch (Exception e) { +// } +// } +// +// public static void loadOpenCV() { +// // Load opencv native library +// String dir = StuyVision.class.getClassLoader().getResource("").getPath(); +// if (System.getProperty("os.name").toLowerCase().contains("windows")) { +// System.load(dir.substring(1).replaceAll("\\%20", " ") +// + "..\\lib\\opencv-3.1.0\\build\\java\\x64\\opencv_java310.dll"); +// } else { +// // This is the .so's location on the roboRio +// System.load("/usr/local/frc/lib/libopencv_java320.so"); +// } +// } +// +// private void initializeCamera() { +// Runtime rt = Runtime.getRuntime(); +// try { +// rt.exec("/usr/bin/v4l2-ctl -c exposure_auto=1,exposure_absolute=5,brightness=30,contrast=10,saturation=200,white_balance_temperature_auto=0,sharpness=50").waitFor(); +// rt.exec("/usr/bin/v4l2-ctl -c white_balance_temperature=4624").waitFor(); +// } catch (Exception e) { +// System.err.println("Setting v4l settings crashed!"); +// } +// camera = new DeviceCaptureSource(cameraPort); +// System.out.println("Made camera"); +// camera.capture.set(Videoio.CV_CAP_PROP_BUFFERSIZE, 2); +// } +// +// /** +// * Given the dimensions of a rectangle, return whether the ratio of these +// * rectangle's dimensions suggests it may be a valid goal. +// * +// * @param height +// * @param width +// * @return +// */ +// private boolean aspectRatioThreshold(double height, double width) { +// double ratio = width / height; +// return (minGoalRatio.value() < ratio && ratio < maxGoalRatio.value()) +// || (1 / maxGoalRatio.value() < ratio && ratio < 1 / minGoalRatio.value()); +// } +// +// private double[] getLargestGoal(Mat originalFrame, Mat filteredImage, Main app) { +// boolean withGui = app != null; +// Mat drawn = null; +// if (withGui) { +// drawn = originalFrame.clone(); +// } +// +// ArrayList contours = new ArrayList(); +// Imgproc.findContours(filteredImage, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); +// double largestArea = 0.0; +// RotatedRect largestRect = null; +// +// for (int i = 0; i < contours.size(); i++) { +// double currArea = Imgproc.contourArea(contours.get(i)); +// if (currArea < minGoalArea.value() || currArea > maxGoalArea.value()) { +// continue; +// } +// MatOfPoint2f tmp = new MatOfPoint2f(); +// contours.get(i).convertTo(tmp, CvType.CV_32FC1); +// RotatedRect r = Imgproc.minAreaRect(tmp); +// if (!aspectRatioThreshold(r.size.height, r.size.width)) { +// continue; +// } +// if (withGui) { +// Point[] points = new Point[4]; +// r.points(points); +// for (int j = 0; j < points.length; j++) { +// Imgproc.line(drawn, points[j], points[(j + 1) % 4], new Scalar(0, 255, 0)); +// } +// } +// if (currArea > largestArea) { +// largestArea = currArea; +// largestRect = r; +// } +// } +// +// if (largestRect == null) { +// if (withGui) { +// // Post the unchanged image anyway for visual consistency +// app.postImage(originalFrame, "Goals", this); +// } +// // Return null to signify no goal found +// return null; +// } +// +// double[] vector = new double[3]; +// vector[0] = largestRect.center.x - originalFrame.width() / 2.0; +// vector[1] = largestRect.center.y - originalFrame.height() / 2.0; +// vector[2] = largestRect.angle; +// +// if (withGui) { +// Imgproc.circle(drawn, largestRect.center, 1, new Scalar(0, 0, 255), 2); +// double w = drawn.width(); +// double h = drawn.height(); +// Imgproc.line(drawn, new Point(w / 2, h / 2), largestRect.center, new Scalar(0, 0, 255)); +// app.postImage(drawn, "Goals", this); +// } +// +// return vector; +// } +// +// public double[] getLargestGoal(Mat orig, Mat f) { +// return getLargestGoal(orig, f, null); +// } +// +// /** +// * Process an image to look for a goal, and, if a app is +// * passed, post two intermediate states of the image from during processing +// * to the gui +// * +// * @param frame +// * The image to process +// * +// * @param app +// * (Optional: pass null to ignore) The Main to +// * post intermediate states of the processed image to. +// * +// * @return Three doubles, in a double[3], ordered as such:

+// * index 0: The x-offset, in pixels, of the center of the +// * bounding rectangle of the found goal from the center of the image

+// *

index 1: The y-offset, in pixels, of the center of the +// * bounding rectangle of the found goal form the center of the image

+// *

index 2: The angle at which the bounding rectangle is +// * tilted

+// */ +// public double[] hsvThresholding(Mat frame, Main app) { +// boolean withGui = app != null; +// +// // Convert BGR camera image to HSV for processing +// Mat hsv = new Mat(); +// Imgproc.cvtColor(frame, hsv, Imgproc.COLOR_BGR2HSV); +// +// // Split HSV channels and process each channel +// ArrayList greenFilterChannels = new ArrayList(); +// Core.split(hsv, greenFilterChannels); +// Core.inRange(greenFilterChannels.get(0), new Scalar(minH_GREEN.value()), new Scalar(maxH_GREEN.value()), +// greenFilterChannels.get(0)); +// if (withGui) { +// app.postImage(greenFilterChannels.get(0), "After H", this); +// } +// Core.inRange(greenFilterChannels.get(1), new Scalar(minS_GREEN.value()), new Scalar(maxS_GREEN.value()), +// greenFilterChannels.get(1)); +// if (withGui) { +// app.postImage(greenFilterChannels.get(1), "After S", this); +// } +// Core.inRange(greenFilterChannels.get(2), new Scalar(minV_GREEN.value()), new Scalar(maxV_GREEN.value()), +// greenFilterChannels.get(2)); +// if (withGui) { +// app.postImage(greenFilterChannels.get(2), "After V", this); +// } +// +// // Merge filtered H, S and V back into one binarized image +// Mat greenFiltered = new Mat(); +// Core.bitwise_and(greenFilterChannels.get(0), greenFilterChannels.get(1), greenFiltered); +// Core.bitwise_and(greenFilterChannels.get(2), greenFiltered, greenFiltered); +// if (withGui) { +// app.postImage(greenFiltered, "After filtering H, S, V", this); +// } +// +// // Erode and dilate to remove noise +// Mat erodeKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)); +// Mat dilateKernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9, 9)); +// Imgproc.erode(greenFiltered, greenFiltered, erodeKernel); +// Imgproc.dilate(greenFiltered, greenFiltered, dilateKernel); +// if (withGui) { +// app.postImage(greenFiltered, "After erode/dilate", this); +// } +// +// double[] output = getLargestGoal(frame, greenFiltered, app); +// try { +// logWriter.println(new Report(output)); +// logWriter.flush(); +// } catch (Exception e) { +// } +// return output; +// } +// +// public double[] hsvThresholding(Mat frame) { +// return hsvThresholding(frame, null); +// } +// +// public double[] processImage(boolean save) { +// if (camera == null) { +// System.out.println("Camera object is uninitialized or frame not taken!"); +// return null; +// } +// // To prevent buffer repeat frames from being used: +// for (int i = 0; i < 5; i++) { +// camera.readFrame(rawFrame); +// } +// // Now read and resize updated frame: +// Mat frame = camera.readSized(rawFrame, resizedFrame); +// System.out.println("Got frame from camera"); +// if (frame == null) { +// System.out.println("FRAME WAS NULL"); +// return null; +// } +// double[] result = hsvThresholding(frame); +// if (save) { +// String homeDir = System.getProperty("user.home"); +// String path = homeDir + "/save.png"; +// Imgcodecs.imwrite(path, frame); +// System.out.println("Successfully saved"); +// } +// return result; +// } +// +// public double[] processImage() { +// return processImage(false); +// } +// +// /** +// * Tests time taken to process iters frames read from +// * cs +// * +// * @param cs +// * The CaptureSource from which to read frames +// * @param iters +// * The number of frames to read from cs and to process and time +// * @return The average time taken by hsvThresholding to process +// * one of the frames +// */ +// public double testProcessingTime(CaptureSource cs, int iters) { +// int total = 0; +// double[] vec; +// for (int i = 0; i < iters; i++) { +// long start = System.currentTimeMillis(); +// vec = processImage(); +// total += (int) (System.currentTimeMillis() - start); +// } +// return total / (double) iters; +// } +// +// // Calculation methods: +// public static double frameXPxToDegrees(double px) { +// return CAMERA_VIEWING_ANGLE_X * px / CAMERA_FRAME_PX_WIDTH; +// } +// +// public static double frameYPxToDegrees(double dy) { +// return dy / CAMERA_FRAME_PX_HEIGHT * CAMERA_VIEWING_ANGLE_Y; +// } +// +// public static double yInFrameToDegreesFromHorizon(double height) { +// return CAMERA_TILT_ANGLE - frameYPxToDegrees(height); +// } +// +// public static double findCameraDistanceToGoal(double frameY) { +// double angle = yInFrameToDegreesFromHorizon(frameY); +// return (HIGH_GOAL_HEIGHT - CAMERA_HEIGHT_FROM_GROUND) / Math.tan(Math.toRadians(angle)); +// } +// +// public static double findBotDistanceToGoal(double frameY) { +// return findCameraDistanceToGoal(frameY) - CAMERA_DIST_TO_BOT_FRONT; +// } +// +// public static double findDistanceToGoal(double[] vec) { +// if (vec == null) { +// return -1; +// } +// return findCameraDistanceToGoal(vec[1]); +// } +// +// public static class Report { +// double[] reading; +// double goalDegsY; +// double goalDegsX; +// double inchesAway; +// double degsUp; +// +// public Report(double[] visionReading) { +// if (visionReading == null) { +// return; +// } +// reading = visionReading; +// goalDegsX = frameXPxToDegrees(reading[0]); +// goalDegsY = frameXPxToDegrees(reading[1]); +// degsUp = yInFrameToDegreesFromHorizon(reading[1]); +// inchesAway = findCameraDistanceToGoal(reading[1]); +// // let null pointer exception occur if data is null +// } +// +// public String formattedReading() { +// if (reading == null) { +// return "null"; +// } +// return "[" + fmt(reading[0]) + ", " + fmt(reading[1]) + ", " + fmt(reading[2]) + "]"; +// } +// +// private static final String blank = "------------------------------------"; +// +// public String toString() { +// boolean none = false; +// if (reading == null) { +// // return "| CV read no goals in frame\n" + blank + blank + +// // blank + blank + blank; +// none = true; +// } +// return "| CV Read: " + Arrays.toString(reading) + "\n" + "| Data: " +// + (none ? blank : formattedReading()) + "\n" + "| Angle X: " +// + (none ? blank : (fmt(goalDegsX) + "\u00B0 right from center")) + "\n" + "| Angle Y: " +// + (none ? blank : (fmt(goalDegsY) + "\u00B0 down from center")) + "\n" + "| Elevation: " +// + (none ? blank : (fmt(degsUp) + "\u00B0 up from horizon")) + "\n" + "| Cam Dist: " +// + (none ? blank : fmtDist(inchesAway)) + "\n" + "| (Time: " + System.currentTimeMillis() + ")\n"; +// } +// +// private static String fmtDist(double d) { +// int inches = (int) d; +// return (inches / 12) + " ft, " + (inches % 12) + " in"; +// } +// +// private static String fmt(double d) { +// return String.format("%.0f", d); +// } +// } +// +// public static void main(String[] args) { +// System.out.println("Running test: read from frame and determine angle to rotate"); +// StuyVision sv = new StuyVision(); +// double[] reading = sv.processImage(); +// System.out.println(new Report(reading)); +// } +// +// public void run(Main app, Mat frame) { +// app.postImage(frame, "Video", this); +// double[] reading = hsvThresholding(frame, app); +// System.out.println("\n\n" + new Report(reading)); +// } +//} diff --git a/src/edu/stuy/robot/cv/capture/CaptureSource.java b/src/main/java/edu/stuy/robot/cv/capture/CaptureSource.java similarity index 100% rename from src/edu/stuy/robot/cv/capture/CaptureSource.java rename to src/main/java/edu/stuy/robot/cv/capture/CaptureSource.java diff --git a/src/edu/stuy/robot/cv/capture/DeviceCaptureSource.java b/src/main/java/edu/stuy/robot/cv/capture/DeviceCaptureSource.java similarity index 100% rename from src/edu/stuy/robot/cv/capture/DeviceCaptureSource.java rename to src/main/java/edu/stuy/robot/cv/capture/DeviceCaptureSource.java diff --git a/src/edu/stuy/robot/cv/capture/ImageCaptureSource.java b/src/main/java/edu/stuy/robot/cv/capture/ImageCaptureSource.java similarity index 100% rename from src/edu/stuy/robot/cv/capture/ImageCaptureSource.java rename to src/main/java/edu/stuy/robot/cv/capture/ImageCaptureSource.java diff --git a/src/edu/stuy/robot/cv/capture/VideoCaptureSource.java b/src/main/java/edu/stuy/robot/cv/capture/VideoCaptureSource.java similarity index 100% rename from src/edu/stuy/robot/cv/capture/VideoCaptureSource.java rename to src/main/java/edu/stuy/robot/cv/capture/VideoCaptureSource.java diff --git a/src/edu/stuy/robot/cv/gui/BooleanVariable.java b/src/main/java/edu/stuy/robot/cv/gui/BooleanVariable.java similarity index 100% rename from src/edu/stuy/robot/cv/gui/BooleanVariable.java rename to src/main/java/edu/stuy/robot/cv/gui/BooleanVariable.java diff --git a/src/main/java/edu/stuy/robot/cv/gui/ControlsController.java b/src/main/java/edu/stuy/robot/cv/gui/ControlsController.java new file mode 100644 index 0000000..8f7df08 --- /dev/null +++ b/src/main/java/edu/stuy/robot/cv/gui/ControlsController.java @@ -0,0 +1,170 @@ +//package edu.stuy.robot.cv.gui; +// +//import java.lang.reflect.Field; +//import java.text.DecimalFormat; +//import java.util.ArrayList; +// +//import edu.stuy.robot.cv.util.DebugPrinter; +//import javafx.application.Platform; +//import javafx.beans.value.ChangeListener; +//import javafx.beans.value.ObservableValue; +//import javafx.fxml.FXML; +//import javafx.geometry.Pos; +//import javafx.scene.Node; +//import javafx.scene.control.Button; +//import javafx.scene.control.CheckBox; +//import javafx.scene.control.Slider; +//import javafx.scene.layout.FlowPane; +//import javafx.scene.layout.VBox; +//import javafx.scene.text.Text; +// +//public class ControlsController { +// +// @FXML +// FlowPane flowPane; +// @FXML +// VBox controlsContainer; +// @FXML +// Button restoreDefaults; +// +// final DecimalFormat formatter = new DecimalFormat("#.###"); +// +// public void setup(VisionModule module) { +// ArrayList variables = new ArrayList<>(); +// restoreDefaults.setOnAction((event) -> { +// for (VariableWrapper var : variables) { +// var.restoreDefault(); +// } +// }); +// ArrayList variableContainers = new ArrayList<>(); +// for (Field f : module.getClass().getFields()) { +// Class fType = f.getType(); +// if (fType.isAssignableFrom(IntegerSV.class)) { +// DebugPrinter.println("Found IntegerSV: " + f.getName()); +// IntegerSV isv = null; +// try { +// isv = (IntegerSV) f.get(module); +// } +// catch (IllegalArgumentException | IllegalAccessException e) { +// e.printStackTrace(); +// } +// VBox sliderContainer = new VBox(); +// sliderContainer.setAlignment(Pos.CENTER); +// Slider slider = new Slider(isv.MIN, isv.MAX, isv.DEFAULT); +// slider.setShowTickMarks(true); +// Text value = new Text(Integer.toString(isv.DEFAULT)); +// value.getStyleClass().add("slider-value"); +// Text label = new Text(isv.LABEL); +// label.getStyleClass().add("slider-label"); +// final IntegerSV finalIsv = isv; +// sliderContainer.getChildren().addAll(slider, value, label); +// slider.valueProperty().addListener(new ChangeListener() { +// @Override +// public void changed(ObservableValue observable, Number oldValue, +// Number newValue) { +// int intValue = newValue.intValue(); +// finalIsv.set(intValue); +// value.setText(Integer.toString(intValue)); +// } +// }); +// variables.add(new SliderVariableWrapper(slider, isv)); +// variableContainers.add(sliderContainer); +// } +// else if (fType.isAssignableFrom(DoubleSV.class)) { +// DebugPrinter.println("Found DoubleSV: " + f.getName()); +// DoubleSV dsv = null; +// try { +// dsv = (DoubleSV) f.get(module); +// } +// catch (IllegalArgumentException | IllegalAccessException e) { +// e.printStackTrace(); +// } +// VBox sliderContainer = new VBox(); +// sliderContainer.setAlignment(Pos.CENTER); +// Slider slider = new Slider(dsv.MIN, dsv.MAX, dsv.DEFAULT); +// slider.setShowTickMarks(true); +// Text value = new Text(formatter.format(dsv.DEFAULT)); +// value.getStyleClass().add("slider-value"); +// Text label = new Text(dsv.LABEL); +// label.getStyleClass().add("slider-label"); +// final DoubleSV finalDsv = dsv; +// sliderContainer.getChildren().addAll(slider, value, label); +// slider.valueProperty().addListener(new ChangeListener() { +// @Override +// public void changed(ObservableValue observable, Number oldValue, +// Number newValue) { +// double doubleValue = newValue.doubleValue(); +// finalDsv.set(doubleValue); +// value.setText(formatter.format(doubleValue)); +// } +// }); +// variables.add(new SliderVariableWrapper(slider, finalDsv)); +// variableContainers.add(sliderContainer); +// } +// else if (fType.isAssignableFrom(BooleanVariable.class)) { +// DebugPrinter.println("Found BooleanVariable: " + f.getName()); +// BooleanVariable bv = null; +// try { +// bv = (BooleanVariable) f.get(module); +// } +// catch (IllegalArgumentException | IllegalAccessException e) { +// e.printStackTrace(); +// } +// VBox checkBoxContainer = new VBox(); +// checkBoxContainer.setAlignment(Pos.CENTER); +// CheckBox checkBox = new CheckBox(bv.LABEL); +// checkBox.setSelected(bv.DEFAULT); +// checkBox.getStyleClass().add("boolean-label"); +// final BooleanVariable finalBv = bv; +// checkBoxContainer.getChildren().addAll(checkBox); +// checkBox.selectedProperty().addListener(new ChangeListener() { +// @Override +// public void changed(ObservableValue observable, Boolean oldValue, +// Boolean newValue) { +// boolean booleanValue = newValue.booleanValue(); +// finalBv.setValue(booleanValue); +// } +// }); +// variables.add(new BooleanVariableWrapper(checkBox, finalBv)); +// variableContainers.add(checkBoxContainer); +// } +// } +// Platform.runLater(() -> { +// controlsContainer.getChildren().addAll(variableContainers); +// }); +// } +// +// private abstract class VariableWrapper { +// public abstract void restoreDefault(); +// } +// +// private class SliderVariableWrapper extends VariableWrapper { +// private Slider slider; +// private NumberVariable sliderVariable; +// +// private SliderVariableWrapper(Slider slider, NumberVariable sliderVariable) { +// this.slider = slider; +// this.sliderVariable = sliderVariable; +// } +// +// public void restoreDefault() { +// sliderVariable.restoreDefault(); +// slider.setValue(sliderVariable.getValue().doubleValue()); +// } +// } +// +// private class BooleanVariableWrapper extends VariableWrapper { +// private CheckBox checkBox; +// private BooleanVariable booleanVariable; +// +// private BooleanVariableWrapper(CheckBox checkBox, BooleanVariable booleanVariable) { +// this.checkBox = checkBox; +// this.booleanVariable = booleanVariable; +// } +// +// public void restoreDefault() { +// booleanVariable.restoreDefault(); +// checkBox.setSelected(booleanVariable.getValue()); +// } +// } +//} diff --git a/src/edu/stuy/robot/cv/gui/DoubleSV.java b/src/main/java/edu/stuy/robot/cv/gui/DoubleSV.java similarity index 100% rename from src/edu/stuy/robot/cv/gui/DoubleSV.java rename to src/main/java/edu/stuy/robot/cv/gui/DoubleSV.java diff --git a/src/main/java/edu/stuy/robot/cv/gui/ImageViewer.java b/src/main/java/edu/stuy/robot/cv/gui/ImageViewer.java new file mode 100644 index 0000000..005117c --- /dev/null +++ b/src/main/java/edu/stuy/robot/cv/gui/ImageViewer.java @@ -0,0 +1,58 @@ +//package edu.stuy.robot.cv.gui; +// +//import java.util.HashMap; +// +//import javafx.application.Platform; +//import javafx.scene.Scene; +//import javafx.scene.image.ImageView; +//import javafx.scene.layout.Pane; +//import javafx.stage.Stage; +// +//public class ImageViewer { +// +// private static ImageViewer instance; +// private HashMap windows = new HashMap<>(); +// +// private ImageViewer() {} +// +// public static ImageViewer getInstance() { +// if (instance == null) { +// instance = new ImageViewer(); +// } +// return instance; +// } +// +// public void showImage(String label, ImageView image) { +// Stage imageWindow = windows.get(image); +// if (imageWindow != null) { +// final Stage finalImageWindow = imageWindow; +// Platform.runLater(() -> { +// finalImageWindow.toFront(); +// }); +// } +// else { +// imageWindow = new Stage(); +// double imageWidth = image.getImage().getWidth(); +// double imageHeight = image.getImage().getHeight(); +// double resizeRatio = (double) 960 / Math.max(imageWidth, imageHeight); +// ImageView resizedView = new ImageView(image.getImage()); +// // blow up image size to max of 960px +// resizedView.setFitWidth(imageWidth * resizeRatio); +// resizedView.setFitHeight(imageHeight * resizeRatio); +// resizedView.imageProperty().bind(image.imageProperty()); +// imageWindow.setTitle(label); +// imageWindow.setWidth(imageWidth * resizeRatio); +// imageWindow.setHeight(imageHeight * resizeRatio); +// imageWindow.setScene(new Scene(new Pane(resizedView))); +// imageWindow.setOnCloseRequest((event) -> { +// windows.remove(image); +// }); +// final Stage finalImageWindow = imageWindow; +// Platform.runLater(() -> { +// finalImageWindow.show(); +// }); +// windows.put(image, imageWindow); +// } +// } +// +//} diff --git a/src/edu/stuy/robot/cv/gui/IntegerSV.java b/src/main/java/edu/stuy/robot/cv/gui/IntegerSV.java similarity index 100% rename from src/edu/stuy/robot/cv/gui/IntegerSV.java rename to src/main/java/edu/stuy/robot/cv/gui/IntegerSV.java diff --git a/src/main/java/edu/stuy/robot/cv/gui/Main.java b/src/main/java/edu/stuy/robot/cv/gui/Main.java new file mode 100644 index 0000000..514077d --- /dev/null +++ b/src/main/java/edu/stuy/robot/cv/gui/Main.java @@ -0,0 +1,143 @@ +//package edu.stuy.robot.cv.gui; +// +//import java.io.ByteArrayInputStream; +//import java.util.HashMap; +// +//import org.opencv.core.Mat; +//import org.opencv.core.MatOfByte; +//import org.opencv.imgcodecs.Imgcodecs; +// +//import edu.stuy.robot.cv.StuyVision; +//import edu.stuy.robot.cv.capture.DeviceCaptureSource; +//import edu.stuy.robot.cv.util.DebugPrinter; +//import javafx.application.Application; +//import javafx.application.Platform; +//import javafx.fxml.FXMLLoader; +//import javafx.geometry.Pos; +//import javafx.scene.Scene; +//import javafx.scene.control.SplitPane; +//import javafx.scene.control.Tab; +//import javafx.scene.control.TabPane; +//import javafx.scene.image.Image; +//import javafx.scene.image.ImageView; +//import javafx.scene.input.MouseButton; +//import javafx.scene.layout.VBox; +//import javafx.scene.text.Text; +//import javafx.stage.Stage; +// +//public class Main extends Application { +// private TabPane root; +// private Scene scene; +// private HashMap tabs = new HashMap(); +// private HashMap images = new HashMap(); +// +// @Override +// public void start(Stage primaryStage) { +// try { +// FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/main.fxml")); +// root = loader.load(); +// scene = new Scene(root); +// scene.getStylesheets().add(getClass().getResource("css/main.css").toString()); +// // Initialize ModuleRunner with VisionModuleSuite +// VisionModule module = new StuyVision(); +// { +// FXMLLoader tabLoader = new FXMLLoader(getClass().getResource("fxml/module_main.fxml")); +// final SplitPane moduleContainer = tabLoader.load(); +// ControlsController controlsController = tabLoader.getController(); +// controlsController.setup(module); +// tabs.put(module.hashCode(), controlsController); +// root.getTabs().add(new Tab(module.getName(), moduleContainer)); +// } +// Main self = this; +// DeviceCaptureSource cs = new DeviceCaptureSource(0); +// { +// Thread t = new Thread(new Runnable() { +// private Mat rawFrame; +// private Mat resizedFrame; +// @Override +// public void run() { +// rawFrame = new Mat(); +// resizedFrame = new Mat(); +// for (;;) { +// try { +// long start = System.currentTimeMillis(); +// Mat frame = cs.readSized(rawFrame, resizedFrame); +// module.run(self, frame); +// long duration = System.currentTimeMillis() - start; +// DebugPrinter.println(module.getName() + ": " + duration + " ms"); +// Thread.sleep(1000 / 30); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// }, module.getName() + " Thread"); +// t.setDaemon(true); +// t.start(); +// } +// primaryStage.setOnCloseRequest((event) -> quit()); +// primaryStage.setTitle("Java Vision GUI"); +// primaryStage.setScene(scene); +// primaryStage.show(); +// } +// catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// private void quit() { +// Platform.exit(); +// System.exit(0); +// } +// +// public synchronized void postImage(Mat m, String label, VisionModule requester) { +// String key = requester.hashCode() + label; +// // Convert raw image to PNG +// MatOfByte buffer = new MatOfByte(); +// Imgcodecs.imencode(".png", m, buffer); +// Image image = new Image(new ByteArrayInputStream(buffer.toArray())); +// // Check if an ImageFrame already exists +// ImageFrame existingFrame = images.get(key); +// if (existingFrame == null) { +// VBox container = new VBox(); +// container.setAlignment(Pos.CENTER); +// ImageView imageView = new ImageView(image); +// Text text = new Text(label); +// text.getStyleClass().add("image-label"); +// container.getChildren().addAll(imageView, text); +// images.put(key, new ImageFrame(imageView, text)); +// Platform.runLater(() -> { +// tabs.get(requester.hashCode()).flowPane.getChildren().add(container); +// }); +// container.setOnMouseClicked((event) -> { +// if (event.getButton().equals(MouseButton.PRIMARY)) { +// if (event.getClickCount() == 2) { +// ImageViewer.getInstance().showImage(label, imageView); +// } +// } +// }); +// } +// else { +// // Update the existing ImageFrame +// Platform.runLater(() -> { +// existingFrame.imageView.setImage(image); +// existingFrame.imageView.toFront(); +// existingFrame.label.toFront(); +// }); +// } +// } +// +// public static void main(String[] args) { +// launch(args); +// } +// +// private class ImageFrame { +// private ImageView imageView; +// private Text label; +// +// public ImageFrame(ImageView imageView, Text label) { +// this.imageView = imageView; +// this.label = label; +// } +// } +//} diff --git a/src/edu/stuy/robot/cv/gui/NumberVariable.java b/src/main/java/edu/stuy/robot/cv/gui/NumberVariable.java similarity index 100% rename from src/edu/stuy/robot/cv/gui/NumberVariable.java rename to src/main/java/edu/stuy/robot/cv/gui/NumberVariable.java diff --git a/src/edu/stuy/robot/cv/gui/Variable.java b/src/main/java/edu/stuy/robot/cv/gui/Variable.java similarity index 100% rename from src/edu/stuy/robot/cv/gui/Variable.java rename to src/main/java/edu/stuy/robot/cv/gui/Variable.java diff --git a/src/main/java/edu/stuy/robot/cv/gui/VisionModule.java b/src/main/java/edu/stuy/robot/cv/gui/VisionModule.java new file mode 100644 index 0000000..88e4c45 --- /dev/null +++ b/src/main/java/edu/stuy/robot/cv/gui/VisionModule.java @@ -0,0 +1,12 @@ +//package edu.stuy.robot.cv.gui; +// +//import org.opencv.core.Mat; +// +//public abstract class VisionModule { +// +// public abstract void run(Main app, Mat frame); +// +// public String getName() { +// return getClass().getSimpleName(); +// } +//} diff --git a/src/edu/stuy/robot/cv/gui/css/main.css b/src/main/java/edu/stuy/robot/cv/gui/css/main.css similarity index 100% rename from src/edu/stuy/robot/cv/gui/css/main.css rename to src/main/java/edu/stuy/robot/cv/gui/css/main.css diff --git a/src/edu/stuy/robot/cv/gui/fxml/main.fxml b/src/main/java/edu/stuy/robot/cv/gui/fxml/main.fxml similarity index 100% rename from src/edu/stuy/robot/cv/gui/fxml/main.fxml rename to src/main/java/edu/stuy/robot/cv/gui/fxml/main.fxml diff --git a/src/edu/stuy/robot/cv/gui/fxml/module_main.fxml b/src/main/java/edu/stuy/robot/cv/gui/fxml/module_main.fxml similarity index 100% rename from src/edu/stuy/robot/cv/gui/fxml/module_main.fxml rename to src/main/java/edu/stuy/robot/cv/gui/fxml/module_main.fxml diff --git a/src/edu/stuy/robot/cv/util/DebugPrinter.java b/src/main/java/edu/stuy/robot/cv/util/DebugPrinter.java similarity index 100% rename from src/edu/stuy/robot/cv/util/DebugPrinter.java rename to src/main/java/edu/stuy/robot/cv/util/DebugPrinter.java diff --git a/src/edu/stuy/robot/cv/util/FileDoesNotExistException.java b/src/main/java/edu/stuy/robot/cv/util/FileDoesNotExistException.java similarity index 100% rename from src/edu/stuy/robot/cv/util/FileDoesNotExistException.java rename to src/main/java/edu/stuy/robot/cv/util/FileDoesNotExistException.java diff --git a/src/edu/stuy/robot/cv/util/FileManager.java b/src/main/java/edu/stuy/robot/cv/util/FileManager.java similarity index 100% rename from src/edu/stuy/robot/cv/util/FileManager.java rename to src/main/java/edu/stuy/robot/cv/util/FileManager.java diff --git a/src/edu/stuy/robot/subsystems/Acquirer.java b/src/main/java/edu/stuy/robot/subsystems/Acquirer.java similarity index 81% rename from src/edu/stuy/robot/subsystems/Acquirer.java rename to src/main/java/edu/stuy/robot/subsystems/Acquirer.java index 0d84b25..e7326e7 100644 --- a/src/edu/stuy/robot/subsystems/Acquirer.java +++ b/src/main/java/edu/stuy/robot/subsystems/Acquirer.java @@ -1,8 +1,10 @@ package edu.stuy.robot.subsystems; import static edu.stuy.robot.RobotMap.ACQUIRER_MOTOR_CHANNEL; + +import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; + import edu.stuy.robot.commands.AcquirerStopCommand; -import edu.wpi.first.wpilibj.CANTalon; import edu.wpi.first.wpilibj.command.Subsystem; /** @@ -10,13 +12,13 @@ */ public class Acquirer extends Subsystem { - private CANTalon acquirerMotor; + private WPI_TalonSRX acquirerMotor; // Put methods for controlling this subsystem // here. Call these from Commands. public Acquirer() { - acquirerMotor = new CANTalon(ACQUIRER_MOTOR_CHANNEL); + acquirerMotor = new WPI_TalonSRX(ACQUIRER_MOTOR_CHANNEL); } public void initDefaultCommand() { diff --git a/src/edu/stuy/robot/subsystems/Drivetrain.java b/src/main/java/edu/stuy/robot/subsystems/Drivetrain.java similarity index 78% rename from src/edu/stuy/robot/subsystems/Drivetrain.java rename to src/main/java/edu/stuy/robot/subsystems/Drivetrain.java index 886b87a..c647fe0 100644 --- a/src/edu/stuy/robot/subsystems/Drivetrain.java +++ b/src/main/java/edu/stuy/robot/subsystems/Drivetrain.java @@ -12,16 +12,19 @@ import static edu.stuy.robot.RobotMap.RIGHT_ENCODER_CHANNEL_A; import static edu.stuy.robot.RobotMap.RIGHT_ENCODER_CHANNEL_B; +import com.ctre.phoenix.motorcontrol.NeutralMode; +import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; + import edu.stuy.robot.commands.DrivetrainTankDriveCommand; import edu.stuy.util.TankDriveOutput; import edu.wpi.first.wpilibj.ADXRS450_Gyro; -import edu.wpi.first.wpilibj.CANTalon; import edu.wpi.first.wpilibj.Encoder; import edu.wpi.first.wpilibj.PIDController; import edu.wpi.first.wpilibj.PIDSourceType; -import edu.wpi.first.wpilibj.RobotDrive; import edu.wpi.first.wpilibj.Solenoid; +import edu.wpi.first.wpilibj.SpeedControllerGroup; import edu.wpi.first.wpilibj.command.Subsystem; +import edu.wpi.first.wpilibj.drive.DifferentialDrive; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; /** @@ -30,16 +33,17 @@ public class Drivetrain extends Subsystem { private Encoder rightEncoder; private Encoder leftEncoder; - private CANTalon leftFrontMotor; - private CANTalon rightFrontMotor; - private CANTalon leftRearMotor; - private CANTalon rightRearMotor; - private RobotDrive robotDrive; + private WPI_TalonSRX leftFrontMotor; + private WPI_TalonSRX rightFrontMotor; + private WPI_TalonSRX leftRearMotor; + private WPI_TalonSRX rightRearMotor; + private DifferentialDrive differentialDrive; private ADXRS450_Gyro gyro; private TankDriveOutput out; private Solenoid gearShift; private double[] currents; - + private SpeedControllerGroup leftSpeedController; + private SpeedControllerGroup rightSpeedController; public final PIDController pid; public boolean gearUp; // Stores the state of the gear shift @@ -53,16 +57,17 @@ public class Drivetrain extends Subsystem { public Drivetrain() { gearShift = new Solenoid(GEAR_SHIFT_CHANNEL); currents = new double[10]; - leftFrontMotor = new CANTalon(FRONT_LEFT_MOTOR_CHANNEL); - rightFrontMotor = new CANTalon(FRONT_RIGHT_MOTOR_CHANNEL); - leftRearMotor = new CANTalon(REAR_LEFT_MOTOR_CHANNEL); - rightRearMotor = new CANTalon(REAR_RIGHT_MOTOR_CHANNEL); + leftFrontMotor = new WPI_TalonSRX(FRONT_LEFT_MOTOR_CHANNEL); + rightFrontMotor = new WPI_TalonSRX(FRONT_RIGHT_MOTOR_CHANNEL); + leftRearMotor = new WPI_TalonSRX(REAR_LEFT_MOTOR_CHANNEL); + rightRearMotor = new WPI_TalonSRX(REAR_RIGHT_MOTOR_CHANNEL); leftFrontMotor.setInverted(true); rightFrontMotor.setInverted(true); leftRearMotor.setInverted(true); rightRearMotor.setInverted(true); - robotDrive = new RobotDrive(leftFrontMotor, leftRearMotor, - rightFrontMotor, rightRearMotor); + leftSpeedController = new SpeedControllerGroup(leftFrontMotor, leftRearMotor); + rightSpeedController = new SpeedControllerGroup(rightFrontMotor, rightRearMotor); + differentialDrive = new DifferentialDrive(leftSpeedController, rightSpeedController); rightEncoder = new Encoder(RIGHT_ENCODER_CHANNEL_A, RIGHT_ENCODER_CHANNEL_B); @@ -74,11 +79,11 @@ public Drivetrain() { autoGearShiftingState = true; // Setup PIDController for auto-rotation and aiming - out = new TankDriveOutput(robotDrive); + out = new TankDriveOutput(differentialDrive); gyro = new ADXRS450_Gyro(); - pid = new PIDController(SmartDashboard.getNumber("Gyro P"), - SmartDashboard.getNumber("Gyro I"), - SmartDashboard.getNumber("Gyro D"), gyro, out); + pid = new PIDController(SmartDashboard.getNumber("Gyro P", 0), + SmartDashboard.getNumber("Gyro I", 0), + SmartDashboard.getNumber("Gyro D", 0), gyro, out); pid.setInputRange(0, 360); pid.setContinuous(); // Tell `pid' that 0deg = 360deg pid.setAbsoluteTolerance(MAX_DEGREES_OFF_AUTO_AIMING); @@ -97,7 +102,7 @@ public void initDefaultCommand() { } public void tankDrive(double left, double right) { - robotDrive.tankDrive(left, right); + differentialDrive.tankDrive(left, right); } public double getGyroAngle() { @@ -138,7 +143,7 @@ public void resetEncoders() { } public void stop() { - robotDrive.tankDrive(0.0, 0.0); + differentialDrive.tankDrive(0.0, 0.0); } /** @@ -157,7 +162,7 @@ public void autoGearShift() { sum += currents[i]; } gearUp = sum / currents.length > SmartDashboard - .getNumber("Gear Shifting Threshold"); + .getNumber("Gear Shifting Threshold", 0); gearShift.set(gearUp); gearCounter = 0; } else { @@ -199,10 +204,10 @@ public double getAverageCurrent() { } public void setDrivetrainBrakeMode(boolean on) { - leftFrontMotor.enableBrakeMode(on); - leftRearMotor.enableBrakeMode(on); - rightFrontMotor.enableBrakeMode(on); - rightRearMotor.enableBrakeMode(on); + leftFrontMotor.setNeutralMode(NeutralMode.Brake); + leftRearMotor.setNeutralMode(NeutralMode.Brake); + rightFrontMotor.setNeutralMode(NeutralMode.Brake); + rightRearMotor.setNeutralMode(NeutralMode.Brake); } public void resetGyro() { diff --git a/src/edu/stuy/robot/subsystems/DropDown.java b/src/main/java/edu/stuy/robot/subsystems/DropDown.java similarity index 89% rename from src/edu/stuy/robot/subsystems/DropDown.java rename to src/main/java/edu/stuy/robot/subsystems/DropDown.java index aa8f19a..b61aca8 100644 --- a/src/edu/stuy/robot/subsystems/DropDown.java +++ b/src/main/java/edu/stuy/robot/subsystems/DropDown.java @@ -3,9 +3,12 @@ import static edu.stuy.robot.RobotMap.ACQUIRER_POTENTIOMETER_CHANNEL; import static edu.stuy.robot.RobotMap.DROPDOWN_MOTOR_CHANNEL; import static edu.stuy.robot.RobotMap.DROP_DOWN_DEADBAND; + +import com.ctre.phoenix.motorcontrol.NeutralMode; +import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; + import edu.stuy.robot.commands.DropDownDefaultCommand; import edu.wpi.first.wpilibj.AnalogPotentiometer; -import edu.wpi.first.wpilibj.CANTalon; import edu.wpi.first.wpilibj.command.Subsystem; import edu.wpi.first.wpilibj.interfaces.Potentiometer; import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard; @@ -15,7 +18,7 @@ */ public class DropDown extends Subsystem { - private CANTalon dropDownMotor; + private WPI_TalonSRX dropDownMotor; private Potentiometer potentiometer; public double currentAngle; @@ -23,7 +26,7 @@ public class DropDown extends Subsystem { // here. Call these from Commands. public DropDown() { - dropDownMotor = new CANTalon(DROPDOWN_MOTOR_CHANNEL); + dropDownMotor = new WPI_TalonSRX(DROPDOWN_MOTOR_CHANNEL); dropDownMotor.setInverted(true); potentiometer = new AnalogPotentiometer(ACQUIRER_POTENTIOMETER_CHANNEL, 300, 0); currentAngle = getAngle(); @@ -54,8 +57,8 @@ public double getVoltage() { public double getAngle() { double x = getVoltage(); - double initialVoltage = SmartDashboard.getNumber("Initial Voltage"); - double finalVoltage = SmartDashboard.getNumber("Final Voltage"); + double initialVoltage = SmartDashboard.getNumber("Initial Voltage", 0); + double finalVoltage = SmartDashboard.getNumber("Final Voltage", 0); double conversionFactor = 90.0 / (finalVoltage - initialVoltage); return (x - initialVoltage) * conversionFactor; } @@ -68,7 +71,7 @@ public void lowerAcquirerToDrivingPosition() { } public void setDropDownBreakMode(boolean breakMode) { - dropDownMotor.enableBrakeMode(breakMode); + dropDownMotor.setNeutralMode(NeutralMode.Brake); } /** diff --git a/src/edu/stuy/robot/subsystems/Flashlight.java b/src/main/java/edu/stuy/robot/subsystems/Flashlight.java similarity index 100% rename from src/edu/stuy/robot/subsystems/Flashlight.java rename to src/main/java/edu/stuy/robot/subsystems/Flashlight.java diff --git a/src/edu/stuy/robot/subsystems/Hood.java b/src/main/java/edu/stuy/robot/subsystems/Hood.java similarity index 100% rename from src/edu/stuy/robot/subsystems/Hood.java rename to src/main/java/edu/stuy/robot/subsystems/Hood.java diff --git a/src/edu/stuy/robot/subsystems/Hopper.java b/src/main/java/edu/stuy/robot/subsystems/Hopper.java similarity index 85% rename from src/edu/stuy/robot/subsystems/Hopper.java rename to src/main/java/edu/stuy/robot/subsystems/Hopper.java index 552682b..55737cf 100644 --- a/src/edu/stuy/robot/subsystems/Hopper.java +++ b/src/main/java/edu/stuy/robot/subsystems/Hopper.java @@ -4,10 +4,12 @@ import static edu.stuy.robot.RobotMap.HOPPER_SENSOR_CHANNEL; import static edu.stuy.robot.RobotMap.HOPPER_SENSOR_THRESHOLD; +import com.ctre.phoenix.motorcontrol.NeutralMode; +import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; + import edu.stuy.robot.Robot; import edu.stuy.robot.commands.HopperStopCommand; import edu.wpi.first.wpilibj.AnalogInput; -import edu.wpi.first.wpilibj.CANTalon; import edu.wpi.first.wpilibj.command.Subsystem; /** @@ -16,11 +18,11 @@ public class Hopper extends Subsystem { // Put methods for controlling this subsystem // here. Call these from Commands. - private CANTalon hopperMotor; + private WPI_TalonSRX hopperMotor; private AnalogInput distanceSensor; public Hopper() { - hopperMotor = new CANTalon(HOPPER_MOTOR_CHANNEL); + hopperMotor = new WPI_TalonSRX(HOPPER_MOTOR_CHANNEL); hopperMotor.setInverted(true); distanceSensor = new AnalogInput(HOPPER_SENSOR_CHANNEL); } @@ -43,7 +45,7 @@ public void stop() { } public void setHopperBrakeMode(boolean on) { - hopperMotor.enableBrakeMode(on); + hopperMotor.setNeutralMode(NeutralMode.Brake); } public double getDistance() { diff --git a/src/edu/stuy/robot/subsystems/Shooter.java b/src/main/java/edu/stuy/robot/subsystems/Shooter.java similarity index 89% rename from src/edu/stuy/robot/subsystems/Shooter.java rename to src/main/java/edu/stuy/robot/subsystems/Shooter.java index 322284b..fa4e078 100644 --- a/src/edu/stuy/robot/subsystems/Shooter.java +++ b/src/main/java/edu/stuy/robot/subsystems/Shooter.java @@ -2,7 +2,11 @@ import static edu.stuy.robot.RobotMap.SHOOTER_ENCODER_MAXSPEED; import static edu.stuy.robot.RobotMap.SHOOTER_MOTOR_CHANNEL; -import edu.wpi.first.wpilibj.CANTalon; + +import com.ctre.phoenix.motorcontrol.NeutralMode; +import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX; +import com.ctre.phoenix.motorcontrol.can.WPI_VictorSPX; + import edu.wpi.first.wpilibj.Timer; import edu.wpi.first.wpilibj.command.Subsystem; @@ -15,12 +19,12 @@ */ public class Shooter extends Subsystem { - private CANTalon shooterMotor; + private WPI_VictorSPX shooterMotor; public double currentSpeed; public Shooter() { - shooterMotor = new CANTalon(SHOOTER_MOTOR_CHANNEL); + shooterMotor = new WPI_VictorSPX(SHOOTER_MOTOR_CHANNEL); currentSpeed = 1.0; /* * shooterMotor.setFeedbackDevice(FeedbackDevice.CtreMagEncoder_Relative @@ -54,7 +58,7 @@ public void stop() { * public void setSpeedHigh() { setRPM(SHOOTER_ENCODER_MAXSPEED - 400.0); } */ public double getCurrentMotorSpeedInRPM() { - return shooterMotor.getSpeed(); + return shooterMotor.getSelectedSensorVelocity(0); } // Use the encoders to verify the speed @@ -97,7 +101,7 @@ public void setSpeedReliablyVBus(double speed) { } public void setShooterBrakeMode(boolean on) { - shooterMotor.enableBrakeMode(on); + shooterMotor.setNeutralMode(NeutralMode.Brake); } public void initDefaultCommand() { diff --git a/src/edu/stuy/robot/subsystems/Sonar.java b/src/main/java/edu/stuy/robot/subsystems/Sonar.java similarity index 100% rename from src/edu/stuy/robot/subsystems/Sonar.java rename to src/main/java/edu/stuy/robot/subsystems/Sonar.java diff --git a/src/edu/stuy/util/BoolBox.java b/src/main/java/edu/stuy/util/BoolBox.java similarity index 100% rename from src/edu/stuy/util/BoolBox.java rename to src/main/java/edu/stuy/util/BoolBox.java diff --git a/src/main/java/edu/stuy/util/Gamepad.java b/src/main/java/edu/stuy/util/Gamepad.java new file mode 100644 index 0000000..6a17597 --- /dev/null +++ b/src/main/java/edu/stuy/util/Gamepad.java @@ -0,0 +1,605 @@ +package edu.stuy.util; + +import edu.wpi.first.wpilibj.DriverStation; +import edu.wpi.first.wpilibj.GenericHID; +import edu.wpi.first.wpilibj.Joystick; +import edu.wpi.first.wpilibj.buttons.Button; +import edu.wpi.first.wpilibj.buttons.JoystickButton; + +/** + * Class for both the Logitech Dual Action 2 Gamepad and the Logitech Gamepad + * F310. This class also works with the Logitech Wireless Gamepad F710, and on + * the PS4 Wireless controller (the PS4 also comes with an extra button and 2 + * extra axis for the bumpers) + * + * @author wangmeister + */ + +public class Gamepad extends Joystick { + // Threshold for whether we're "pressing" the trigger + private static final double RAW_TRIGGER_PRESS_AXIS_THRESHOLD = 0.1; + + // On the back of the logitech controller there is a switch. + // "X" gives you access to the axis inputs + public enum GamepadSwitchMode { + SWITCH_X, SWITCH_D, PS4, // PS4 Controller Enum. + AUTO_DETECT + } + + private GamepadSwitchMode switchMode; + private int port; + private int controllerType; + private boolean isAutoDetect; + + public Gamepad(int port, GamepadSwitchMode switchMode) { + super(port); + this.port = port; + this.isAutoDetect = false; + if (switchMode == GamepadSwitchMode.AUTO_DETECT) { + this.isAutoDetect = true; + resetGamepadType(); + } else { + this.switchMode = switchMode; + } + } + + // Defaults to D mode (for backwards compatibility) + public Gamepad(int port) { + this(port, GamepadSwitchMode.SWITCH_D); + } + + // Debugging + public String getGamepadType() { + return switchMode.name(); + } + /** + * Resets the type of the gamepad (Not expensive) + */ + public void resetGamepadType() { + if (isAutoDetect) { + controllerType = DriverStation.getInstance().getJoystickType(port); + switch (controllerType) { + case 20: + switchMode = GamepadSwitchMode.SWITCH_D; + break; + case 21: + switchMode = GamepadSwitchMode.PS4; + break; + default: + // Make sure the code doesn't break when this gamepad is called + // SWITCH_X has a controller type of 21 + switchMode = GamepadSwitchMode.SWITCH_X; + } + } + } + + /** + * The left analog stick x-axis. + * + * @return value of left analog x-axis + */ + public double getLeftX() { + return getRawAxis(0); + } + + /** + * The left analog stick y-axis. + * + * @return value of left analog y-axis (pushing stick up is positive) + */ + public double getLeftY() { + return -getRawAxis(1); + } + + /** + * The right analog stick x-axis. + * + * @return value of right analog x-axis + */ + public double getRightX() { + switch (switchMode) { + case SWITCH_D: + return getRawAxis(4); + case SWITCH_X: + return getRawAxis(4); + case PS4: + return getRawAxis(2); + default: + return 0; + } + } + + /** + * The right analog stick y-axis. + * + * @return value of right analog y-axis (pushing stick up is positive) + */ + public double getRightY() { + switch (switchMode) { + case SWITCH_D: + return -getRawAxis(3); + case SWITCH_X: + case PS4: + return -getRawAxis(5); + default: + return 0; + } + } + + /** + * The upper d-pad button. + * + * @return if upper d-pad button is pressed + */ + public boolean getRawDPadUp() { + return getPOV() == 0; + } + + public DPadButton getDPadUp() { + return new DPadButton(this, DPadButton.Direction.UP); + } + + /** + * The lower d-pad button. + * + * @return if the lower d-pad button is pressed + */ + public boolean getRawDPadDown() { + return getPOV() == 180; + } + + public DPadButton getDPadDown() { + return new DPadButton(this, DPadButton.Direction.DOWN); + } + + /** + * The left d-pad button. + * + * @return if the left d-pad button is pressed + */ + public boolean getRawDPadLeft() { + return getPOV() == 270; + } + + public DPadButton getDPadLeft() { + return new DPadButton(this, DPadButton.Direction.LEFT); + } + + /** + * The right d-pad button. + * + * @return if the right d-pad button is pressed + */ + public boolean getRawDPadRight() { + return getPOV() == 90; + } + + public DPadButton getDPadRight() { + return new DPadButton(this, DPadButton.Direction.RIGHT); + } + + /** + * The left bumper. + * + * @return if the left bumper is pressed + */ + public boolean getRawLeftBumper() { + return getRawButton(5); + } + + public JoystickButton getLeftBumper() { + return new JoystickButton(this, 5); + } + + /** + * The right bumper. + * + * @return if the right bumper is pressed + */ + public boolean getRawRightBumper() { + return getRawButton(6); + } + + public JoystickButton getRightBumper() { + return new JoystickButton(this, 6); + } + + /** + * The left trigger: analog + * + * @return how far we've pushed the trigger down (0: none, 1: all the way) + */ + public double getRawLeftTriggerAxis() { + switch (switchMode) { + case SWITCH_D: + // Turn digital input into on/off analog + return getRawLeftTrigger() ? 1 : 0; + case SWITCH_X: + return getRawAxis(2); + case PS4: + return (getRawAxis(3) + 1) / 2; + default: + return 0; + } + } + + /** + * The left trigger: digital + * + * @return if the left trigger is pressed + */ + public boolean getRawLeftTrigger() { + switch (switchMode) { + case SWITCH_D: + return getRawButton(7); + case SWITCH_X: + case PS4: + return getRawLeftTriggerAxis() > RAW_TRIGGER_PRESS_AXIS_THRESHOLD; + default: + return false; + } + } + + public Button getLeftTrigger() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 7); + case SWITCH_X: + return new LeftTriggerButton(this); + default: + return null; + } + } + + /** + * The right trigger: analog + * + * @return how far we've pushed the trigger down (0: none, 1: all the way) + */ + public double getRawRightTriggerAxis() { + switch (switchMode) { + case SWITCH_D: + // Turn digital input into on/off analog + return getRawLeftTrigger() ? 1 : 0; + case SWITCH_X: + return getRawAxis(3); + case PS4: + return (getRawAxis(4) + 1) / 2; + default: + return 0; + } + } + + /** + * The left trigger: digital + * + * @return if the left trigger is pressed + */ + public boolean getRawRightTrigger() { + switch (switchMode) { + case SWITCH_D: + return getRawButton(8); + case SWITCH_X: + case PS4: + return getRawRightTriggerAxis() > RAW_TRIGGER_PRESS_AXIS_THRESHOLD; + default: + return false; + } + } + + public Button getRightTrigger() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 8); + case SWITCH_X: + return new RightTriggerButton(this); + default: + return null; + } + } + + /** + * The left button of the button group. On some gamepads this is X. + * + * @return if the left button is pressed + */ + public boolean getRawLeftButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(1); + case SWITCH_X: + return getRawButton(3); + default: + return false; + } + } + + public JoystickButton getLeftButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 1); + case SWITCH_X: + return new JoystickButton(this, 3); + default: + return null; + } + } + + /** + * The bottom button of the button group. On some gamepads this is A. + * + * @return if the bottom button is pressed + */ + public boolean getRawBottomButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(2); + case SWITCH_X: + return getRawButton(1); + default: + return false; + } + } + + public JoystickButton getBottomButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 2); + case SWITCH_X: + return new JoystickButton(this, 1); + default: + return null; + } + } + + /** + * The right button of the button group. On some gamepads this is B. + * + * @return if the right button is pressed + */ + public boolean getRawRightButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(3); + case SWITCH_X: + return getRawButton(2); + default: + return false; + } + } + + public JoystickButton getRightButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 3); + case SWITCH_X: + return new JoystickButton(this, 2); + default: + return null; + } + } + + /** + * The top button of the button group. On some gamepads this is Y. + * + * @return if the top button is pressed + */ + public boolean getRawTopButton() { + return getRawButton(4); + } + + public JoystickButton getTopButton() { + return new JoystickButton(this, 4); + } + + /** + * The central left button. On some gamepads this is the select button. + * + * @return if the back button is pressed + */ + public boolean getRawSelectButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(9); + case SWITCH_X: + return getRawButton(7); + default: + return false; + } + } + + public JoystickButton getSelectButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 9); + case SWITCH_X: + return new JoystickButton(this, 7); + default: + return null; + } + } + + /** + * The central right button. On some gamepads this is the start button. + * + * @return if the start button is pressed + */ + public boolean getRawStartButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(10); + case SWITCH_X: + return getRawButton(8); + default: + return false; + } + } + + public JoystickButton getStartButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 10); + case SWITCH_X: + return new JoystickButton(this, 8); + default: + return null; + } + } + + /** + * The click-function of the left analog stick. + * + * @return if the left analog stick is being clicked down + */ + public boolean getRawLeftAnalogButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(11); + case SWITCH_X: + return getRawButton(9); + default: + return false; + } + } + + public JoystickButton getLeftAnalogButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 11); + case SWITCH_X: + return new JoystickButton(this, 9); + default: + return null; + } + } + + /** + * The click-function of the right analog stick. + * + * @return if the right analog stick is being clicked down + */ + public boolean getRawRightAnalogButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return getRawButton(12); + case SWITCH_X: + return getRawButton(10); + default: + return false; + } + } + + public JoystickButton getRightAnalogButton() { + switch (switchMode) { + case SWITCH_D: + case PS4: + return new JoystickButton(this, 12); + case SWITCH_X: + return new JoystickButton(this, 10); + default: + return null; + } + } + + public boolean getRawOptionButton() { + switch (switchMode) { + case PS4: + return getRawButton(10); + case SWITCH_D: + case SWITCH_X: + default: + return false; + } + } + + /** + * DPadButton Class + * + * Lets us treat the D-Pad axis as individual buttons + */ + public static class DPadButton extends Button { + public static enum Direction { + UP, DOWN, LEFT, RIGHT + } + + private Gamepad gamepad; + private Direction direction; + + public DPadButton(Gamepad gamepad, Direction direction) { + this.gamepad = gamepad; + this.direction = direction; + } + + @Override + public boolean get() { + switch (direction) { + case UP: + return gamepad.getRawDPadUp(); + case DOWN: + return gamepad.getRawDPadDown(); + case LEFT: + return gamepad.getRawDPadLeft(); + case RIGHT: + return gamepad.getRawDPadRight(); + default: // Never reached + return false; + } + } + } + + /** + * LeftTriggerButton Class + * + * Lets us treat the Left trigger as an individual button in SWITCH_X mode + */ + public static class LeftTriggerButton extends Button { + private Gamepad gamepad; + + public LeftTriggerButton(Gamepad gamepad) { + this.gamepad = gamepad; + } + + @Override + public boolean get() { + return gamepad.getRawLeftTrigger(); + } + } + + /** + * RightTriggerButton Class + * + * Lets us treat the right trigger as an individual button in SWITCH_X mode + */ + public static class RightTriggerButton extends Button { + private Gamepad gamepad; + + public RightTriggerButton(Gamepad gamepad) { + this.gamepad = gamepad; + } + + @Override + public boolean get() { + return gamepad.getRawRightTrigger(); + } + } + + public void rumble(double intensity) { + setRumble(GenericHID.RumbleType.kLeftRumble, intensity); + setRumble(GenericHID.RumbleType.kRightRumble, intensity); + } +} \ No newline at end of file diff --git a/src/edu/stuy/util/SignalLight.java b/src/main/java/edu/stuy/util/SignalLight.java similarity index 100% rename from src/edu/stuy/util/SignalLight.java rename to src/main/java/edu/stuy/util/SignalLight.java diff --git a/src/edu/stuy/util/TankDriveOutput.java b/src/main/java/edu/stuy/util/TankDriveOutput.java similarity index 75% rename from src/edu/stuy/util/TankDriveOutput.java rename to src/main/java/edu/stuy/util/TankDriveOutput.java index 0b8cc61..e5aec26 100644 --- a/src/edu/stuy/util/TankDriveOutput.java +++ b/src/main/java/edu/stuy/util/TankDriveOutput.java @@ -1,15 +1,16 @@ package edu.stuy.util; import static edu.stuy.robot.RobotMap.PID_MAX_ROBOT_SPEED; + import edu.wpi.first.wpilibj.PIDOutput; -import edu.wpi.first.wpilibj.RobotDrive; +import edu.wpi.first.wpilibj.drive.DifferentialDrive; public class TankDriveOutput implements PIDOutput { - private RobotDrive pidDrive; + private DifferentialDrive pidDrive; private double maxValue; - public TankDriveOutput(RobotDrive drive) { + public TankDriveOutput(DifferentialDrive drive) { pidDrive = drive; maxValue = PID_MAX_ROBOT_SPEED; } diff --git a/src/edu/stuy/util/ThreeLaws.java b/src/main/java/edu/stuy/util/ThreeLaws.java similarity index 100% rename from src/edu/stuy/util/ThreeLaws.java rename to src/main/java/edu/stuy/util/ThreeLaws.java diff --git a/vendordeps/Phoenix.json b/vendordeps/Phoenix.json new file mode 100644 index 0000000..d4da1ce --- /dev/null +++ b/vendordeps/Phoenix.json @@ -0,0 +1,87 @@ +{ + "fileName": "Phoenix.json", + "name": "CTRE-Phoenix", + "version": "5.12.0", + "uuid": "ab676553-b602-441f-a38d-f1296eff6537", + "mavenUrls": [ + "http://devsite.ctr-electronics.com/maven/release/" + ], + "jsonUrl": "http://devsite.ctr-electronics.com/maven/release/com/ctre/phoenix/Phoenix-latest.json", + "javaDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-java", + "version": "5.12.0" + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-java", + "version": "5.12.0" + } + ], + "jniDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.12.0", + "isJar": false, + "skipInvalidPlatforms": true, + "validPlatforms": [ + "linuxathena", + "windowsx86-64", + "linuxx86-64" + ] + } + ], + "cppDependencies": [ + { + "groupId": "com.ctre.phoenix", + "artifactId": "wpiapi-cpp", + "version": "5.12.0", + "libName": "CTRE_Phoenix_WPI", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "windowsx86-64", + "linuxx86-64" + ] + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "api-cpp", + "version": "5.12.0", + "libName": "CTRE_Phoenix", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "windowsx86-64", + "linuxx86-64" + ] + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "cci", + "version": "5.12.0", + "libName": "CTRE_PhoenixCCI", + "headerClassifier": "headers", + "sharedLibrary": false, + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena", + "windowsx86-64", + "linuxx86-64" + ] + }, + { + "groupId": "com.ctre.phoenix", + "artifactId": "core", + "version": "5.12.0", + "libName": "CTRE_PhoenixCore", + "headerClassifier": "headers" + } + ] +} \ No newline at end of file diff --git a/vendordeps/navx_frc.json b/vendordeps/navx_frc.json new file mode 100644 index 0000000..80defba --- /dev/null +++ b/vendordeps/navx_frc.json @@ -0,0 +1,33 @@ +{ + "fileName": "navx_frc.json", + "name": "KauaiLabs_navX_FRC", + "version": "3.1.344", + "uuid": "cb311d09-36e9-4143-a032-55bb2b94443b", + "mavenUrls": [ + "https://repo1.maven.org/maven2/" + ], + "jsonUrl": "https://www.kauailabs.com/dist/frc/2019/navx_frc.json", + "javaDependencies": [ + { + "groupId": "com.kauailabs.navx.frc", + "artifactId": "navx-java", + "version": "3.1.344" + } + ], + "jniDependencies": [], + "cppDependencies": [ + { + "groupId": "com.kauailabs.navx.frc", + "artifactId": "navx-cpp", + "version": "3.1.344", + "headerClassifier": "headers", + "sourcesClassifier": "sources", + "sharedLibrary": false, + "libName": "navx_frc", + "skipInvalidPlatforms": true, + "binaryPlatforms": [ + "linuxathena" + ] + } + ] +} \ No newline at end of file