diff --git a/.gitignore b/.gitignore
index f9394a280..06e0ca5f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -121,3 +121,4 @@ New client/chameleon-client/*
*.jfr
.DS_Store
# *.iml
+chameleon-server/build
diff --git a/chameleon-server/build.gradle b/chameleon-server/build.gradle
new file mode 100644
index 000000000..3400252d8
--- /dev/null
+++ b/chameleon-server/build.gradle
@@ -0,0 +1,86 @@
+plugins {
+ id 'java'
+ id 'com.github.johnrengelman.shadow' version '5.2.0'
+}
+
+shadowJar {
+ baseName = 'shadow'
+ configurations = [project.configurations.compile]
+ classifier = ''
+ archiveVersion = ''
+}
+
+group 'com.chameleonvision'
+version '1.0-SNAPSHOT'
+
+sourceCompatibility = 11
+
+repositories {
+ mavenCentral()
+ maven {
+ url = 'https://frcmaven.wpi.edu:443/artifactory/release'
+ }
+}
+ext {
+ wpilibVersion = '2020.2.2'
+ openCVVersion = '3.4.7-2'
+}
+
+dependencies {
+ implementation "io.javalin:javalin:3.7.0"
+
+ implementation "com.fasterxml.jackson.core:jackson-annotations:2.10.0"
+ implementation "com.fasterxml.jackson.core:jackson-core:2.10.0"
+ implementation "com.fasterxml.jackson.core:jackson-databind:2.10.0"
+
+ implementation "org.msgpack:msgpack-core:0.8.20"
+ implementation "org.msgpack:jackson-dataformat-msgpack:0.8.20"
+
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9'
+ implementation "org.apache.commons:commons-math3:3.6.1"
+ implementation group: 'commons-io', name: 'commons-io', version: '2.6'
+ implementation "org.apache.commons:commons-collections4:4.4"
+ implementation "org.apache.commons:commons-exec:1.3"
+
+ implementation "com.moandjiezana.toml:toml4j:0.7.2"
+
+ // javacv
+ compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.5.2'
+
+ // wpilib stuff
+ implementation "edu.wpi.first.wpiutil:wpiutil-java:$wpilibVersion"
+ implementation "edu.wpi.first.cameraserver:cameraserver-java:$wpilibVersion"
+
+ implementation "edu.wpi.first.cscore:cscore-java:$wpilibVersion"
+ compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxaarch64bionic"
+ compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxraspbian"
+ compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxx86-64"
+ compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:osxx86-64"
+ compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:windowsx86-64"
+
+ implementation "edu.wpi.first.ntcore:ntcore-java:$wpilibVersion"
+ compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxaarch64bionic"
+ compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxraspbian"
+ compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxx86-64"
+ compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:osxx86-64"
+ compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:windowsx86-64"
+
+ implementation "edu.wpi.first.thirdparty.frc2020.opencv:opencv-java:$openCVVersion"
+ compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxaarch64bionic"
+ compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxraspbian"
+ compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxx86-64"
+ compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:osxx86-64"
+ compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:windowsx86-64"
+
+ // test stuff
+ testImplementation('org.junit.jupiter:junit-jupiter:5.6.0')
+}
+
+test {
+ test {
+ useJUnitPlatform()
+ testLogging {
+ events "passed", "skipped", "failed"
+ }
+ }
+}
\ No newline at end of file
diff --git a/chameleon-server/chameleon-vision.iml b/chameleon-server/chameleon-vision.iml
deleted file mode 100644
index 41084fba0..000000000
--- a/chameleon-server/chameleon-vision.iml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/chameleon-server/gradle/wrapper/gradle-wrapper.properties b/chameleon-server/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..9ae0a13b0
--- /dev/null
+++ b/chameleon-server/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Feb 20 23:05:11 EST 2020
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/chameleon-server/gradlew b/chameleon-server/gradlew
new file mode 100644
index 000000000..af6708ff2
--- /dev/null
+++ b/chameleon-server/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/chameleon-server/gradlew.bat b/chameleon-server/gradlew.bat
new file mode 100644
index 000000000..6d57edc70
--- /dev/null
+++ b/chameleon-server/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/chameleon-server/pom.xml b/chameleon-server/pom.xml
deleted file mode 100644
index 94b7b4e83..000000000
--- a/chameleon-server/pom.xml
+++ /dev/null
@@ -1,269 +0,0 @@
-
-
- 4.0.0
- org.chameleon-vision.main
- chameleon-vision
-
- 2.3.2
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.0
-
- 12
- 12
- true
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 3.2.1
-
-
- package
-
- shade
-
-
-
-
- com.chameleonvision.Main
-
-
-
-
-
-
-
-
-
- UTF-8
- 2020.2.2
- 3.4.7-2
-
-
- 12
-
-
-
- WPI
- WPILib Artifactory Server-releases
- https://frcmaven.wpi.edu:443/artifactory/release
-
-
-
-
-
- io.javalin
- javalin
- RELEASE
-
-
-
-
- org.json
- json
- 20190722
-
-
-
-
- org.slf4j
- slf4j-nop
- 1.7.26
-
-
-
-
- org.apache.commons
- commons-math3
- 3.6.1
-
-
- commons-io
- commons-io
- RELEASE
-
-
- org.msgpack
- msgpack-core
- 0.8.18
-
-
- org.msgpack
- jackson-dataformat-msgpack
- 0.8.18
-
-
- org.apache.commons
- commons-lang3
- 3.9
-
-
-
- com.fasterxml.jackson.core
- jackson-core
- 2.10.1
-
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- 2.10.1
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
- 2.10.1
-
-
-
- org.junit.jupiter
- junit-jupiter-engine
- 5.5.2
-
-
-
-
-
- edu.wpi.first.cscore
- cscore-java
- ${wpilib.version}
-
-
-
- edu.wpi.first.cscore
- cscore-jni
- ${wpilib.version}
- linuxaarch64bionic
-
-
- edu.wpi.first.cscore
- cscore-jni
- ${wpilib.version}
- linuxraspbian
-
-
- edu.wpi.first.cscore
- cscore-jni
- ${wpilib.version}
- linuxx86-64
-
-
- edu.wpi.first.cscore
- cscore-jni
- ${wpilib.version}
- osxx86-64
-
-
- edu.wpi.first.cscore
- cscore-jni
- ${wpilib.version}
- windowsx86-64
-
-
-
-
- edu.wpi.first.cameraserver
- cameraserver-java
- ${wpilib.version}
-
-
-
-
- edu.wpi.first.ntcore
- ntcore-java
- ${wpilib.version}
-
-
-
-
- edu.wpi.first.ntcore
- ntcore-jni
- ${wpilib.version}
- osxx86-64
-
-
- edu.wpi.first.ntcore
- ntcore-jni
- ${wpilib.version}
- linuxraspbian
-
-
- edu.wpi.first.ntcore
- ntcore-jni
- ${wpilib.version}
- linuxx86-64
-
-
- edu.wpi.first.ntcore
- ntcore-jni
- ${wpilib.version}
- linuxaarch64bionic
-
-
- edu.wpi.first.ntcore
- ntcore-jni
- ${wpilib.version}
- windowsx86-64
-
-
-
-
- edu.wpi.first.wpiutil
- wpiutil-java
- ${wpilib.version}
-
-
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-java
- ${opencv.version}
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-jni
- ${opencv.version}
- linuxaarch64bionic
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-jni
- ${opencv.version}
- linuxraspbian
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-jni
- ${opencv.version}
- linuxx86-64
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-jni
- ${opencv.version}
- osxx86-64
-
-
- edu.wpi.first.thirdparty.frc2020.opencv
- opencv-jni
- ${opencv.version}
- windowsx86-64
-
-
-
diff --git a/chameleon-server/settings.gradle b/chameleon-server/settings.gradle
new file mode 100644
index 000000000..c1d0ca741
--- /dev/null
+++ b/chameleon-server/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'ChameleonVision'
+
diff --git a/chameleon-server/src/main/java/com/chameleonvision/Debug.java b/chameleon-server/src/main/java/com/chameleonvision/Debug.java
deleted file mode 100644
index b90b7d75f..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/Debug.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.chameleonvision;
-
-public class Debug {
- private Debug() {}
-
- private static boolean isTestMode() {
- return Main.testMode;
- }
-
- public static void printInfo(String infoMessage) {
- if (isTestMode()) {
- System.out.println(infoMessage);
- }
- }
-
- public static void printInfo(String smallInfo, String largeInfo) {
- System.out.println(isTestMode() ? String.format("%s - %s" , smallInfo, largeInfo) : smallInfo);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/Exceptions/DuplicatedKeyException.java b/chameleon-server/src/main/java/com/chameleonvision/Exceptions/DuplicatedKeyException.java
deleted file mode 100644
index dc54ae95a..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/Exceptions/DuplicatedKeyException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.chameleonvision.Exceptions;
-
-public class DuplicatedKeyException extends Exception{
- public DuplicatedKeyException(String message){
- super(message);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/Main.java b/chameleon-server/src/main/java/com/chameleonvision/Main.java
deleted file mode 100644
index 08d68a714..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/Main.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package com.chameleonvision;
-
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.network.NetworkManager;
-import com.chameleonvision.networktables.NetworkTablesManager;
-import com.chameleonvision.scripting.ScriptEventType;
-import com.chameleonvision.scripting.ScriptManager;
-import com.chameleonvision.util.Platform;
-import com.chameleonvision.util.Utilities;
-import com.chameleonvision.vision.VisionManager;
-import com.chameleonvision.web.Server;
-import edu.wpi.cscore.CameraServerCvJNI;
-import edu.wpi.cscore.CameraServerJNI;
-
-import java.io.IOException;
-
-import static com.chameleonvision.util.Platform.CurrentPlatform;
-
-public class Main {
-
- private static final String NT_SERVERMODE_KEY = "--nt-servermode"; // no args for this setting
- private static final String NT_CLIENTMODESERVER_KEY = "--nt-client-server"; // expects String representing an IP address (hostnames will be rejected!)
- private static final String NETWORK_MANAGE_KEY = "--unmanage-network"; // no args for this setting
- private static final String IGNORE_ROOT_KEY = "--ignore-root"; // no args for this setting
- private static final String TEST_MODE_KEY = "--cv-development";
- private static final String UI_PORT_KEY = "--ui-port";
-
- private static final int DEFAULT_PORT = 5800;
-
- private static boolean ntServerMode = false;
- private static boolean manageNetwork = true;
- private static boolean ignoreRoot = false;
- private static String ntClientModeServer = null;
- public static boolean testMode = false;
- public static int uiPort = DEFAULT_PORT;
-
- private static void handleArgs(String[] args) {
- for (int i = 0; i < args.length; i++) {
- var key = args[i].toLowerCase();
- String value = null;
-
- // this switch handles arguments with a value. Add any settings with a value here.
- switch (key) {
- case NT_CLIENTMODESERVER_KEY:
- var potentialValue = args[i + 1];
- // ensures this "value" isnt null, blank, nor another argument
- if (potentialValue != null && !potentialValue.isBlank() && !potentialValue.startsWith("-") & !potentialValue.startsWith("--")) {
- value = potentialValue.toLowerCase();
- }
- i++; // increment to skip an 'arg' next go-around of for loop, as that would be this value
- break;
- case UI_PORT_KEY:
- var potentialPort = args[i + 1];
- if (potentialPort != null && !potentialPort.isBlank() && !potentialPort.startsWith("-") & !potentialPort.startsWith("--")) {
- value = potentialPort;
- }
- i++;
- break;
- case NT_SERVERMODE_KEY:
- case NETWORK_MANAGE_KEY:
- case IGNORE_ROOT_KEY:
- case TEST_MODE_KEY:
- // nothing
- break;
- }
-
- // this switch actually handles the arguments.
- switch (key) {
- case NT_SERVERMODE_KEY:
- ntServerMode = true;
- break;
- case NT_CLIENTMODESERVER_KEY:
- if (value != null) {
- if (value.equals("localhost")) {
- ntClientModeServer = "127.0.0.1";
- continue;
- }
-
- if (Utilities.isValidIPV4(value)) {
- ntClientModeServer = value;
- continue;
- }
- }
- System.err.println("Argument for NT Server Host was invalid, defaulting to team number host");
- break;
- case NETWORK_MANAGE_KEY:
- manageNetwork = false;
- break;
- case IGNORE_ROOT_KEY:
- ignoreRoot = true;
- break;
- case TEST_MODE_KEY:
- testMode = true;
- break;
- case UI_PORT_KEY:
- if (value != null) {
- try {
- uiPort = Integer.parseInt(value);
- } catch (NumberFormatException e){
- System.err.println("ui Port was not a valid number using port 5800");
- }
- }
- break;
- }
- }
- }
-
- public static void main(String[] args) {
-
- Runtime.getRuntime().addShutdownHook(new Thread(() -> ScriptManager.queueEvent(ScriptEventType.kProgramExit)));
-
- if (CurrentPlatform.equals(Platform.UNSUPPORTED)) {
- System.err.printf("Sorry, this platform is not supported. Give these details to the developers.\n%s\n", CurrentPlatform.toString());
- return;
- } else {
- System.out.printf("Starting Chameleon Vision on platform %s\n", CurrentPlatform.toString());
- }
-
- handleArgs(args);
-
- if (!CurrentPlatform.isRoot()) {
- if (ignoreRoot) {
- // manageNetwork = false;
- System.out.println("Ignoring root, network will not be managed!");
- } else {
- System.err.println("This program must be run as root!");
- return;
- }
- }
-
- // Attempt to load the JNI Libraries
- System.out.println("Loading CameraServer...");
- try {
- CameraServerJNI.forceLoad();
- CameraServerCvJNI.forceLoad();
- } catch (UnsatisfiedLinkError | IOException e) {
- if (CurrentPlatform.isWindows()) {
- System.err.println("Try to download the VC++ Redistributable, https://aka.ms/vs/16/release/vc_redist.x64.exe");
- }
- throw new RuntimeException("Failed to load JNI Libraries!");
- }
-
- System.out.println("Checking Settings...");
- ConfigManager.initializeSettings();
-
- if (!CurrentPlatform.isWindows()) {
- System.out.println("Initializing Script Manager...");
- ScriptManager.initialize();
- } else {
- System.out.println("Scripts not yet supported on Windows. ScriptEvents will be ignored.");
- }
-
- NetworkManager.initialize(manageNetwork);
-
- if (ntServerMode) {
- NetworkTablesManager.setServerMode();
- } else {
- NetworkTablesManager.setClientMode(ntClientModeServer);
- }
-
- ScriptManager.queueEvent(ScriptEventType.kProgramInit);
-
- boolean visionSourcesOk = VisionManager.initializeSources();
- if (!visionSourcesOk) {
- System.err.println("No cameras connected!");
- return;
- }
-
- boolean visionProcessesOk = VisionManager.initializeProcesses();
- if (!visionProcessesOk) {
- System.err.println("Failed to initialize vision processes!");
- return;
- }
-
- System.out.println("Starting vision processes...");
- VisionManager.startProcesses();
-
- System.out.printf("Starting Web server at port %d\n", uiPort);
- Server.main(uiPort);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFile.java b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFile.java
new file mode 100644
index 000000000..944740039
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFile.java
@@ -0,0 +1,12 @@
+package com.chameleonvision.common.configuration;
+
+public class ConfigFile {
+
+ /**
+ * Represents a config file at a fixed path
+ * @param path Path to config file
+ */
+ public ConfigFile(String path) {
+
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFolder.java b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFolder.java
new file mode 100644
index 000000000..67d060410
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigFolder.java
@@ -0,0 +1,12 @@
+package com.chameleonvision.common.configuration;
+
+public class ConfigFolder {
+
+ /**
+ * Represents a folder of config files
+ * @param path path to config file
+ */
+ public ConfigFolder(String path) {
+
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigManager.java b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigManager.java
new file mode 100644
index 000000000..2b5ea6f2e
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/configuration/ConfigManager.java
@@ -0,0 +1,24 @@
+package com.chameleonvision.common.configuration;
+
+import com.chameleonvision.common.server.configuration.MainConfig;
+
+public class ConfigManager {
+
+ private final ConfigFolder rootFolder;
+ final MainConfig mainConfig;
+
+ protected ConfigManager() {
+
+ rootFolder = new ConfigFolder("");
+
+ mainConfig = MainConfig.getInstance();
+ }
+
+ private static class SingletonHolder {
+ private static final ConfigManager INSTANCE = new ConfigManager();
+ }
+
+ public static ConfigManager getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/common/network/LinuxNetworking.java
similarity index 92%
rename from chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java
rename to chameleon-server/src/main/java/com/chameleonvision/common/network/LinuxNetworking.java
index 47ae1a47d..13628893b 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/LinuxNetworking.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/network/LinuxNetworking.java
@@ -1,4 +1,4 @@
-package com.chameleonvision.network;
+package com.chameleonvision.common.network;
import org.apache.commons.io.FileUtils;
@@ -44,7 +44,7 @@ public class LinuxNetworking extends SysNetworking {
}
} else {
- System.err.println("dhcpcd5 is not installed cant set ip");
+ System.err.println("dhcpcd5 is not installed, unable to set IP.");
return false;
}
return true;
@@ -52,9 +52,8 @@ public class LinuxNetworking extends SysNetworking {
@Override
public boolean setHostname(String newHostname) {
- String[] setHostnameArgs = {"set-hostname", newHostname};
try {
- var setHostnameRetCode = shell.execute("hostnamectl", setHostnameArgs);
+ var setHostnameRetCode = shell.execute("hostnamectl", "set-hostname", newHostname);
return setHostnameRetCode == 0;
} catch (Exception e) {
e.printStackTrace();
@@ -70,7 +69,7 @@ public class LinuxNetworking extends SysNetworking {
List lines = FileUtils.readLines(dhcpConf, StandardCharsets.UTF_8);
lines.add("interface " + networkInterface.name);
InetAddress iNetMask = InetAddress.getByName(netmask);
- int prefix = NetmaskToCIDR.convertNetmaskToCIDR(iNetMask);
+ int prefix = convertNetmaskToCIDR(iNetMask);
lines.add("static ip_address=" + ipAddress + "/" + prefix);
lines.add("static routers=" + gateway);
FileUtils.writeLines(dhcpConf, lines);
@@ -81,7 +80,6 @@ public class LinuxNetworking extends SysNetworking {
return false;
}
-
@Override
public List getNetworkInterfaces() throws SocketException {
List netInterfaces;
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkInterface.java b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkInterface.java
similarity index 69%
rename from chameleon-server/src/main/java/com/chameleonvision/network/NetworkInterface.java
rename to chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkInterface.java
index 7eedcfc88..99b9bc91a 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkInterface.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkInterface.java
@@ -1,22 +1,22 @@
-package com.chameleonvision.network;
+package com.chameleonvision.common.network;
import java.net.InterfaceAddress;
@SuppressWarnings("WeakerAccess")
public class NetworkInterface {
- public final String name;
- public final String displayName;
- public final String IPAddress;
- public final String Netmask;
- public final String Gateway;
- public final String Broadcast;
+ public final String name;
+ public final String displayName;
+ public final String IPAddress;
+ public final String Netmask;
+ public final String Gateway;
+ public final String Broadcast;
- public NetworkInterface(java.net.NetworkInterface inetface, InterfaceAddress ifaceAddress) {
- name = inetface.getName();
- displayName = inetface.getDisplayName();
+ public NetworkInterface(java.net.NetworkInterface inetface, InterfaceAddress ifaceAddress) {
+ name = inetface.getName();
+ displayName = inetface.getDisplayName();
- var inetAddress = ifaceAddress.getAddress();
- IPAddress = inetAddress.getHostAddress();
+ var inetAddress = ifaceAddress.getAddress();
+ IPAddress = inetAddress.getHostAddress();
Netmask = getIPv4LocalNetMask(ifaceAddress);
// TODO: (low) hack to "get" gateway, this is gross and bad, pls fix
@@ -25,10 +25,10 @@ public class NetworkInterface {
Gateway = String.join(".", splitIPAddr);
splitIPAddr[3] = "255";
Broadcast = String.join(".", splitIPAddr);
- }
+ }
private static String getIPv4LocalNetMask(InterfaceAddress interfaceAddress) {
- var netPrefix = interfaceAddress.getNetworkPrefixLength();
+ var netPrefix = interfaceAddress.getNetworkPrefixLength();
try {
// Since this is for IPv4, it's 32 bits, so set the sign value of
// the int to "negative"...
@@ -41,7 +41,7 @@ public class NetworkInterface {
}
// Transform the resulting value in xxx.xxx.xxx.xxx format, like if
/// it was a standard address...
- // Return the address thus created...
+ // Return the address thus created...
return ((shiftby >> 24) & 255) + "." + ((shiftby >> 16) & 255) + "." + ((shiftby >> 8) & 255) + "." + (shiftby & 255);
// return InetAddress.getByName(maskString);
}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkManager.java b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkManager.java
new file mode 100644
index 000000000..a3958ca90
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkManager.java
@@ -0,0 +1,23 @@
+package com.chameleonvision.common.network;
+
+public class NetworkManager {
+ private NetworkManager() {}
+
+ private static class SingletonHolder {
+ private static final NetworkManager INSTANCE = new NetworkManager();
+ }
+
+ public static NetworkManager getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+
+ private boolean isManaged = false;
+
+ public void initialize(boolean shouldManage) {
+ isManaged = shouldManage;
+ if (!isManaged) {
+ return;
+ }
+
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkMode.java b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkMode.java
new file mode 100644
index 000000000..aa979670c
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/network/NetworkMode.java
@@ -0,0 +1,6 @@
+package com.chameleonvision.common.network;
+
+public enum NetworkMode {
+ DHCP,
+ STATIC
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/network/SysNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/common/network/SysNetworking.java
new file mode 100644
index 000000000..212b79eb9
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/network/SysNetworking.java
@@ -0,0 +1,63 @@
+package com.chameleonvision.common.network;
+
+import com.chameleonvision.common.server.util.ShellExec;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.util.List;
+
+public abstract class SysNetworking {
+ NetworkInterface networkInterface;
+ ShellExec shell = new ShellExec(true, true);
+
+ private String hostname = getHostname();
+
+ public String getHostname() {
+ if (hostname == null) {
+ try {
+ var retCode = shell.execute("hostname", null, true);
+ if (retCode == 0) {
+ while(!shell.isOutputCompleted()) {}
+ return shell.getOutput();
+ } else {
+ return null;
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ } else return hostname;
+ }
+
+ //code belongs to https://stackoverflow.com/questions/19531411/calculate-cidr-from-a-given-netmask-java
+ public static int convertNetmaskToCIDR(InetAddress netmask) {
+
+ byte[] netmaskBytes = netmask.getAddress();
+ int cidr = 0;
+ boolean zero = false;
+ for (byte b : netmaskBytes) {
+ int mask = 0x80;
+
+ for (int i = 0; i < 8; i++) {
+ int result = b & mask;
+ if (result == 0) {
+ zero = true;
+ } else if (zero) {
+ throw new IllegalArgumentException("Invalid netmask.");
+ } else {
+ cidr++;
+ }
+ mask >>>= 1;
+ }
+ }
+ return cidr;
+ }
+
+ public void setNetworkInterface(NetworkInterface networkInterface) {
+ this.networkInterface = networkInterface;
+ }
+ public abstract boolean setDHCP();
+ public abstract boolean setHostname(String hostname);
+ public abstract boolean setStatic(String ipAddress, String netmask, String gateway);
+ public abstract List getNetworkInterfaces() throws SocketException;
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/MainConfig.java b/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/MainConfig.java
new file mode 100644
index 000000000..64d1ca481
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/MainConfig.java
@@ -0,0 +1,21 @@
+package com.chameleonvision.common.server.configuration;
+
+import com.chameleonvision.common.configuration.ConfigFile;
+
+public class MainConfig extends ConfigFile {
+
+ public int teamNumber = 0;
+ public boolean ntServer = false;
+
+ private MainConfig() {
+ super("general");
+ }
+
+ private static class SingletonHolder {
+ private static final MainConfig INSTANCE = new MainConfig();
+ }
+
+ public static MainConfig getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/NetworkConfig.java b/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/NetworkConfig.java
new file mode 100644
index 000000000..2e40b825b
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/server/configuration/NetworkConfig.java
@@ -0,0 +1,23 @@
+package com.chameleonvision.common.server.configuration;
+
+import com.chameleonvision.common.configuration.ConfigFile;
+import com.chameleonvision.common.network.NetworkMode;
+
+public class NetworkConfig extends ConfigFile {
+
+ public NetworkMode networkMode = NetworkMode.DHCP;
+ public String ip = "";
+ public String hostname = "chameleon-vision";
+
+ private NetworkConfig() {
+ super("network");
+ }
+
+ private static class SingletonHolder {
+ private static final NetworkConfig INSTANCE = new NetworkConfig();
+ }
+
+ public static NetworkConfig getInstance() {
+ return SingletonHolder.INSTANCE;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/server/util/Platform.java b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/Platform.java
new file mode 100644
index 000000000..dc38da09d
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/Platform.java
@@ -0,0 +1,109 @@
+package com.chameleonvision.common.server.util;
+
+import edu.wpi.first.wpiutil.RuntimeDetector;
+
+import java.io.IOException;
+
+@SuppressWarnings("unused")
+public enum Platform {
+ // WPILib Supported (JNI)
+ WINDOWS_32("Windows x32"),
+ WINDOWS_64("Windows x64"),
+ LINUX_64("Linux x64"),
+ LINUX_RASPBIAN("Linux Raspbian"), // Raspberry Pi 3/4
+ LINUX_AARCH64BIONIC("Linux AARCH64 Bionic"), // Jetson Nano, Jetson TX2
+ MACOS_64("Mac OS x64"),
+
+ // ChameleonVision Supported (Manual install)
+ LINUX_ARM32("Linux ARM32"), // ODROID XU4, C1+
+ LINUX_ARM64("Linux ARM64"), // ODROID C2, N2
+
+ // Completely unsupported
+ UNSUPPORTED("Unsupported Platform");
+
+ public final String value;
+ public final boolean isRoot = checkForRoot();
+
+ Platform(String value) {
+ this.value = value;
+ }
+
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String OS_ARCH = System.getProperty("os.arch");
+ public static final Platform CurrentPlatform = getCurrentPlatform();
+
+ private static String UnknownPlatformString = String.format("Unknown Platform. OS: %s, Architecture: %s", OS_NAME, OS_ARCH);
+
+ public boolean isWindows() {
+ return this == WINDOWS_64 || this == WINDOWS_32;
+ }
+
+ public boolean isLinux() {
+ return this == LINUX_64 || this == LINUX_RASPBIAN || this == LINUX_ARM64;
+ }
+
+ public boolean isMac() {
+ return this == MACOS_64;
+ }
+
+ public static boolean isRaspberryPi() {
+ return CurrentPlatform.equals(LINUX_RASPBIAN);
+ }
+
+ private static ShellExec shell = new ShellExec(true, false);
+
+ @SuppressWarnings("StatementWithEmptyBody")
+ private boolean checkForRoot() {
+ if (isLinux() || isMac()) {
+ try {
+ shell.execute("id", null, true, "-u");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // TODO: better way to do this?
+ while (!shell.isOutputCompleted()) {
+ // ignored
+ }
+
+ if (shell.getExitCode() == 0) {
+ return shell.getOutput().split("\n")[0].equals("0");
+ }
+
+ } else {
+ return true;
+ }
+ return false;
+ }
+
+ private static Platform getCurrentPlatform() {
+ if (RuntimeDetector.isWindows()) {
+ if (RuntimeDetector.is32BitIntel()) return WINDOWS_32;
+ if (RuntimeDetector.is64BitIntel()) return WINDOWS_64;
+ }
+
+ if (RuntimeDetector.isMac()) {
+ if (RuntimeDetector.is32BitIntel()) return UNSUPPORTED;
+ if (RuntimeDetector.is64BitIntel()) return MACOS_64;
+ }
+
+ if (RuntimeDetector.isLinux()) {
+ if (RuntimeDetector.is32BitIntel()) return UNSUPPORTED;
+ if (RuntimeDetector.is64BitIntel()) return LINUX_64;
+ if (RuntimeDetector.isRaspbian()) return LINUX_RASPBIAN;
+
+ }
+
+ System.out.println(UnknownPlatformString);
+ return Platform.UNSUPPORTED;
+ }
+
+
+ public String toString() {
+ if (this.equals(UNSUPPORTED)) {
+ return UnknownPlatformString;
+ } else {
+ return this.value;
+ }
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/ShellExec.java b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExec.java
similarity index 90%
rename from chameleon-server/src/main/java/com/chameleonvision/util/ShellExec.java
rename to chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExec.java
index 60856cf79..16ee97af0 100644
--- a/chameleon-server/src/main/java/com/chameleonvision/util/ShellExec.java
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExec.java
@@ -1,10 +1,11 @@
-package com.chameleonvision.util;
+package com.chameleonvision.common.server.util;
import java.io.*;
/**
* Execute external process and optionally read output buffer.
*/
+@SuppressWarnings({"unused", "ConstantConditions"})
public class ShellExec {
private int exitCode;
private boolean readOutput, readError;
@@ -23,7 +24,7 @@ public class ShellExec {
* Execute a bash command. We can handle complex bash commands including
* multiple executions (; | && ||), quotes, expansions ($), escapes (\), e.g.:
* "cd /abc/def; mv ghi 'older ghi '$(whoami)"
- * @param command
+ * @param command Bash command to execute
* @return true if bash got started, but your command may have failed.
*/
public int executeBashCommand(String command) throws IOException {
@@ -41,19 +42,7 @@ public class ShellExec {
// Consume streams, older jvm's had a memory leak if streams were not read,
// some other jvm+OS combinations may block unless streams are consumed.
- errorGobbler = new StreamGobbler(process.getErrorStream(), readError);
- outputGobbler = new StreamGobbler(process.getInputStream(), readOutput);
- errorGobbler.start();
- outputGobbler.start();
-
- exitCode = 0;
- if (wait) {
- try {
- process.waitFor();
- exitCode = process.exitValue();
- } catch (InterruptedException ignored) { }
- }
- return exitCode;
+ return doProcess(wait, process);
}
/**
@@ -92,7 +81,11 @@ public class ShellExec {
// Consume streams, older jvm's had a memory leak if streams were not read,
// some other jvm+OS combinations may block unless streams are consumed.
- errorGobbler = new StreamGobbler(process.getErrorStream(), readError);
+ return doProcess(wait, process);
+ }
+
+ private int doProcess(boolean wait, Process process) {
+ errorGobbler = new StreamGobbler(process.getErrorStream(), readError);
outputGobbler = new StreamGobbler(process.getInputStream(), readOutput);
errorGobbler.start();
outputGobbler.start();
@@ -169,7 +162,7 @@ public class ShellExec {
/**
* Get inputstream buffer or null if stream
* was not consumed.
- * @return
+ * @return Output stream
*/
public String getOutput() {
return (output != null ? output.toString() : null);
@@ -177,7 +170,7 @@ public class ShellExec {
/**
* Is input stream completed.
- * @return
+ * @return if input stream is completed
*/
public boolean isCompleted() {
return completed;
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExecutor.java b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExecutor.java
new file mode 100644
index 000000000..bf79ed2b9
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/server/util/ShellExecutor.java
@@ -0,0 +1,45 @@
+package com.chameleonvision.common.server.util;
+
+import org.apache.commons.exec.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+// TODO: Finish me!
+@SuppressWarnings({"FieldCanBeLocal", "unused"})
+public class ShellExecutor {
+
+ private final Executor executor;
+ private final ExecuteWatchdog watchdog;
+ private final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
+ private final OutputStream stdOutStream = new ByteArrayOutputStream();
+ private final OutputStream stdErrStream = new ByteArrayOutputStream();
+ private final boolean block;
+
+ public ShellExecutor(String command, boolean block, int timeoutMillis, String... args) {
+ this.block = block;
+
+ CommandLine cmdLine = new CommandLine(command);
+ cmdLine.addArguments(args);
+
+ watchdog = new ExecuteWatchdog(timeoutMillis);
+ executor = new DefaultExecutor();
+ executor.setWatchdog(watchdog);
+ executor.setStreamHandler(new PumpStreamHandler(stdOutStream, stdErrStream));
+ }
+
+// public int execute() {
+// if ()
+// }
+
+ public String getStdOut() {
+ if (!watchdog.isWatching()) {
+ return executor.toString();
+ }
+ return "";
+ }
+
+ public String getStdErr() {
+ return "";
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/camera/USBCamera.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/camera/USBCamera.java
new file mode 100644
index 000000000..c792006e4
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/camera/USBCamera.java
@@ -0,0 +1,6 @@
+package com.chameleonvision.common.vision.base.camera;
+
+import com.chameleonvision.common.vision.base.capture.USBFrameProvider;
+
+public class USBCamera extends USBFrameProvider {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/FileFrameProvider.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/FileFrameProvider.java
new file mode 100644
index 000000000..09df97e15
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/FileFrameProvider.java
@@ -0,0 +1,12 @@
+package com.chameleonvision.common.vision.base.capture;
+
+import com.chameleonvision.common.vision.base.frame.Frame;
+import com.chameleonvision.common.vision.base.frame.FrameProvider;
+import org.apache.commons.lang3.NotImplementedException;
+
+public class FileFrameProvider implements FrameProvider {
+ @Override
+ public Frame getFrame() {
+ throw new NotImplementedException("");
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/NetworkFrameProvider.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/NetworkFrameProvider.java
new file mode 100644
index 000000000..a236ad8a7
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/NetworkFrameProvider.java
@@ -0,0 +1,12 @@
+package com.chameleonvision.common.vision.base.capture;
+
+import com.chameleonvision.common.vision.base.frame.Frame;
+import com.chameleonvision.common.vision.base.frame.FrameProvider;
+import org.apache.commons.lang3.NotImplementedException;
+
+public class NetworkFrameProvider implements FrameProvider {
+ @Override
+ public Frame getFrame() {
+ throw new NotImplementedException("");
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/USBFrameProvider.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/USBFrameProvider.java
new file mode 100644
index 000000000..0b96d2f94
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/capture/USBFrameProvider.java
@@ -0,0 +1,12 @@
+package com.chameleonvision.common.vision.base.capture;
+
+import com.chameleonvision.common.vision.base.frame.Frame;
+import com.chameleonvision.common.vision.base.frame.FrameProvider;
+import org.apache.commons.lang3.NotImplementedException;
+
+public class USBFrameProvider implements FrameProvider {
+ @Override
+ public Frame getFrame() {
+ throw new NotImplementedException("");
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/Frame.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/Frame.java
new file mode 100644
index 000000000..b8950c68b
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/Frame.java
@@ -0,0 +1,10 @@
+package com.chameleonvision.common.vision.base.frame;
+
+import org.opencv.core.Mat;
+import org.opencv.core.Size;
+
+public class Frame {
+ public long timestamp;
+ public Mat image;
+ public Size imageSize;
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameConsumer.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameConsumer.java
new file mode 100644
index 000000000..2374a21f6
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameConsumer.java
@@ -0,0 +1,5 @@
+package com.chameleonvision.common.vision.base.frame;
+
+public interface FrameConsumer {
+
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameProvider.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameProvider.java
new file mode 100644
index 000000000..be8ce43e0
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/frame/FrameProvider.java
@@ -0,0 +1,5 @@
+package com.chameleonvision.common.vision.base.frame;
+
+public interface FrameProvider {
+ Frame getFrame();
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/Pipe.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/Pipe.java
new file mode 100644
index 000000000..7a9610f06
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/Pipe.java
@@ -0,0 +1,37 @@
+package com.chameleonvision.common.vision.base.pipeline;
+
+import java.util.function.Function;
+
+/**
+ * Defines a pipe. A pipe is a single step in a pipeline.
+ * This class is to be extended, never used on its own.
+ *
+ * @param Input type for the pipe
+ * @param Output type for the pipe
+ */
+public abstract class Pipe implements Function> {
+
+ private PipeResult result = new PipeResult<>();
+
+ /**
+ * Runs the process for the pipe.
+ *
+ * @param in Input for pipe processing
+ * @return Result of processing
+ */
+ protected abstract O process(I in);
+
+ /**
+ *
+ *
+ * @param in Input for pipe processing
+ * @return Result of processing
+ */
+ @Override
+ public PipeResult apply(I in) {
+ long pipeStartNanos = System.nanoTime();
+ result.result = process(in);
+ result.nanosElapsed = System.nanoTime() - pipeStartNanos;
+ return result;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/PipeResult.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/PipeResult.java
new file mode 100644
index 000000000..dfdb9b576
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/PipeResult.java
@@ -0,0 +1,6 @@
+package com.chameleonvision.common.vision.base.pipeline;
+
+public class PipeResult {
+ O result;
+ long nanosElapsed;
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/ResizeImagePipe.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/ResizeImagePipe.java
new file mode 100644
index 000000000..b17324026
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/ResizeImagePipe.java
@@ -0,0 +1,16 @@
+package com.chameleonvision.common.vision.base.pipeline.pipe;
+
+import com.chameleonvision.common.vision.base.pipeline.Pipe;
+import org.opencv.core.Mat;
+
+public class ResizeImagePipe extends Pipe {
+
+ public ResizeImagePipe() {
+
+ }
+
+ @Override
+ protected Mat process(Mat in) {
+ return null;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/javacv/GPUResizeImagePipe.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/javacv/GPUResizeImagePipe.java
new file mode 100644
index 000000000..46c6216c1
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/pipeline/pipe/javacv/GPUResizeImagePipe.java
@@ -0,0 +1,16 @@
+package com.chameleonvision.common.vision.base.pipeline.pipe.javacv;
+
+import com.chameleonvision.common.vision.base.pipeline.Pipe;
+import org.bytedeco.opencv.opencv_core.GpuMat;
+
+public class GPUResizeImagePipe extends Pipe {
+
+ public GPUResizeImagePipe() {
+
+ }
+
+ @Override
+ protected GpuMat process(GpuMat in) {
+ return null;
+ }
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/AsyncMjpgStreamer.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/AsyncMjpgStreamer.java
new file mode 100644
index 000000000..f59486fa4
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/AsyncMjpgStreamer.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.base.stream;
+
+public class AsyncMjpgStreamer extends MjpgStreamer {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/MjpgStreamer.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/MjpgStreamer.java
new file mode 100644
index 000000000..decd48963
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/MjpgStreamer.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.base.stream;
+
+public class MjpgStreamer {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/Streamer.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/Streamer.java
new file mode 100644
index 000000000..6bb6450e2
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/base/stream/Streamer.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.base.stream;
+
+public interface Streamer {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/opencv/OpenCVWrapper.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/opencv/OpenCVWrapper.java
new file mode 100644
index 000000000..4457f598d
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/opencv/OpenCVWrapper.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.opencv;
+
+public class OpenCVWrapper {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/KnownTarget.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/KnownTarget.java
new file mode 100644
index 000000000..739b30781
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/KnownTarget.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.target;
+
+public class KnownTarget {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/TrackedTarget.java b/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/TrackedTarget.java
new file mode 100644
index 000000000..169950a7d
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/common/vision/target/TrackedTarget.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.common.vision.target;
+
+public class TrackedTarget {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/CVPipelineSettingsList.java b/chameleon-server/src/main/java/com/chameleonvision/config/CVPipelineSettingsList.java
deleted file mode 100644
index f9c61a48e..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/CVPipelineSettingsList.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-
-import java.util.List;
-
-public interface CVPipelineSettingsList extends List {
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/CameraCalibrationConfig.java b/chameleon-server/src/main/java/com/chameleonvision/config/CameraCalibrationConfig.java
deleted file mode 100644
index 2dbed87b2..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/CameraCalibrationConfig.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.chameleonvision.config;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonIgnoreType;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import org.opencv.core.Mat;
-import org.opencv.core.MatOfDouble;
-import org.opencv.core.Size;
-
-/**
- * A class that holds a camera matrix and distortion coefficients for a given resolution
- */
-public class CameraCalibrationConfig {
- @JsonProperty("resolution") public final Size resolution;
- @JsonProperty("cameraMatrix") public final JsonMat cameraMatrix;
- @JsonProperty("distortionCoeffs") public final JsonMat distortionCoeffs;
- @JsonProperty("squareSize") public final double squareSize;
-
- @JsonCreator
- public CameraCalibrationConfig(
- @JsonProperty("resolution") Size resolution,
- @JsonProperty("cameraMatrix") JsonMat cameraMatrix,
- @JsonProperty("distortionCoeffs") JsonMat distortionCoeffs,
- @JsonProperty("squareSize") double squareSize) {
- this.resolution = resolution;
- this.cameraMatrix = cameraMatrix;
- this.distortionCoeffs = distortionCoeffs;
- this.squareSize = squareSize;
- }
-
- public CameraCalibrationConfig(Size resolution, Mat cameraMatrix, Mat distortionCoeffs, double squareSize) {
- this.resolution = resolution;
- this.cameraMatrix = JsonMat.fromMat(cameraMatrix);
- this.distortionCoeffs = JsonMat.fromMat(distortionCoeffs);
- this.squareSize = squareSize;
- }
-
- @JsonIgnoreType
- public static class UICameraCalibrationConfig {
- public final int width;
- public final int height;
- public final double[] cameraMatrix;
- public final double[] distortionCoeffs;
-
- public UICameraCalibrationConfig(CameraCalibrationConfig config) {
- width = (int) config.resolution.width;
- height = (int) config.resolution.height;
- cameraMatrix = config.cameraMatrix.data;
- distortionCoeffs = config.distortionCoeffs.data;
- }
-
- }
-
- @JsonIgnore
- public Mat getCameraMatrixAsMat() {
- return cameraMatrix.toMat();
- }
-
- @JsonIgnore
- public MatOfDouble getDistortionCoeffsAsMat() {
- return new MatOfDouble(distortionCoeffs.toMat());
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/CameraConfig.java b/chameleon-server/src/main/java/com/chameleonvision/config/CameraConfig.java
deleted file mode 100644
index 7c5b1e0e7..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/CameraConfig.java
+++ /dev/null
@@ -1,181 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.util.FileHelper;
-import com.chameleonvision.util.JacksonHelper;
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class CameraConfig {
-
- private static final Path camerasConfigFolderPath = Path.of(ConfigManager.SettingsPath.toString(), "cameras");
-
- private final CameraJsonConfig preliminaryConfig;
- private final Path configFolderPath;
- private final Path configPath;
- private final Path driverModePath;
- private final Path calibrationPath;
- final Path pipelineFolderPath;
-
- public final PipelineConfig pipelineConfig;
-
- CameraConfig(CameraJsonConfig config) {
- preliminaryConfig = config;
- String cameraConfigName = preliminaryConfig.name.replace(' ', '_');
- pipelineConfig = new PipelineConfig(this);
-
- configFolderPath = Path.of(camerasConfigFolderPath.toString(), cameraConfigName);
- configPath = Path.of(configFolderPath.toString(), "camera.json");
- driverModePath = Path.of(configFolderPath.toString(), "drivermode.json");
- calibrationPath = Path.of(configFolderPath.toString(), "calibration.json");
- pipelineFolderPath = Paths.get(configFolderPath.toString(), "pipelines");
- }
-
- public FullCameraConfiguration load() {
- checkFolder();
- checkConfig();
- checkDriverMode();
- checkCalibration();
- pipelineConfig.check();
-
- return new FullCameraConfiguration(loadConfig(), pipelineConfig.load(), loadDriverMode(), loadCalibration(), this);
- }
-
- private CameraJsonConfig loadConfig() {
- CameraJsonConfig config = preliminaryConfig;
- try {
- config = JacksonHelper.deserialize(configPath, CameraJsonConfig.class);
- } catch (IOException e) {
- System.err.printf("Failed to load camera config: %s - using default.\n", configPath.toString());
- }
- return config;
- }
-
- private CVPipelineSettings loadDriverMode() {
- CVPipelineSettings driverMode = new CVPipelineSettings();
- try {
- driverMode = JacksonHelper.deserialize(driverModePath, CVPipelineSettings.class);
- } catch (IOException e) {
- System.err.println("Failed to load camera drivermode: " + driverModePath.toString());
- }
- if (driverMode != null) {
- driverMode.nickname = "DRIVERMODE";
- driverMode.index = -1;
- }
- return driverMode;
- }
-
- private List loadCalibration() {
- List calibrations = new ArrayList<>();
- try {
- calibrations = List.of(Objects.requireNonNull(JacksonHelper.deserialize(calibrationPath, CameraCalibrationConfig[].class)));
- } catch (Exception e) {
- System.err.println("Failed to load camera calibration: " + driverModePath.toString());
- }
- return calibrations;
- }
-
- void saveConfig(CameraJsonConfig config) {
- try {
- JacksonHelper.serializer(configPath, config, true);
- FileHelper.setFilePerms(configPath);
- } catch (IOException e) {
- System.err.println("Failed to save camera config file: " + configPath.toString());
- }
- }
-
- void savePipelines(List pipelines) {
- pipelineConfig.save(pipelines);
- }
-
- public void saveDriverMode(CVPipelineSettings driverMode) {
- try {
- JacksonHelper.serializer(driverModePath, driverMode, true);
- FileHelper.setFilePerms(driverModePath);
- } catch (IOException e) {
- System.err.println("Failed to save camera drivermode file: " + driverModePath.toString());
- }
- }
-
-
- public void saveCalibration(List cal) {
- CameraCalibrationConfig[] configs = cal.toArray(new CameraCalibrationConfig[0]);
- try {
- JacksonHelper.serializer(calibrationPath, configs, true);
- FileHelper.setFilePerms(calibrationPath);
- } catch (IOException e) {
- System.err.println("Failed to save camera calibration file: " + calibrationPath.toString());
- }
- }
-
- void checkFolder() {
- if (!configFolderExists()) {
- try {
- if (!(new File(configFolderPath.toUri()).mkdirs())) {
- System.err.println("Failed to create camera config folder: " + configFolderPath.toString());
- }
- FileHelper.setFilePerms(configFolderPath);
- } catch (Exception e) {
- System.err.println("Failed to create camera config folder: " + configFolderPath.toString());
- }
- }
- }
-
- private void checkConfig() {
- if (!configExists()) {
- try {
- JacksonHelper.serializer(configPath, preliminaryConfig, true);
- FileHelper.setFilePerms(configPath);
- } catch (IOException e) {
- System.err.println("Failed to create camera config file: " + configPath.toString());
- }
- }
- }
-
- private void checkDriverMode() {
- if (!driverModeExists()) {
- try {
- CVPipelineSettings newDriverModeSettings = new CVPipelineSettings();
- newDriverModeSettings.nickname = "DRIVERMODE";
- JacksonHelper.serializer(driverModePath, newDriverModeSettings, true);
- FileHelper.setFilePerms(driverModePath);
- } catch (IOException e) {
- System.err.println("Failed to create camera drivermode file: " + driverModePath.toString());
- }
- }
- }
-
- private void checkCalibration() {
- if (!calibrationExists()) {
- try {
- List calibrations = new ArrayList<>();
- JacksonHelper.serializer(calibrationPath, calibrations.toArray(), true);
- } catch (IOException e) {
- System.err.println("Failed to create camera calibration file: " + calibrationPath.toString());
- }
- }
- }
-
- private boolean configFolderExists() {
- return Files.exists(configFolderPath);
- }
-
- private boolean configExists() {
- return configFolderExists() && Files.exists(configPath);
- }
-
- private boolean driverModeExists() {
- return configFolderExists() && Files.exists(driverModePath);
- }
-
- private boolean calibrationExists() {
- return configFolderExists() && Files.exists(calibrationPath);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/CameraJsonConfig.java b/chameleon-server/src/main/java/com/chameleonvision/config/CameraJsonConfig.java
deleted file mode 100644
index 0411ca7e0..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/CameraJsonConfig.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.vision.VisionProcess;
-import com.chameleonvision.vision.camera.USBCaptureProperties;
-import com.chameleonvision.vision.enums.StreamDivisor;
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class CameraJsonConfig {
- public final double fov;
- public final String path;
- public final String name;
- public final String nickname;
- public final int videomode;
- public final double tilt;
- public final StreamDivisor streamDivisor;
-
- @JsonCreator
- public CameraJsonConfig(
- @JsonProperty("fov") double fov,
- @JsonProperty("path") String path,
- @JsonProperty("name") String name,
- @JsonProperty("nickname") String nickname,
- @JsonProperty("videomode") int videomode,
- @JsonProperty("streamDivisor") StreamDivisor streamDivisor,
- @JsonProperty("tilt") double tilt) {
- this.fov = fov;
- this.path = path;
- this.name = name;
- this.nickname = nickname;
- this.videomode = videomode;
- this.streamDivisor = streamDivisor;
- this.tilt = tilt;
- }
-
- public CameraJsonConfig(String path, String name) {
- this.fov = USBCaptureProperties.DEFAULT_FOV;
- this.path = path;
- this.name = name;
- this.nickname = name;
- this.videomode = 0;
- this.streamDivisor = StreamDivisor.NONE;
- this.tilt = 0;
- }
-
- public static CameraJsonConfig fromVisionProcess(VisionProcess process) {
- USBCaptureProperties camProps = process.getCamera().getProperties();
- int videomode = camProps.getCurrentVideoModeIndex();
- StreamDivisor streamDivisor = process.cameraStreamer.getDivisor();
- double tilt = process.getCamera().getProperties().getTilt().getDegrees();
- return new CameraJsonConfig(camProps.getFOV(), camProps.path, camProps.name, camProps.getNickname(), videomode, streamDivisor, tilt);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/ConfigManager.java b/chameleon-server/src/main/java/com/chameleonvision/config/ConfigManager.java
deleted file mode 100644
index 5acc18625..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/ConfigManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.util.*;
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-
-public class ConfigManager {
- private ConfigManager() {
- }
-
- public static final Path SettingsPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "settings");
- private static final Path settingsFilePath = Paths.get(SettingsPath.toString(), "settings.json");
-
- private static final LinkedHashMap cameraConfigs = new LinkedHashMap<>();
-
- public static GeneralSettings settings = new GeneralSettings();
-
- private static boolean settingsFolderExists() {
- return Files.exists(SettingsPath);
- }
-
- private static boolean settingsFileExists() {
- return settingsFolderExists() && Files.exists(settingsFilePath);
- }
-
- private static void checkSettingsFolder() {
- if (!settingsFolderExists()) {
- try {
- if (!(new File(SettingsPath.toUri()).mkdirs())) {
- System.err.println("Failed to create settings folder: " + SettingsPath.toString());
- }
- Files.createDirectory(SettingsPath);
- if (!Platform.CurrentPlatform.isWindows()) {
- new ShellExec().executeBashCommand("sudo chmod -R 0777 " + SettingsPath.toString());
- }
- } catch (IOException e) {
- if (!(e instanceof java.nio.file.FileAlreadyExistsException))
- e.printStackTrace();
- }
- }
- }
-
- private static void checkSettingsFile() {
- boolean settingsFileEmpty = settingsFileExists() && new File(settingsFilePath.toString()).length() == 0;
- if (settingsFileEmpty || !settingsFileExists()) {
- try {
- JacksonHelper.serializer(settingsFilePath, settings, true);
- FileHelper.setFilePerms(settingsFilePath);
- } catch (IOException e) {
- e.printStackTrace();
- }
- } else {
- try {
- settings = JacksonHelper.deserialize(settingsFilePath, GeneralSettings.class);
- } catch (IOException e) {
- System.err.println("Failed to load settings.json, using defaults.");
- }
- }
- }
-
- public static void initializeSettings() {
- System.out.println("Settings folder: " + SettingsPath.toString());
- checkSettingsFolder();
- checkSettingsFile();
- FileHelper.setAllPerms(SettingsPath);
- }
-
- private static void saveSettingsFile() {
- try {
- JacksonHelper.serializer(settingsFilePath, settings, true);
- FileHelper.setFilePerms(settingsFilePath);
- } catch (IOException e) {
- System.err.println("Failed to save settings.json!");
- }
- }
-
- public static void saveGeneralSettings() {
- checkSettingsFolder();
- saveSettingsFile();
- }
-
- public static List initializeCameras(List preliminaryConfigs) {
- List configList = new ArrayList<>();
-
- checkSettingsFolder();
-
- // loop over all the camera names and try to create settings folders for it
- for (CameraJsonConfig preliminaryConfig : preliminaryConfigs) {
- CameraConfig cameraConfiguration = new CameraConfig(preliminaryConfig);
- cameraConfigs.put(preliminaryConfig.name, cameraConfiguration);
-
- FullCameraConfiguration camJsonConfig = cameraConfiguration.load();
-
- configList.add(camJsonConfig);
- }
-
- return configList;
- }
-
- public static void saveCameraConfig(String cameraName, CameraJsonConfig config) {
- var camConf = cameraConfigs.get(cameraName);
- camConf.saveConfig(config);
- }
-
- public static void saveCameraPipelines(String cameraName, List pipelines) {
- var camConf = cameraConfigs.get(cameraName);
- camConf.savePipelines(pipelines);
- }
-
- public static void saveCameraDriverMode(String cameraName, CVPipelineSettings driverMode) {
- var camConf = cameraConfigs.get(cameraName);
- camConf.saveDriverMode(driverMode);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/FullCameraConfiguration.java b/chameleon-server/src/main/java/com/chameleonvision/config/FullCameraConfiguration.java
deleted file mode 100644
index 632526fbc..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/FullCameraConfiguration.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-
-import java.util.List;
-
-public class FullCameraConfiguration {
- public final CameraJsonConfig cameraConfig;
- public final List pipelines;
- public final CVPipelineSettings driverMode;
- public final List calibration;
- public final CameraConfig fileConfig;
-
- FullCameraConfiguration(CameraJsonConfig cameraConfig, List pipelines, CVPipelineSettings driverMode, List calibration, CameraConfig fileConfig) {
- this.cameraConfig = cameraConfig;
- this.pipelines = pipelines;
- this.driverMode = driverMode;
- this.calibration = calibration;
- this.fileConfig = fileConfig;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/GeneralSettings.java b/chameleon-server/src/main/java/com/chameleonvision/config/GeneralSettings.java
deleted file mode 100644
index 50f40a7db..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/GeneralSettings.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.network.NetworkIPMode;
-
-public class GeneralSettings {
- public int teamNumber = 1577;
- public NetworkIPMode connectionType = NetworkIPMode.DHCP;
- public String ip = "";
- public String gateway = "";
- public String netmask = "";
- public String hostname = "Chameleon-vision";
- public String currentCamera = "";
- public Integer currentPipeline = null;
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/JsonMat.java b/chameleon-server/src/main/java/com/chameleonvision/config/JsonMat.java
deleted file mode 100644
index fbdd6f1a4..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/JsonMat.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.chameleonvision.config;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import org.opencv.core.CvType;
-import org.opencv.core.Mat;
-
-import java.util.Arrays;
-
-
-public class JsonMat {
- public final int rows;
- public final int cols;
- public final int type;
- public final double[] data;
-
- public JsonMat(int rows, int cols, double[] data) {
- this(rows, cols, CvType.CV_64FC1, data);
- }
-
- public JsonMat(
- @JsonProperty("rows") int rows,
- @JsonProperty("cols") int cols,
- @JsonProperty("type") int type,
- @JsonProperty("data") double[] data) {
- this.rows = rows;
- this.cols = cols;
- this.type = type;
- this.data = data;
- }
-
- public Mat toMat() {
- return toMat(this);
- }
-
- private static boolean isCameraMatrixMat(Mat mat) {
- return mat.type() == CvType.CV_64FC1 && mat.cols() == 3 && mat.rows() == 3;
- }
-
- private static boolean isDistortionCoeffsMat(Mat mat) {
- return mat.type() == CvType.CV_64FC1 && mat.cols() == 5 && mat.rows() == 1;
- }
-
- private static boolean isCalibrationMat(Mat mat) {
- return isDistortionCoeffsMat(mat) || isCameraMatrixMat(mat);
- }
-
- public static double[] getDataFromMat(Mat mat) {
- if (!isCalibrationMat(mat)) return null;
-
- double[] data = new double[(int)(mat.total()*mat.elemSize())];
- mat.get(0, 0, data);
-
- int dataLen = -1;
-
- if (isCameraMatrixMat(mat)) dataLen = 9;
- if (isDistortionCoeffsMat(mat)) dataLen = 5;
-
- // truncate Mat data to correct number data points.
- return Arrays.copyOfRange(data, 0, dataLen);
- }
-
- public static JsonMat fromMat(Mat mat) {
- if (!isCalibrationMat(mat)) return null;
- return new JsonMat(mat.rows(), mat.cols(), getDataFromMat(mat));
- }
-
- public static Mat toMat(JsonMat jsonMat) {
- if (jsonMat.type != CvType.CV_64FC1) return null;
-
- Mat retMat = new Mat(jsonMat.rows, jsonMat.cols, jsonMat.type);
- retMat.put(0, 0, jsonMat.data);
- return retMat;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/PipelineConfig.java b/chameleon-server/src/main/java/com/chameleonvision/config/PipelineConfig.java
deleted file mode 100644
index 2b7b2074e..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/PipelineConfig.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.chameleonvision.config;
-
-import com.chameleonvision.config.serializers.StandardCVPipelineSettingsDeserializer;
-import com.chameleonvision.config.serializers.StandardCVPipelineSettingsSerializer;
-import com.chameleonvision.util.FileHelper;
-import com.chameleonvision.util.JacksonHelper;
-import com.chameleonvision.vision.pipeline.*;
-import com.chameleonvision.vision.pipeline.impl.StandardCVPipelineSettings;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-
-public class PipelineConfig {
-
- private final CameraConfig cameraConfig;
-
- /**
- * Construct a new PipelineConfig
- *
- * @param cameraConfig the CameraConfig (parent folder, kinda?)
- */
- PipelineConfig(CameraConfig cameraConfig) {
- this.cameraConfig = cameraConfig;
- }
-
- private void checkFolder() {
- if (!(new File(cameraConfig.pipelineFolderPath.toUri()).mkdirs())) {
- if (Files.notExists(cameraConfig.pipelineFolderPath)) {
- System.err.println("Failed to create pipelines folder.");
- }
- }
- try {
- FileHelper.setFilePerms(cameraConfig.pipelineFolderPath);
- } catch (IOException e) {
- // ignored
- }
- }
-
- private File[] getPipelineFiles() {
- return new File(cameraConfig.pipelineFolderPath.toUri()).listFiles();
- }
-
- private boolean folderHasPipelines() {
- File[] folderContents = getPipelineFiles();
- if (folderContents == null) return false;
- return folderContents.length > 0;
- }
-
- void check() {
- cameraConfig.checkFolder();
- checkFolder();
- // Check if there's at least one pipe
- if (!folderHasPipelines()) {
- save(new StandardCVPipelineSettings());
- }
- }
-
- private Path getPipelinePath(CVPipelineSettings setting) {
- String pipelineName = setting.nickname.replace(' ', '_');
- String fullFileName = pipelineName + ".json";
- return Path.of(cameraConfig.pipelineFolderPath.toString(), fullFileName);
- }
-
- private boolean pipelineExists(CVPipelineSettings setting) {
- return Files.exists(getPipelinePath(setting));
- }
-
- public void save(CVPipelineSettings settings) {
-
- var path = getPipelinePath(settings);
-
- if (settings instanceof StandardCVPipelineSettings) {
- try {
- JacksonHelper.serialize(path, (StandardCVPipelineSettings) settings, StandardCVPipelineSettings.class, new StandardCVPipelineSettingsSerializer(), true);
- FileHelper.setFilePerms(path);
- } catch (IOException e) {
- e.printStackTrace();
- }
- } else {
- try {
- JacksonHelper.serializer(path, settings, true);
- FileHelper.setFilePerms(path);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- public void save(List settings) {
- for (CVPipelineSettings setting : settings) {
- save(setting);
- }
- }
-
- public void delete(CVPipelineSettings setting) {
- if (pipelineExists(setting)) {
- try {
- Files.delete(getPipelinePath(setting));
- } catch (IOException e) {
- System.err.println("Failed to delete pipeline!");
- }
- }
- }
-
- public CVPipelineSettings rename(CVPipelineSettings setting, String newName) {
- if (pipelineExists(setting)) {
- delete(setting);
- setting.nickname = newName;
- save(setting);
- } else {
- setting.nickname = newName;
- save(setting);
- }
- return setting;
- }
-
- public List load() {
- check(); // TODO: this ensures there will be a default pipeline. is the check later necessary?
-
- File[] pipelineFiles = getPipelineFiles();
- List deserializedList = new ArrayList<>();
-
- if (pipelineFiles == null || pipelineFiles.length < 1) {
- // TODO handle no pipelines to load
- System.err.println("no pipes to load! loading default");
- } else {
- for (File pipelineFile : pipelineFiles) {
- try {
- var pipe = JacksonHelper.deserialize(Paths.get(pipelineFile.getPath()), StandardCVPipelineSettings.class, new StandardCVPipelineSettingsDeserializer());
- deserializedList.add(pipe);
- } catch (IOException e) {
- System.err.println("couldn't load cvpipeline2d");
- }
- }
- }
-
- return deserializedList;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseDeserializer.java b/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseDeserializer.java
deleted file mode 100644
index 69c5b86b3..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseDeserializer.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.chameleonvision.config.serializers;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-import com.fasterxml.jackson.databind.type.CollectionType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import org.jetbrains.annotations.NotNull;
-import org.opencv.core.MatOfPoint3f;
-import org.opencv.core.Point3;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class BaseDeserializer extends StdDeserializer {
- protected BaseDeserializer(Class> vc) {
- super(vc);
- }
-
- JsonNode baseNode;
-
- private static final CollectionType numberListColType = TypeFactory.defaultInstance().constructCollectionType(List.class, Number.class);
- private CollectionType pointListColType = TypeFactory.defaultInstance().constructCollectionType(List.class, Object.class);
- private static final ObjectMapper mapper = new ObjectMapper();
- private static boolean nodeGood(JsonNode node) {
- return node != null && !node.toString().equals("");
- }
-
- List getNumberList(String name, List defaultValue) throws JsonProcessingException {
- JsonNode node = baseNode.get(name);
-
- if (nodeGood(node)) {
- return mapper.readValue(node.toString(), numberListColType);
- }
- return defaultValue;
- }
-
- boolean getBoolean(String name, boolean defaultValue) {
- JsonNode node = baseNode.get(name);
-
- if (nodeGood(node)) {
- return node.booleanValue();
- }
-
- return defaultValue;
- }
-
- int getInt(String name, int defaultValue) {
- return (int) getDouble(name, defaultValue);
- }
-
- double getDouble(String name, double defaultValue) {
- JsonNode node = baseNode.get(name);
-
- if (nodeGood(node)) {
- return node.numberValue().doubleValue();
- }
-
- return defaultValue;
- }
-
- String getString(String name, String defaultValue) {
- JsonNode node = baseNode.get(name);
-
- if (nodeGood(node)) {
- return node.asText();
- }
-
- return defaultValue;
- }
-
- > E getEnum(String name, Class enumClass, E defaultValue) throws IOException {
- JsonNode node = baseNode.get(name);
-
- if (nodeGood(node)) {
- E[] possibleVals = enumClass.getEnumConstants();
- String jsonVal = baseNode.get(name).asText();
-
- for (E val : possibleVals) {
- if (val.name().equals(jsonVal)) {
- return val;
- }
- }
- }
-
- return defaultValue;
- }
- MatOfPoint3f getMatOfPoint3f(String name, MatOfPoint3f defaultValue) throws JsonProcessingException {
- JsonNode node = baseNode.get(name);
- if (nodeGood(node)){
- List> numberList = mapper.readValue(node.toString(), pointListColType);
- List point3List = new ArrayList<>();
- for (List tmp : numberList){
- Point3 p = new Point3();
- p.x = tmp.get(0).doubleValue();
- p.y = tmp.get(1).doubleValue();
- p.z = tmp.get(2).doubleValue();
- point3List.add(p);
- }
- MatOfPoint3f mat = new MatOfPoint3f();
- mat.fromList(point3List);
- return mat;
- }
-
- return defaultValue;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseSerializer.java b/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseSerializer.java
deleted file mode 100644
index fdfbb9db8..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/BaseSerializer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.chameleonvision.config.serializers;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-import org.opencv.core.MatOfPoint3f;
-import org.opencv.core.Point;
-import org.opencv.core.Point3;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class BaseSerializer extends StdSerializer {
- protected BaseSerializer(Class t) {
- super(t);
- }
-
- JsonGenerator generator;
-
- void writeNumberListAsNumberArray(String name, List list) throws IOException {
- generator.writeArrayFieldStart(name);
- for (Number i : list) {
- generator.writeObject(i);
- }
- generator.writeEndArray();
- }
-
- > void writeEnum(String name, E num) throws IOException {
- generator.writeFieldName(name);
- generator.writeString(num.name());
- }
-
- void writeMatOfPoint3f(String name, MatOfPoint3f mat) throws IOException {
- List point3List = mat.toList();
- generator.writeArrayFieldStart(name);
-
- for (Point3 point3 : point3List) {
- double[] tmp = {point3.x, point3.y, point3.z};
- generator.writeObject(tmp);
- }
- generator.writeEndArray();
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsDeserializer.java b/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsDeserializer.java
deleted file mode 100644
index b68d1ccbf..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsDeserializer.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.chameleonvision.config.serializers;
-
-import com.chameleonvision.vision.enums.*;
-import com.chameleonvision.vision.pipeline.impl.StandardCVPipelineSettings;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationContext;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.IntNode;
-
-import java.io.IOException;
-
-public class StandardCVPipelineSettingsDeserializer extends BaseDeserializer {
- public StandardCVPipelineSettingsDeserializer() {
- this(null);
- }
-
- private StandardCVPipelineSettingsDeserializer(Class> vc) {
- super(vc);
- }
-
- @Override
- public StandardCVPipelineSettings deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
- // set BaseDeserializer parser reference.
- baseNode = jsonParser.getCodec().readTree(jsonParser);
-
- StandardCVPipelineSettings pipeline = new StandardCVPipelineSettings();
-
- pipeline.index = getInt("index", pipeline.index);
-
- pipeline.flipMode = getEnum("flipMode", ImageFlipMode.class, pipeline.flipMode);
- pipeline.rotationMode = getEnum("rotationMode", ImageRotationMode.class, pipeline.rotationMode);
-
- pipeline.nickname = getString("nickname", pipeline.nickname);
-
- pipeline.exposure = getDouble("exposure", pipeline.exposure);
- pipeline.brightness = getDouble("brightness", pipeline.brightness);
- pipeline.gain = getDouble("gain", pipeline.gain);
-
- pipeline.videoModeIndex = getInt("videoModeIndex", pipeline.videoModeIndex);
-
- pipeline.streamDivisor = getEnum("streamDivisor", StreamDivisor.class, pipeline.streamDivisor);
-
- pipeline.hue = getNumberList("hue", pipeline.hue);
- pipeline.saturation = getNumberList("saturation", pipeline.saturation);
- pipeline.value = getNumberList("value", pipeline.value);
-
- pipeline.erode = getBoolean("erode", pipeline.erode);
- pipeline.dilate = getBoolean("dilate", pipeline.dilate);
-
- pipeline.area = getNumberList("area", pipeline.area);
- pipeline.ratio = getNumberList("ratio", pipeline.ratio);
- pipeline.extent = getNumberList("extent", pipeline.extent);
-
- pipeline.speckle = getInt("speckle", (Integer) pipeline.speckle);
-
- pipeline.isBinary = getBoolean("isBinary", pipeline.isBinary);
-
- pipeline.sortMode = getEnum("sortMode", SortMode.class, pipeline.sortMode);
- pipeline.targetRegion = getEnum("targetRegion", TargetRegion.class, pipeline.targetRegion);
- pipeline.targetOrientation = getEnum("targetOrientation", TargetOrientation.class, pipeline.targetOrientation);
-
- pipeline.multiple = getBoolean("multiple", pipeline.multiple);
-
- pipeline.targetGroup = getEnum("targetGroup", TargetGroup.class, pipeline.targetGroup);
- pipeline.targetIntersection = getEnum("targetIntersection", TargetIntersection.class, pipeline.targetIntersection);
-
- pipeline.point = getNumberList("point", pipeline.point);
-
- pipeline.calibrationMode = getEnum("calibrationMode", CalibrationMode.class, pipeline.calibrationMode);
-
- pipeline.dualTargetCalibrationM = getDouble("dualTargetCalibrationM", pipeline.dualTargetCalibrationM);
- pipeline.dualTargetCalibrationB = getDouble("dualTargetCalibrationB", pipeline.dualTargetCalibrationB);
-
- pipeline.is3D = getBoolean("is3D", pipeline.is3D);
- pipeline.targetCornerMat = getMatOfPoint3f("targetCornerMat", pipeline.targetCornerMat);
- pipeline.accuracy = getDouble("accuracy", pipeline.accuracy.doubleValue());
-
- return pipeline;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsSerializer.java b/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsSerializer.java
deleted file mode 100644
index ee8958ed8..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/config/serializers/StandardCVPipelineSettingsSerializer.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.chameleonvision.config.serializers;
-
-import com.chameleonvision.vision.pipeline.impl.StandardCVPipelineSettings;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.SerializerProvider;
-
-import java.io.IOException;
-
-public class StandardCVPipelineSettingsSerializer extends BaseSerializer {
- public StandardCVPipelineSettingsSerializer() {
- this(null);
- }
-
- private StandardCVPipelineSettingsSerializer(Class t) {
- super(t);
- }
-
- @Override
- public void serialize(StandardCVPipelineSettings pipeline, JsonGenerator gen, SerializerProvider provider) throws IOException {
- // set BaseSerializer generator reference.
- generator = gen;
-
- gen.writeStartObject();
-
- gen.writeNumberField("index", pipeline.index);
-
- writeEnum("flipMode", pipeline.flipMode);
- writeEnum("rotationMode", pipeline.rotationMode);
-
- gen.writeStringField("nickname", pipeline.nickname);
-
- gen.writeNumberField("exposure", pipeline.exposure);
- gen.writeNumberField("brightness", pipeline.brightness);
- gen.writeNumberField("gain", pipeline.gain);
-
- gen.writeNumberField("videoModeIndex", pipeline.videoModeIndex);
-
- writeEnum("streamDivisor", pipeline.streamDivisor);
-
- writeNumberListAsNumberArray("hue", pipeline.hue);
- writeNumberListAsNumberArray("saturation", pipeline.saturation);
- writeNumberListAsNumberArray("value", pipeline.value);
-
- gen.writeBooleanField("erode", pipeline.erode);
- gen.writeBooleanField("dilate", pipeline.dilate);
-
- writeNumberListAsNumberArray("area", pipeline.area);
- writeNumberListAsNumberArray("ratio", pipeline.ratio);
- writeNumberListAsNumberArray("extent", pipeline.extent);
-
- // speckle rejection
- gen.writeNumberField("speckle", (Integer) pipeline.speckle);
-
- // stream output (camera feed, or thresholded feed)
- gen.writeBooleanField("isBinary", pipeline.isBinary);
-
- writeEnum("sortMode", pipeline.sortMode);
- writeEnum("targetRegion", pipeline.targetRegion);
- writeEnum("targetOrientation", pipeline.targetOrientation);
-
- // show multiple targets when drawing
- gen.writeBooleanField("multiple", pipeline.multiple);
-
- writeEnum("targetGroup", pipeline.targetGroup);
- writeEnum("targetIntersection", pipeline.targetIntersection);
-
- // single calibration point
- writeNumberListAsNumberArray("point", pipeline.point);
-
- // target X/Y calibration
- writeEnum("calibrationMode", pipeline.calibrationMode);
-
- // TODO: better names? or use an array?
- gen.writeNumberField("dualTargetCalibrationM", pipeline.dualTargetCalibrationM);
- gen.writeNumberField("dualTargetCalibrationB", pipeline.dualTargetCalibrationB);
-
-
- gen.writeBooleanField("is3D", pipeline.is3D);
- writeMatOfPoint3f("targetCornerMat", pipeline.targetCornerMat);
- gen.writeNumberField("accuracy", pipeline.accuracy.doubleValue());
- gen.writeEndObject();
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java
deleted file mode 100644
index 84673605f..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/network/NetmaskToCIDR.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.chameleonvision.network;
-
-import java.net.InetAddress;
-
-public class NetmaskToCIDR {
- //code belongs to https://stackoverflow.com/questions/19531411/calculate-cidr-from-a-given-netmask-java
- public static int convertNetmaskToCIDR(InetAddress netmask) {
-
- byte[] netmaskBytes = netmask.getAddress();
- int cidr = 0;
- boolean zero = false;
- for (byte b : netmaskBytes) {
- int mask = 0x80;
-
- for (int i = 0; i < 8; i++) {
- int result = b & mask;
- if (result == 0) {
- zero = true;
- } else if (zero) {
- throw new IllegalArgumentException("Invalid netmask.");
- } else {
- cidr++;
- }
- mask >>>= 1;
- }
- }
- return cidr;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkIPMode.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkIPMode.java
deleted file mode 100644
index ec5a376d3..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkIPMode.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.chameleonvision.network;
-
-public enum NetworkIPMode {
- DHCP,
- STATIC,
- UNKNOWN
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java b/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java
deleted file mode 100644
index 60a99b8f1..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/network/NetworkManager.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.chameleonvision.network;
-
-
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.util.Platform;
-
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class NetworkManager {
- private NetworkManager() {
- }
-
- private static SysNetworking networking;
- private static boolean isManaged = false;
-
- public static void initialize(boolean manage) {
- isManaged = manage;
- if (!isManaged) {
- return;
- }
-
- Platform platform = Platform.CurrentPlatform;
-
- if (platform.isLinux()) {
- networking = new LinuxNetworking();
- } else if (platform.isWindows()) {
-// networking = new WindowsNetworking();
- System.out.println("Windows networking is not yet supported. Running unmanaged.");
- return;
- }
-
- if (networking == null) {
- throw new RuntimeException("Failed to detect platform!");
- }
-
- List interfaces = new ArrayList<>();
- List goodInterfaces = new ArrayList<>();
-
- try {
- interfaces = networking.getNetworkInterfaces();
- } catch (SocketException e) {
- e.printStackTrace();
- }
-
- var teamBytes = NetworkManager.GetTeamNumberIPBytes(ConfigManager.settings.teamNumber);
-
- if (interfaces.size() > 0) {
- for (var inetface : interfaces) {
- for (var inetfaceAddr : inetface.getInterfaceAddresses()) {
- var rawAddr = inetfaceAddr.getAddress().getAddress();
- if (rawAddr.length > 4) continue;
- if (rawAddr[1] == teamBytes[0] && rawAddr[2] == teamBytes[1]) {
- goodInterfaces.add(new NetworkInterface(inetface, inetfaceAddr));
- }
- }
- }
-
- if (goodInterfaces.size() == 0) {
- isManaged = false;
- System.err.println("No valid network interfaces found! Staying unmanaged.");
- return;
- }
-
- NetworkInterface botInterface = goodInterfaces.get(0);
- networking.setNetworkInterface(botInterface);
- } else {
- isManaged = false;
- System.err.println("No valid network interfaces found! Staying unmanaged.");
- }
- }
-
- private static byte[] GetTeamNumberIPBytes(int teamNumber) {
- return new byte[]{(byte) (teamNumber / 100), (byte) (teamNumber % 100)};
- }
-
-
- private static boolean setDHCP() {
- if (!isManaged) {
- return true;
- }
- return networking.setDHCP();
- }
-
- private static boolean setStatic(String ipAddress, String netmask, String gateway) {
- if (!isManaged) {
- return true;
- }
- return networking.setStatic(ipAddress, netmask, gateway);
- }
-
- public static boolean setHostname(String hostname) {
- if (!isManaged) {
- return true;
- }
- return networking.setHostname(hostname);
- }
-
- public static boolean setNetwork(boolean isStatic, String ip, String netmask, String gateway) {
- if (isStatic) {
- return setStatic(ip, netmask, gateway);
- } else {
- return setDHCP();
- }
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java
deleted file mode 100644
index 7073809fb..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/network/SysNetworking.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.chameleonvision.network;
-
-import com.chameleonvision.util.ShellExec;
-
-import java.io.IOException;
-import java.net.SocketException;
-import java.util.List;
-
-public abstract class SysNetworking {
-
- NetworkInterface networkInterface;
- ShellExec shell = new ShellExec(true, true);
-
- public String getHostname() {
- try {
- var retCode = shell.execute("hostname", null, true);
- if (retCode == 0) {
- while(!shell.isOutputCompleted()) {}
- return shell.getOutput();
- } else {
- return null;
- }
- } catch (IOException e) {
- return null;
- }
- }
-
- public void setNetworkInterface(NetworkInterface networkInterface) {
- this.networkInterface = networkInterface;
- }
- public abstract boolean setDHCP();
- public abstract boolean setHostname(String hostname);
- public abstract boolean setStatic(String ipAddress, String netmask, String gateway);
- public abstract List getNetworkInterfaces() throws SocketException;
-
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java b/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java
deleted file mode 100644
index c6fdae74f..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/network/WindowsNetworking.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.chameleonvision.network;
-
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public class WindowsNetworking extends SysNetworking {
-
- @Override
- public boolean setDHCP() {
- return false;
- }
-
- @Override
- public boolean setHostname(String newHostname) {
- var currentHostname = getHostname();
-
- if (getHostname() == null) {
- return false;
- }
-
- String command = String.format("wmic computersystem where name=\"%s\" call rename name=\"%s\"", currentHostname, newHostname);
-
- try {
- var process = Runtime.getRuntime().exec(command);
- var returnCode = process.waitFor();
- return returnCode == 0;
- } catch(Exception e) {
- return false;
- }
- }
-
- @Override
- public boolean setStatic(String ipAddress, String netmask, String gateway) {
- return false;
- }
-
- @Override
- public List getNetworkInterfaces() throws SocketException {
- var netInterfaces = Collections.list(java.net.NetworkInterface.getNetworkInterfaces());
-
- List goodInterfaces = new ArrayList<>();
-
- for (var netInterface : netInterfaces) {
- if (netInterface.getDisplayName().toLowerCase().contains("bluetooth")) continue;
- if (netInterface.getDisplayName().toLowerCase().contains("virtual")) continue;
- if (netInterface.getDisplayName().toLowerCase().contains("loopback")) continue;
- if (!netInterface.isUp()) continue;
- goodInterfaces.add(netInterface);
- }
- return goodInterfaces;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/networktables/NetworkTablesManager.java b/chameleon-server/src/main/java/com/chameleonvision/networktables/NetworkTablesManager.java
deleted file mode 100644
index aab2df65c..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/networktables/NetworkTablesManager.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.chameleonvision.networktables;
-
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.scripting.ScriptEventType;
-import com.chameleonvision.scripting.ScriptManager;
-import edu.wpi.first.networktables.LogMessage;
-import edu.wpi.first.networktables.NetworkTable;
-import edu.wpi.first.networktables.NetworkTableInstance;
-
-import java.util.function.Consumer;
-
-public class NetworkTablesManager {
-
- private NetworkTablesManager() {}
-
- private static final NetworkTableInstance ntInstance = NetworkTableInstance.getDefault();
-
- public static final String kRootTableName = "/chameleon-vision";
- public static final NetworkTable kRootTable = NetworkTableInstance.getDefault().getTable(kRootTableName);
-
- public static boolean isServer = false;
-
- private static int getTeamNumber() {
- return ConfigManager.settings.teamNumber;
- }
-
- private static class NTLogger implements Consumer {
-
- private boolean hasReportedConnectionFailure = false;
-
- @Override
- public void accept(LogMessage logMessage) {
- if (!hasReportedConnectionFailure && logMessage.message.contains("timed out")) {
- System.err.println("NT Connection has failed! Will retry in background.");
- hasReportedConnectionFailure = true;
- } else if (logMessage.message.contains("connected")) {
- System.out.println("NT Connected!");
- hasReportedConnectionFailure = false;
- ScriptManager.queueEvent(ScriptEventType.kNTConnected);
- }
- }
- }
-
- static {
- NetworkTableInstance.getDefault().addLogger(new NTLogger(), 0, 255); // to hide error messages
- }
-
- public static void setClientMode(String host) {
- isServer = false;
- System.out.println("Starting NT Client");
- ntInstance.stopServer();
- if (host != null) {
- ntInstance.startClient(host);
- } else {
- ntInstance.startClientTeam(getTeamNumber());
- if(ntInstance.isConnected()) {
- System.out.println("[NetworkTablesManager] Connected to the robot!");
- } else {
- System.out.println("[NetworkTablesManager] Could NOT to the robot! Will retry in the background...");
- }
- }
- }
-
- public static void setTeamClientMode() {
- setClientMode(null);
- }
-
- public static void setServerMode() {
- isServer = true;
- System.out.println("Starting NT Server");
- ntInstance.stopClient();
- ntInstance.startServer();
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptCommandType.java b/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptCommandType.java
deleted file mode 100644
index 017512065..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptCommandType.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.chameleonvision.scripting;
-
-public enum ScriptCommandType {
- kDefault(""),
- kBashScript("bash"),
- kPythonScript("python"),
- kPython3Script("python3");
-
- public final String value;
-
- ScriptCommandType(String value) {
- this.value = value;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptConfig.java b/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptConfig.java
deleted file mode 100644
index 313397841..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptConfig.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.chameleonvision.scripting;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class ScriptConfig {
- public final ScriptEventType eventType;
- public final String command;
-
- public ScriptConfig(ScriptEventType eventType) {
- this.eventType = eventType;
- this.command = "";
- }
-
- @JsonCreator
- public ScriptConfig(
- @JsonProperty("eventType") ScriptEventType eventType,
- @JsonProperty("command") String command
- ) {
- this.eventType = eventType;
- this.command = command;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEvent.java b/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEvent.java
deleted file mode 100644
index c2f987c5a..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.chameleonvision.scripting;
-
-import com.chameleonvision.Debug;
-import com.chameleonvision.util.ShellExec;
-
-import java.io.IOException;
-
-public class ScriptEvent {
- private static final ShellExec executor = new ShellExec(true, true);
-
- public final ScriptConfig config;
-
- public ScriptEvent(ScriptConfig config) {
- this.config = config;
- }
-
- public int run() throws IOException {
- int retVal = executor.executeBashCommand(config.command);
-
- String output = executor.getOutput();
- String error = executor.getError();
-
- if (!error.isEmpty()) {
- System.err.printf("Error when running \"%s\" script: %s\n", config.eventType.name(), error);
- } else if (!output.isEmpty()) {
- Debug.printInfo(String.format("Output from \"%s\" script: %s\n", config.eventType.name(), output));
- }
- Debug.printInfo(String.format("Script for %s ran with command line: \"%s\", exit code: %d, output: %s, error: %s\n", config.eventType.name(), config.command, retVal, output, error));
- return retVal;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEventType.java b/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEventType.java
deleted file mode 100644
index 436676ee3..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptEventType.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.chameleonvision.scripting;
-
-public enum ScriptEventType {
- kProgramInit("Program Init"),
- kProgramExit("Program Exit"),
- kNTConnected("NT Connected"),
- kLEDOn("LED On"),
- kLEDOff("LED Off"),
- kEnterDriverMode("Enter Driver Mode"),
- kExitDriverMode("Exit Driver Mode"),
- kFoundTarget("Found Target"),
- kFoundMultipleTarget("Found Multiple Target"),
- kLostTarget("Lost Target"),
- kPipelineLag("Pipeline Lag");
-
- public final String value;
-
- ScriptEventType(String value) {
- this.value = value;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptManager.java b/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptManager.java
deleted file mode 100644
index 0e2633658..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/scripting/ScriptManager.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.chameleonvision.scripting;
-
-import com.chameleonvision.Debug;
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.util.JacksonHelper;
-import com.chameleonvision.util.LoopingRunnable;
-import com.chameleonvision.util.Platform;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingDeque;
-
-public class ScriptManager {
-
- private ScriptManager() {
- }
-
- private static final List events = new ArrayList<>();
- private static final LinkedBlockingDeque queuedEvents = new LinkedBlockingDeque<>(25);
-
- public static void initialize() {
- ScriptConfigManager.initialize();
- if (ScriptConfigManager.fileExists()) {
- for (ScriptConfig scriptConfig : ScriptConfigManager.loadConfig()) {
- ScriptEvent scriptEvent = new ScriptEvent(scriptConfig);
- events.add(scriptEvent);
- }
-
- new Thread(new ScriptRunner(10L)).start();
- } else {
- System.err.println("Something went wrong initializing scripts! Events will not run.");
- }
- }
-
- private static class ScriptRunner extends LoopingRunnable {
-
- ScriptRunner(Long loopTimeMs) {
- super(loopTimeMs);
- }
-
- @Override
- protected void process() {
- try {
-
- handleEvent(queuedEvents.takeFirst());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- private void handleEvent(ScriptEventType eventType) {
- var toRun = events.parallelStream().filter(e -> e.config.eventType == eventType).findFirst().orElse(null);
- if (toRun != null) {
- try {
- toRun.run();
- } catch (IOException e) {
- System.err.printf("Failed to run script for event: %s, exception below.\n%s\n", eventType.name(), e.getMessage());
- }
- }
- }
- }
-
- protected static class ScriptConfigManager {
-
- protected static final Path scriptConfigPath = Paths.get(ConfigManager.SettingsPath.toString(), "scripts.json");
-
- private ScriptConfigManager() {
- }
-
- static boolean fileExists() {
- return Files.exists(scriptConfigPath);
- }
-
- public static void initialize() {
- if (!fileExists()) {
- List eventsConfig = new ArrayList<>();
- for (var eventType : ScriptEventType.values()) {
- eventsConfig.add(new ScriptConfig(eventType));
- }
-
- try {
- JacksonHelper.serializer(scriptConfigPath, eventsConfig.toArray(new ScriptConfig[0]), true);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- static List loadConfig() {
- try {
- var raw = JacksonHelper.deserialize(scriptConfigPath, ScriptConfig[].class);
- if (raw != null) {
- return List.of(raw);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return new ArrayList<>();
- }
-
- protected static void deleteConfig() {
- try {
- Files.delete(scriptConfigPath);
- } catch (IOException e) {
- //
- }
- }
- }
-
- public static void queueEvent(ScriptEventType eventType) {
- if (!Platform.getCurrentPlatform().isWindows()) {
- try {
- queuedEvents.putLast(eventType);
- Debug.printInfo("Queued event: " + eventType.name());
- } catch (InterruptedException e) {
- System.err.println("Failed to add event to queue: " + eventType.name());
- }
- }
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/server/Main.java b/chameleon-server/src/main/java/com/chameleonvision/server/Main.java
new file mode 100644
index 000000000..db2fab704
--- /dev/null
+++ b/chameleon-server/src/main/java/com/chameleonvision/server/Main.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.server;
+
+public class Main {
+}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/FileHelper.java b/chameleon-server/src/main/java/com/chameleonvision/util/FileHelper.java
deleted file mode 100644
index 04d97fc2c..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/FileHelper.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.chameleonvision.util;
-
-import com.chameleonvision.Debug;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFileAttributes;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-public class FileHelper {
- private FileHelper() {}
-
- private static final Set allReadWriteExecutePerms = new HashSet<>(Arrays.asList(PosixFilePermission.values()));
-
- public static void setFilePerms(Path path) throws IOException {
- if (!Platform.CurrentPlatform.isWindows()) {
- File thisFile = path.toFile();
- Set perms = Files.readAttributes(path, PosixFileAttributes.class).permissions();
- if (!perms.equals(allReadWriteExecutePerms)) {
- Debug.printInfo("Setting perms on" + path.toString());
- Files.setPosixFilePermissions(path, perms);
- if (thisFile.isDirectory()) {
- for (File subfile : thisFile.listFiles()) {
- setFilePerms(subfile.toPath());
- }
- }
- }
- }
- }
-
- public static void setAllPerms(Path path) {
- if (!Platform.CurrentPlatform.isWindows()) {
- String command = String.format("chmod 777 -R %s", path.toString());
- try {
- Process p = Runtime.getRuntime().exec(command);
- p.waitFor();
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- // TODO file perms on Windows
- System.out.println("File permission setting not available on Windows. Not changing file permissions.");
- }
-
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/Helpers.java b/chameleon-server/src/main/java/com/chameleonvision/util/Helpers.java
deleted file mode 100644
index a4de4acce..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/Helpers.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.chameleonvision.util;
-
-import edu.wpi.cscore.VideoMode;
-import org.opencv.core.Scalar;
-
-import java.awt.*;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.nio.file.Path;
-import java.util.HashMap;
-
-public class Helpers {
- private static final String kServicePath = "/etc/systemd/system/chameleonVision.service";
- private static final String kServiceString = "[Unit]\n" +
- "Description=chameleon vision\n" +
- "\n" +
- "[Service]\n" +
- "ExecStart=/usr/bin/java -jar %s \n" +
- "StandardOutput=file:/var/log/chameleon.out.txt\n" +
- "StandardError=file:/var/log/chameleon.err.txt\n" +
- "Type=simple\n" +
- "WorkingDirectory=/usr/local/bin\n" +
- "\n" +
- "[Install]\n" +
- "WantedBy=multi-user.target\n" +
- "\n";
-
-
-
- private Helpers() {
- }
-
- public static Scalar colorToScalar(Color color) {
- return new Scalar(color.getBlue(), color.getGreen(), color.getRed());
- }
-
- public static HashMap VideoModeToHashMap(VideoMode videoMode) {
- return new HashMap() {{
- put("width", videoMode.width);
- put("height", videoMode.height);
- put("fps", videoMode.fps);
- put("pixelFormat", videoMode.pixelFormat.toString());
- }};
- }
-
- public static void setService(Path filePath) throws IOException, InterruptedException {
- String newService = String.format(kServiceString, filePath.toString());
- File file = new File(kServicePath);
- if (file.exists()) {
- file.delete();
- }
- Writer writer = new FileWriter(file, false);
- writer.write(newService);
- writer.close();
- Process p = Runtime.getRuntime().exec("systemctl enable chameleonVision.service");
- p.waitFor();
- }
-
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/JacksonHelper.java b/chameleon-server/src/main/java/com/chameleonvision/util/JacksonHelper.java
deleted file mode 100644
index da45fdaa9..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/JacksonHelper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.chameleonvision.util;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
-import com.fasterxml.jackson.databind.json.JsonMapper;
-import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
-import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.databind.ser.std.StdSerializer;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Path;
-
-public class JacksonHelper {
- private JacksonHelper() {
- } // no construction, utility class
-
- public static void serializer(Path path, T object) throws IOException {
- serializer(path, object, false);
- }
-
- public static void serializer(Path path, T object, boolean forceSync) throws IOException {
- PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(object.getClass()).build();
- ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
- String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
- saveJsonString(json, path, forceSync);
- }
-
- public static T deserialize(Path path, Class ref) throws IOException {
- PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(ref).build();
- ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build();
- File jsonFile = new File(path.toString());
- if (jsonFile.exists() && jsonFile.length() > 0) {
- return objectMapper.readValue(jsonFile, ref);
- }
- return null;
- }
-
- public static T deserialize(Path path, Class ref, StdDeserializer deserializer) throws IOException {
- ObjectMapper objectMapper = new ObjectMapper();
- SimpleModule module = new SimpleModule();
- module.addDeserializer(ref, deserializer);
- objectMapper.registerModule(module);
-
- File jsonFile = new File(path.toString());
- if (jsonFile.exists() && jsonFile.length() > 0) {
- return objectMapper.readValue(jsonFile, ref);
- }
- return null;
- }
- public static void serialize(Path path, T object, Class ref, StdSerializer serializer) throws IOException {
- serialize(path, object, ref, serializer, false);
- }
-
- public static void serialize(Path path, T object, Class ref, StdSerializer serializer, boolean forceSync) throws IOException {
- ObjectMapper objectMapper = new ObjectMapper();
- SimpleModule module = new SimpleModule();
- module.addSerializer(ref, serializer);
- objectMapper.registerModule(module);
- String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
- saveJsonString(json, path, forceSync);
- }
-
- private static void saveJsonString(String json, Path path, boolean forceSync) throws IOException {
- FileOutputStream fileOutputStream = new FileOutputStream(path.toFile());
- fileOutputStream.write(json.getBytes());
- fileOutputStream.flush();
- if (forceSync) {
- FileDescriptor fileDescriptor = fileOutputStream.getFD();
- fileDescriptor.sync();
- }
- fileOutputStream.close();
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/LoopingRunnable.java b/chameleon-server/src/main/java/com/chameleonvision/util/LoopingRunnable.java
deleted file mode 100644
index 555063956..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/LoopingRunnable.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.chameleonvision.util;
-
-/**
- * A thread that tries to run at a specified loop time
- */
-public abstract class LoopingRunnable implements Runnable {
- protected volatile Long loopTimeMs;
-
- protected abstract void process();
-
- public LoopingRunnable(Long loopTimeMs) {
- this.loopTimeMs = loopTimeMs;
- }
-
- @Override
- public void run() {
- while(!Thread.interrupted()) {
- var now = System.currentTimeMillis();
-
- // Do the thing
- process();
-
- // sleep for the remaining time
- var timeElapsed = System.currentTimeMillis() - now;
- var delta = loopTimeMs - timeElapsed;
- try {
- if(delta > 0.0) {
-
- Thread.sleep(delta, 0);
-
- } else {
- Thread.sleep(1);
- }
- } catch (Exception ignored) {}
- }
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/MathHandler.java b/chameleon-server/src/main/java/com/chameleonvision/util/MathHandler.java
deleted file mode 100644
index bf4433889..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/MathHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.chameleonvision.util;
-
-import org.apache.commons.math3.util.FastMath;
-
-public class MathHandler {
- MathHandler() {}
-
- public static double sigmoid(Number x){
- double bias = 0;
- double a = 5;
- double b = -0.05;
- double k = 200;
-
- if (x.doubleValue() < 50){
- bias = -1.338;
- }
-
- return ((k / (1 + Math.pow(Math.E,(a + (b * x.doubleValue()))))) + bias);
- }
-
- public static double toSlope(Number angle){
- return FastMath.atan(FastMath.toRadians(angle.doubleValue() - 90));
- }
-
- public static double roundTo(double value, int to) {
- double toMult = Math.pow(10, to);
- return (double)Math.round(value * toMult) / toMult;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/MemoryManager.java b/chameleon-server/src/main/java/com/chameleonvision/util/MemoryManager.java
deleted file mode 100644
index b48cc20ad..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/MemoryManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.chameleonvision.util;
-
-public class MemoryManager {
-
- private static final long MEGABYTE_FACTOR = 1024L * 1024L;
-
- private int collectionThreshold;
- private long collectionPeriodMillis = -1;
-
- private double lastUsedMb = 0;
- private long lastCollectionMillis = 0;
-
- public MemoryManager(int collectionThreshold) {
- this.collectionThreshold = collectionThreshold;
- }
-
- public MemoryManager(int collectionThreshold, long collectionPeriodMillis) {
- this.collectionThreshold = collectionThreshold;
- this.collectionPeriodMillis = collectionPeriodMillis;
- }
-
- public void setCollectionThreshold(int collectionThreshold) {
- this.collectionThreshold = collectionThreshold;
- }
-
- public void setCollectionPeriodMillis(long collectionPeriodMillis) {
- this.collectionPeriodMillis = collectionPeriodMillis;
- }
-
- private static long getUsedMemory() {
- return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
- }
-
- private static double getUsedMemoryMB() {
- return ((double) getUsedMemory() / MEGABYTE_FACTOR);
- }
-
- private void collect() {
- System.gc();
- System.runFinalization();
- }
-
- public void run() {
- run(false);
- }
-
- public void run(boolean print) {
- var usedMem = getUsedMemoryMB();
-
- if (usedMem != lastUsedMb) {
- lastUsedMb = usedMem;
- if (print) System.out.printf("Memory usage: %.2fMB\n", usedMem);
- }
-
- boolean collectionThresholdPassed = usedMem >= collectionThreshold;
- boolean collectionPeriodPassed = collectionPeriodMillis != -1 && (System.currentTimeMillis() - lastCollectionMillis >= collectionPeriodMillis);
-
- if (collectionThresholdPassed || collectionPeriodPassed) {
- collect();
- lastCollectionMillis = System.currentTimeMillis();
- if (print) {
- System.out.printf("Garbage collected at %.2fMB\n", usedMem);
- }
- }
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/Platform.java b/chameleon-server/src/main/java/com/chameleonvision/util/Platform.java
deleted file mode 100644
index 203880e98..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/Platform.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.chameleonvision.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-public enum Platform {
- WINDOWS_64("Windows x64"),
- LINUX_64("Linux x64"),
- LINUX_RASPBIAN("Linux Raspbian"),
- LINUX_ARM64("Linux ARM64"),
- MACOS_64("Mac OS x64"),
- UNSUPPORTED("Unsupported Platform");
-
- public final String value;
-
- Platform(String value) {
- this.value = value;
- }
-
- private static final String OS_NAME = System.getProperty("os.name");
- private static final String OS_ARCH = System.getProperty("os.arch");
- public static final Platform CurrentPlatform = getCurrentPlatform();
-
- public boolean isWindows() {
- return this == WINDOWS_64;
- }
-
- public boolean isLinux() {
- return this == LINUX_64 || this == LINUX_RASPBIAN || this == LINUX_ARM64;
- }
-
- public boolean isMac() {
- return this == MACOS_64;
- }
-
- public static boolean isRaspberryPi() {
- return CurrentPlatform.equals(LINUX_RASPBIAN);
- }
-
- private static ShellExec shell = new ShellExec(true, false);
-
- public boolean isRoot() {
- if (isLinux() || isMac()) {
- try {
- shell.execute("id", null, true, "-u");
- } catch (IOException e) {
- e.printStackTrace();
- }
- while (!shell.isOutputCompleted()) {
- // ignored
- }
- if (shell.getExitCode() == 0) {
- var out = shell.getOutput();
- out = out.split("\n")[0];
- return out.equals("0");
- }
- } else if (isWindows()) {
- return true;
- } else {
- return true;
- }
- return false;
- }
-
- private static boolean isRaspbian() {
- try (BufferedReader reader = Files.newBufferedReader(Paths.get("/etc/os-release"))) {
- String value = reader.readLine();
- return value.contains("Raspbian");
- } catch (IOException ex) {
- return false;
- }
- }
-
- public static Platform getCurrentPlatform() {
- if (OS_NAME.contains("Windows")) {
- if (OS_ARCH.equals("amd64")) return Platform.WINDOWS_64;
- }
-
- if (OS_NAME.contains("Linux")) {
- if (OS_ARCH.equals("amd64")) return Platform.LINUX_64;
- if (isRaspbian()) return Platform.LINUX_RASPBIAN;
- if (OS_ARCH.contains("aarch")) return Platform.LINUX_ARM64;
- }
-
- if (OS_NAME.contains("Mac")) {
- if (OS_ARCH.equals("amd64")) return Platform.MACOS_64;
- }
-
- System.out.printf("Unknown Platform! OS: %s, Architecture: %s", OS_NAME, OS_ARCH);
- return Platform.UNSUPPORTED;
- }
-
- public String toString() {
- if (this.equals(UNSUPPORTED)) {
- return String.format("Unknown Platform. OS: %s, Architecture: %s", OS_NAME, OS_ARCH);
- } else {
- return this.value;
- }
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/ProgramDirectoryUtilities.java b/chameleon-server/src/main/java/com/chameleonvision/util/ProgramDirectoryUtilities.java
deleted file mode 100644
index 189547406..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/ProgramDirectoryUtilities.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.chameleonvision.util;
-
-import java.io.File;
-import java.net.URISyntaxException;
-
-public class ProgramDirectoryUtilities {
- private static String getJarName() {
- return new File(ProgramDirectoryUtilities.class.getProtectionDomain()
- .getCodeSource()
- .getLocation()
- .getPath())
- .getName();
- }
-
- private static boolean runningFromJAR() {
- String jarName = getJarName();
- return jarName.contains(".jar");
- }
-
- public static String getProgramDirectory() {
- if (runningFromJAR()) {
- return getCurrentJARDirectory();
- } else {
- return System.getProperty("user.dir");
- }
- }
-
- private static String getCurrentJARDirectory() {
- try {
- return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent();
- } catch (URISyntaxException exception) {
- exception.printStackTrace();
- }
-
- return null;
- }
-}
\ No newline at end of file
diff --git a/chameleon-server/src/main/java/com/chameleonvision/util/Utilities.java b/chameleon-server/src/main/java/com/chameleonvision/util/Utilities.java
deleted file mode 100644
index 0be21374e..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/util/Utilities.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.chameleonvision.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class Utilities {
- private Utilities() {}
-
- public static boolean isValidIPV4(final String ip) {
- String PATTERN = "^((0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)\\.){3}(0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)$";
-
- return ip.matches(PATTERN);
- }
-
- public static List getDigitBytes(int num) {
- List digits = new ArrayList<>();
- collectDigitBytes(num, digits);
- return digits;
- }
-
- private static void collectDigitBytes(int num, List digits) {
- if (num / 10 > 0) {
- collectDigitBytes( num / 10, digits);
- }
- digits.add((byte) (num % 10));
- }
-
- public static List getDigits(int num) {
- List digits = new ArrayList<>();
- collectDigits(num, digits);
- return digits;
- }
-
- private static void collectDigits(int num, List digits) {
- if(num / 10 > 0) {
- collectDigits(num / 10, digits);
- }
- digits.add(num % 10);
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/vision/VisionManager.java b/chameleon-server/src/main/java/com/chameleonvision/vision/VisionManager.java
deleted file mode 100644
index b37c58b0f..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/vision/VisionManager.java
+++ /dev/null
@@ -1,187 +0,0 @@
-package com.chameleonvision.vision;
-
-import com.chameleonvision.config.CameraConfig;
-import com.chameleonvision.config.CameraJsonConfig;
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.config.FullCameraConfiguration;
-import com.chameleonvision.util.Helpers;
-import com.chameleonvision.util.Platform;
-import com.chameleonvision.vision.camera.USBCameraCapture;
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-import edu.wpi.cscore.UsbCamera;
-import edu.wpi.cscore.UsbCameraInfo;
-import org.opencv.videoio.VideoCapture;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-@SuppressWarnings("rawtypes")
-public class VisionManager {
- private VisionManager() {}
-
- private static final LinkedHashMap usbCameraInfosByCameraName = new LinkedHashMap<>();
- private static final LinkedList loadedCameraConfigs = new LinkedList<>();
- private static final LinkedList visionProcesses = new LinkedList<>();
-
- @SuppressWarnings("WeakerAccess")
- private static class VisionProcessManageable {
- public final int index;
- public final String name;
- public final VisionProcess visionProcess;
-
- public VisionProcessManageable(int index, String name, VisionProcess visionProcess) {
- this.index = index;
- this.name = name;
- this.visionProcess = visionProcess;
- }
- }
-
- private static VisionProcess currentUIVisionProcess;
-
- public static boolean initializeSources() {
- int suffix = 0;
- for (UsbCameraInfo info : UsbCamera.enumerateUsbCameras()) {
- VideoCapture cap = new VideoCapture(info.dev);
- if (cap.isOpened()) {
- cap.release();
- // Filter non-ascii characters because ext4 doesn't play nice with unicode in directory names
- String name = info.name.replaceAll("[^\\x00-\\x7F]", "");
- while (usbCameraInfosByCameraName.containsKey(name)) {
- suffix++;
- name = String.format("%s (%d)", name, suffix);
- }
- usbCameraInfosByCameraName.put(name, info);
- }
- }
-
- if (usbCameraInfosByCameraName.isEmpty()) {
- return false;
- }
- System.out.printf("[VisionManager] Found %s cameras!\n", usbCameraInfosByCameraName.size());
-
- // load the config
- List preliminaryConfigs = new ArrayList<>();
-
- usbCameraInfosByCameraName.forEach((suffixedName, cameraInfo) -> {
- String truePath;
-
- if (Platform.CurrentPlatform.isWindows()) {
- truePath = cameraInfo.path;
- } else {
- truePath = Arrays.stream(cameraInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst().orElse(cameraInfo.path);
- }
-
- preliminaryConfigs.add(new CameraJsonConfig(truePath, suffixedName));
- });
-
- loadedCameraConfigs.addAll(ConfigManager.initializeCameras(preliminaryConfigs));
- System.out.printf("[VisionManager] Loaded %s cameras!\n", loadedCameraConfigs.size());
- return true;
- }
-
- public static boolean initializeProcesses() {
- for (int i = 0; i < loadedCameraConfigs.size(); i++) {
- FullCameraConfiguration config = loadedCameraConfigs.get(i);
-
- CameraJsonConfig cameraJsonConfig = config.cameraConfig;
-
- USBCameraCapture camera = new USBCameraCapture(config);
- VisionProcess process = new VisionProcess(camera, config);
- process.pipelineManager.driverModePipeline.settings = config.driverMode;
- visionProcesses.add(new VisionProcessManageable(i, cameraJsonConfig.name, process));
- }
- currentUIVisionProcess = getVisionProcessByIndex(0);
- ConfigManager.settings.currentCamera = visionProcesses.get(0).name;
-
- System.out.printf("[VisionManager] Loaded %s vision processes! Current process: %s\n", visionProcesses.size(), visionProcesses.get(0).name);
- return true;
- }
-
- public static void startProcesses() {
- visionProcesses.forEach((vpm) -> vpm.visionProcess.start());
- }
-
- public static VisionProcess getCurrentUIVisionProcess() {
- return currentUIVisionProcess;
- }
-
- public static CameraConfig getCurrentCameraConfig() {
- return getCameraConfig(currentUIVisionProcess);
- }
-
- public static CameraConfig getCameraConfig(VisionProcess process) {
- String cameraName = process.getCamera().getProperties().name;
- return Objects.requireNonNull(loadedCameraConfigs.stream().filter(x -> x.cameraConfig.name.equals(cameraName)).findFirst().orElse(null)).fileConfig;
- }
-
- public static void setCurrentProcessByIndex(int processIndex) {
- if (processIndex > visionProcesses.size() - 1) {
- return;
- }
-
- currentUIVisionProcess = getVisionProcessByIndex(processIndex);
- ConfigManager.settings.currentCamera = visionProcesses.get(processIndex).name;
- }
-
- public static VisionProcess getVisionProcessByIndex(int processIndex) {
- if (processIndex > visionProcesses.size() - 1) {
- return null;
- }
-
- VisionProcessManageable vpm = visionProcesses.stream().filter(manageable -> manageable.index == processIndex).findFirst().orElse(null);
- return vpm != null ? vpm.visionProcess : null;
- }
-
- public static List getAllCameraNicknames() {
- return visionProcesses.stream().map(vpm -> vpm.visionProcess.getCamera()
- .getProperties().getNickname()).collect(Collectors.toList());
- }
-
- public static List getCurrentCameraPipelineNicknames() {
- return currentUIVisionProcess.pipelineManager.pipelines.stream().map(cvPipeline -> cvPipeline.settings.nickname).collect(Collectors.toList());
- }
-
-
- public static void saveAllCameras() {
- visionProcesses.forEach((vpm) -> {
- VisionProcess process = vpm.visionProcess;
- String cameraName = process.getCamera().getProperties().name;
- List pipelines = process.pipelineManager.pipelines.stream().map(cvPipeline -> cvPipeline.settings).collect(Collectors.toList());
- CVPipelineSettings driverMode = process.getDriverModeSettings();
- CameraJsonConfig config = CameraJsonConfig.fromVisionProcess(process);
- ConfigManager.saveCameraPipelines(cameraName, pipelines);
- ConfigManager.saveCameraDriverMode(cameraName, driverMode);
- ConfigManager.saveCameraConfig(cameraName, config);
- });
- }
-
- private static String getCurrentCameraName() {
- return currentUIVisionProcess.getCamera().getProperties().name;
- }
-
- public static void saveCurrentCameraSettings() {
- CameraJsonConfig config = CameraJsonConfig.fromVisionProcess(currentUIVisionProcess);
- ConfigManager.saveCameraConfig(getCurrentCameraName(), config);
- }
-
- public static void saveCurrentCameraPipelines() {
- currentUIVisionProcess.pipelineManager.saveAllPipelines();
- }
-
- public static void saveCurrentCameraDriverMode() {
- currentUIVisionProcess.pipelineManager.saveDriverModeConfig();
- }
-
- private static List getCameraResolutionList(USBCameraCapture capture) {
- return capture.getProperties().getVideoModes().stream().map(Helpers::VideoModeToHashMap).collect(Collectors.toList());
- }
-
- public static List getCurrentCameraResolutionList() {
- return getCameraResolutionList(currentUIVisionProcess.getCamera());
- }
-
- public static int getCurrentUIVisionProcessIndex() {
- VisionProcessManageable vpm = visionProcesses.stream().filter(v -> v.visionProcess == currentUIVisionProcess).findFirst().orElse(null);
- return vpm != null ? vpm.index : -1;
- }
-}
diff --git a/chameleon-server/src/main/java/com/chameleonvision/vision/VisionProcess.java b/chameleon-server/src/main/java/com/chameleonvision/vision/VisionProcess.java
deleted file mode 100644
index bb0e474e7..000000000
--- a/chameleon-server/src/main/java/com/chameleonvision/vision/VisionProcess.java
+++ /dev/null
@@ -1,389 +0,0 @@
-package com.chameleonvision.vision;
-
-import com.chameleonvision.Debug;
-import com.chameleonvision.config.CameraCalibrationConfig;
-import com.chameleonvision.config.CameraConfig;
-import com.chameleonvision.config.ConfigManager;
-import com.chameleonvision.config.FullCameraConfiguration;
-import com.chameleonvision.networktables.NetworkTablesManager;
-import com.chameleonvision.scripting.ScriptEventType;
-import com.chameleonvision.scripting.ScriptManager;
-import com.chameleonvision.util.MathHandler;
-import com.chameleonvision.vision.camera.CameraStreamer;
-import com.chameleonvision.vision.camera.USBCameraCapture;
-import com.chameleonvision.vision.pipeline.CVPipelineResult;
-import com.chameleonvision.vision.pipeline.CVPipelineSettings;
-import com.chameleonvision.vision.pipeline.PipelineManager;
-import com.chameleonvision.vision.pipeline.impl.DriverVisionPipeline;
-import com.chameleonvision.vision.pipeline.impl.StandardCVPipeline;
-import com.chameleonvision.vision.pipeline.impl.StandardCVPipelineSettings;
-import com.chameleonvision.web.SocketHandler;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import edu.wpi.cscore.VideoMode;
-import edu.wpi.first.networktables.*;
-import edu.wpi.first.wpilibj.geometry.Pose2d;
-import edu.wpi.first.wpiutil.CircularBuffer;
-import org.apache.commons.lang3.tuple.Pair;
-import org.opencv.core.Mat;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-
-@SuppressWarnings("rawtypes")
-public class VisionProcess {
-
- public final USBCameraCapture cameraCapture;
- private final VisionProcessRunnable visionRunnable;
- private final CameraConfig fileConfig;
- public final CameraStreamer cameraStreamer;
- public PipelineManager pipelineManager;
-
- private volatile CVPipelineResult lastPipelineResult;
-
- // network table stuff
- private final NetworkTable defaultTable;
- private NetworkTableInstance tableInstance;
- private NetworkTableEntry ntPipelineEntry;
- public NetworkTableEntry ntDriverModeEntry;
- private int ntDriveModeListenerID;
- private int ntPipelineListenerID;
- private NetworkTableEntry ntYawEntry;
- private NetworkTableEntry ntPitchEntry;
- private NetworkTableEntry ntAuxListEntry;
- private NetworkTableEntry ntAreaEntry;
- private NetworkTableEntry ntLatencyEntry;
- private NetworkTableEntry ntValidEntry;
- private NetworkTableEntry ntPoseEntry;
- private NetworkTableEntry ntFittedHeightEntry;
- private NetworkTableEntry ntFittedWidthEntry;
- private NetworkTableEntry ntBoundingHeightEntry;
- private NetworkTableEntry ntBoundingWidthEntry;
- private NetworkTableEntry ntTargetRotation;
-
- private ObjectMapper objectMapper = new ObjectMapper();
-
- private long lastUIUpdateMs = 0;
-
- VisionProcess(USBCameraCapture cameraCapture, FullCameraConfiguration config) {
- this.cameraCapture = cameraCapture;
-
- fileConfig = config.fileConfig;
-
- pipelineManager = new PipelineManager(this, config.pipelines);
-
- // Thread to put frames on the dashboard
- this.cameraStreamer = new CameraStreamer(cameraCapture, config.cameraConfig.name, pipelineManager.getCurrentPipeline().settings.streamDivisor);
-
- // Thread to process vision data
- this.visionRunnable = new VisionProcessRunnable();
-
- // network table
- defaultTable = NetworkTableInstance.getDefault().getTable("/chameleon-vision/" + cameraCapture.getProperties().getNickname());
- }
-
- public void start() {
- System.out.printf("[%s Process] Creating network table...\n", getCamera().getProperties().getNickname());
- initNT(defaultTable);
-
- System.out.printf("[%s Process] Starting vision thread...\n", getCamera().getProperties().getNickname());
- var visionThread = new Thread(visionRunnable);
- visionThread.setName(getCamera().getProperties().name + " - Vision Thread");
- visionThread.start();
- }
-
- /**
- * Removes the old value change listeners
- * calls {@link #initNT}
- *
- * @param newTable passed to {@link #initNT}
- */
- public void resetNT(NetworkTable newTable) {
- ntDriverModeEntry.removeListener(ntDriveModeListenerID);
- ntPipelineEntry.removeListener(ntPipelineListenerID);
- initNT(newTable);
- }
-
- public void setCameraNickname(String newName) {
- getCamera().getProperties().setNickname(newName);
- NetworkTable camTable = NetworkTablesManager.kRootTable.getSubTable(newName);
- resetNT(camTable);
- }
-
- private void initNT(NetworkTable camTable) {
- tableInstance = camTable.getInstance();
- ntPipelineEntry = camTable.getEntry("pipeline");
- ntDriverModeEntry = camTable.getEntry("driverMode");
- ntPitchEntry = camTable.getEntry("targetPitch");
- ntYawEntry = camTable.getEntry("targetYaw");
- ntAreaEntry = camTable.getEntry("targetArea");
- ntLatencyEntry = camTable.getEntry("latency");
- ntValidEntry = camTable.getEntry("isValid");
- ntAuxListEntry = camTable.getEntry("auxTargets");
- ntPoseEntry = camTable.getEntry("targetPose");
- ntFittedHeightEntry = camTable.getEntry("targetFittedHeight");
- ntFittedWidthEntry = camTable.getEntry("targetFittedWidth");
- ntBoundingHeightEntry = camTable.getEntry("targetBoundingHeight");
- ntBoundingWidthEntry = camTable.getEntry("targetBoundingWidth");
- ntTargetRotation = camTable.getEntry("targetRotation");
- ntDriveModeListenerID = ntDriverModeEntry.addListener(this::setDriverMode, EntryListenerFlags.kUpdate);
- ntPipelineListenerID = ntPipelineEntry.addListener(this::setPipeline, EntryListenerFlags.kUpdate);
- ntDriverModeEntry.setBoolean(false);
- ntPipelineEntry.setNumber(pipelineManager.getCurrentPipelineIndex());
- pipelineManager.ntIndexEntry = ntPipelineEntry;
- }
-
- private void setDriverMode(EntryNotification driverModeEntryNotification) {
- setDriverMode(driverModeEntryNotification.value.getBoolean());
- }
-
- public void setDriverMode(boolean driverMode) {
- pipelineManager.setDriverMode(driverMode);
- ScriptManager.queueEvent(driverMode ? ScriptEventType.kEnterDriverMode : ScriptEventType.kExitDriverMode);
- SocketHandler.sendFullSettings();
- }
-
- /**
- * Method called by the nt entry listener to update the next pipeline.
- *
- * @param notification the notification
- */
- private void setPipeline(EntryNotification notification) {
- var wantedPipelineIndex = (int) notification.value.getDouble();
- if (pipelineManager.pipelines.size() - 1 < wantedPipelineIndex) {
- ntPipelineEntry.setDouble(pipelineManager.getCurrentPipelineIndex());
- } else {
- pipelineManager.setCurrentPipeline(wantedPipelineIndex);
- }
- }
-
- public void setDriverModeEntry(boolean isDriverMode) {
- // if it's null, we haven't even started the program yet, so just return
- // otherwise, set it.
- if (ntDriverModeEntry != null) {
- ntDriverModeEntry.setBoolean(isDriverMode);
- }
- }
-
- private void updateUI(CVPipelineResult data) {
- // 30 "FPS" update rate
- long currentMillis = System.currentTimeMillis();
- if (currentMillis - lastUIUpdateMs > 1000 / 30) {
- lastUIUpdateMs = currentMillis;
-
-
- if (cameraCapture.getProperties().name.equals(ConfigManager.settings.currentCamera)) {
- HashMap WebSend = new HashMap<>();
- HashMap point = new HashMap<>();
- HashMap pointMap = new HashMap<>();
- ArrayList