Merge branch 'dev' into 'master'

Dev

See merge request chameleon-vision/Chameleon-Vision!19
This commit is contained in:
ori agranat
2019-10-01 16:58:18 +00:00
12 changed files with 305 additions and 128 deletions

View File

@@ -10,6 +10,23 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxathena:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxraspbian:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:windowsx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cameraserver:cameraserver-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxathena:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxraspbian:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:windowsx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.wpiutil:wpiutil-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-java:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:windowsx86-64:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxx86-64:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxathena:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxraspbian:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: io.javalin:javalin:3.4.1" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.31" level="project" />
@@ -40,25 +57,27 @@
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.9.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxathena:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxraspbian:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:windowsx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cameraserver:cameraserver-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxathena:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxraspbian:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:windowsx86-64:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.wpiutil:wpiutil-java:2019.4.1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-java:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:windowsx86-64:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxx86-64:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxathena:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2019.opencv:opencv-jni:linuxraspbian:3.4.4-5" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.0.pr1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.10.0.pr1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.0.pr1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-java:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxaarch64bionic:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxraspbian:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:linuxx86-64:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:osxx86-64:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cscore:cscore-jni:windowsx86-64:2019.4.1-200-g2271570" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.cameraserver:cameraserver-java:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-java:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:osxx86-64:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxraspbian:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:linuxx86-64:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.ntcore:ntcore-jni:windowsx86-64:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.wpiutil:wpiutil-java:2019.4.1-176-ga5650b9" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-java:3.4.7-1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:linuxaarch64bionic:3.4.7-1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:linuxraspbian:3.4.7-1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:linuxx86-64:3.4.7-1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:osxx86-64:3.4.7-1" level="project" />
<orderEntry type="library" name="Maven: edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:windowsx86-64:3.4.7-1" level="project" />
</component>
</module>

View File

@@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.chameleon-vision.main</groupId>
<artifactId>chameleon-vision</artifactId>
<version>1.0.2-BETA</version>
<version>1.1.0-BETA</version>
<build>
<plugins>
<!--setup for java jdk 12-->
@@ -44,10 +44,15 @@
</properties>
<repositories>
<!--WPI official maven repo for frc libs-->
<!-- <repository>-->
<!-- <id>WPI</id>-->
<!-- <name>WPI Maven repo</name>-->
<!-- <url>https://first.wpi.edu/FRC/roborio/maven/release</url>-->
<!-- </repository>-->
<repository>
<id>WPI</id>
<name>WPI Maven repo</name>
<url>https://first.wpi.edu/FRC/roborio/maven/release</url>
<name>WPILib Artifactory Server-releases</name>
<url>https://frcmaven.wpi.edu:443/artifactory/development</url>
</repository>
</repositories>
<dependencies>
@@ -84,7 +89,6 @@
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!--what is this for again?-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
@@ -95,42 +99,54 @@
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0.pr1</version>
</dependency>
<!-- supported platforms for wpilib JNI classifiers
linuxathena
linuxaarch64bionic
linuxraspbian
linuxx86-64
osxx86-64
windowsx86-64
-->
<!--frc cscore java libs-->
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-java</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-200-g2271570</version>
</dependency>
<!--frc cscore interface libs-->
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-jni</artifactId>
<version>2019.4.1</version>
<classifier>linuxathena</classifier>
<version>2019.4.1-200-g2271570</version>
<classifier>linuxaarch64bionic</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-200-g2271570</version>
<classifier>linuxraspbian</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-200-g2271570</version>
<classifier>linuxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-200-g2271570</version>
<classifier>osxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.cscore</groupId>
<artifactId>cscore-jni</artifactId>
<version>2019.4.1-200-g2271570</version>
<classifier>windowsx86-64</classifier>
</dependency>
@@ -138,39 +154,39 @@
<dependency>
<groupId>edu.wpi.first.cameraserver</groupId>
<artifactId>cameraserver-java</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
</dependency>
<!--frc network table java libs-->
<dependency>
<groupId>edu.wpi.first.ntcore</groupId>
<artifactId>ntcore-java</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
</dependency>
<!--frc network tables interface libs-->
<dependency>
<groupId>edu.wpi.first.ntcore</groupId>
<artifactId>ntcore-jni</artifactId>
<version>2019.4.1</version>
<classifier>linuxathena</classifier>
<version>2019.4.1-176-ga5650b9</version>
<classifier>osxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.ntcore</groupId>
<artifactId>ntcore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
<classifier>linuxraspbian</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.ntcore</groupId>
<artifactId>ntcore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
<classifier>linuxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.ntcore</groupId>
<artifactId>ntcore-jni</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
<classifier>windowsx86-64</classifier>
</dependency>
@@ -178,43 +194,44 @@
<dependency>
<groupId>edu.wpi.first.wpiutil</groupId>
<artifactId>wpiutil-java</artifactId>
<version>2019.4.1</version>
<version>2019.4.1-176-ga5650b9</version>
</dependency>
<!-- WPI OpenCV for all supported platforms -->
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2019.opencv</groupId>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-java</artifactId>
<version>3.4.4-5</version>
<version>3.4.7-1</version>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2019.opencv</groupId>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.4-5</version>
<classifier>windowsx86-64</classifier>
<version>3.4.7-1</version>
<classifier>linuxaarch64bionic</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2019.opencv</groupId>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.4-5</version>
<classifier>linuxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2019.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.4-5</version>
<classifier>linuxathena</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2019.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.4-5</version>
<version>3.4.7-1</version>
<classifier>linuxraspbian</classifier>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0.pr1</version>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.7-1</version>
<classifier>linuxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.7-1</version>
<classifier>osxx86-64</classifier>
</dependency>
<dependency>
<groupId>edu.wpi.first.thirdparty.frc2020.opencv</groupId>
<artifactId>opencv-jni</artifactId>
<version>3.4.7-1</version>
<classifier>windowsx86-64</classifier>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,15 @@
package com.chameleonvision.Handler;
import java.lang.Math;
public class MathHandler {
MathHandler(){}
public static double sigmoid(double x){
double bias = 0;
double a = 5;
double b = -0.05;
double k = 200;
if (x < 50){
bias = -1.338;
}
return ((k / (1 + Math.pow(Math.E,(a + (b * x))))) + bias);
}
}

View File

@@ -1,23 +1,116 @@
package com.chameleonvision;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.util.Utilities;
import com.chameleonvision.vision.camera.CameraManager;
import com.chameleonvision.vision.process.VisionProcess;
import com.chameleonvision.web.Server;
import edu.wpi.cscore.CameraServerCvJNI;
import edu.wpi.cscore.CameraServerJNI;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
if (CameraManager.initializeCameras()) {
SettingsManager.initialize();
for (var camSet : CameraManager.getAllCamerasByName().entrySet()) {
new Thread(new VisionProcess(camSet.getValue())).start();
}
NetworkTableInstance.getDefault().startClientTeam(SettingsManager.GeneralSettings.team_number);
// NetworkTableInstance.getDefault().startClient("localhost");
Server.main(8888);
} else {
System.err.println("No cameras connected!");
}
}
private static final String PORT_KEY = "--port"; // expects integer
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 int DEFAULT_PORT = 8888;
private static int webserverPort = DEFAULT_PORT;
private static boolean ntServerMode = false;
private static boolean manageNetwork = true;
private static String ntClientModeServer = null;
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 PORT_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 NT_SERVERMODE_KEY:
case NETWORK_MANAGE_KEY:
// nothing
}
// this switch actually handles the arguments.
switch (key) {
case PORT_KEY:
System.out.println("INFO - The \"--port\" argument is currently disabled.");
// try {
// if (value == null) throw new Exception("Bad or No argument value");
// webserverPort = Integer.parseInt(value);
// } catch (Exception ex) {
// System.err.printf("Argument for port was invalid, starting server at port %d\n", DEFAULT_PORT);
// }
break;
case NT_SERVERMODE_KEY:
ntServerMode = true;
break;
case NT_CLIENTMODESERVER_KEY:
if (value != null) {
if (value.equals("localhost")) {
ntClientModeServer = "127.0.0.1";
return;
}
if (Utilities.isValidIPV4(value)) {
ntClientModeServer = value;
return;
}
}
System.err.println("Argument for NT Server Host was invalid, defaulting to team number host");
break;
case NETWORK_MANAGE_KEY:
manageNetwork = false;
break;
}
}
}
public static void main(String[] args) {
handleArgs(args);
// Attempt to load the JNI Libraries
try {
CameraServerJNI.forceLoad();
CameraServerCvJNI.forceLoad();
} catch (IOException e) {
var errorStr = SettingsManager.getCurrentPlatform().equals(SettingsManager.Platform.UNSUPPORTED) ? "Unsupported platform!" : "Failed to load JNI Libraries!";
throw new RuntimeException(errorStr);
}
if (CameraManager.initializeCameras()) {
SettingsManager.initialize(manageNetwork);
CameraManager.initializeThreads();
if (ntServerMode) {
System.out.println("Starting NT Server");
NetworkTableInstance.getDefault().startServer();
} else {
if (ntClientModeServer != null) {
NetworkTableInstance.getDefault().startClient(ntClientModeServer);
} else {
NetworkTableInstance.getDefault().startClientTeam(SettingsManager.GeneralSettings.team_number);
}
}
System.out.printf("Starting Webserver at port %d\n", webserverPort);
Server.main(webserverPort);
} else {
System.err.println("No cameras connected!");
}
}
}

View File

@@ -14,21 +14,22 @@ import java.nio.file.Path;
import java.nio.file.Paths;
public class SettingsManager {
public static final Path SettingsPath = Paths.get(System.getProperty("user.dir"), "Settings");
public static final Path SettingsPath = Paths.get(System.getProperty("user.dir"), "settings");
public static com.chameleonvision.vision.GeneralSettings GeneralSettings;
private SettingsManager() {}
public static void initialize() {
public static void initialize(boolean manageNetwork) {
initGeneralSettings();
NetworkSettings netSettings = new NetworkSettings();
netSettings.hostname = GeneralSettings.hostname;
netSettings.gateway = GeneralSettings.gateway;
netSettings.netmask = GeneralSettings.netmask;
netSettings.connectionType = GeneralSettings.connection_type;
netSettings.ip = GeneralSettings.ip;
netSettings.run();
if (manageNetwork) {
NetworkSettings netSettings = new NetworkSettings();
netSettings.hostname = GeneralSettings.hostname;
netSettings.gateway = GeneralSettings.gateway;
netSettings.netmask = GeneralSettings.netmask;
netSettings.connectionType = GeneralSettings.connection_type;
netSettings.ip = GeneralSettings.ip;
netSettings.run();
}
var allCameras = CameraManager.getAllCamerasByName();
if (!allCameras.containsKey(GeneralSettings.curr_camera) && allCameras.size() > 0) {
var cam = allCameras.entrySet().stream().findFirst().get().getValue();
@@ -79,7 +80,7 @@ public class SettingsManager {
private static void initGeneralSettings() {
FileHelper.CheckPath(SettingsPath);
try {
GeneralSettings = new Gson().fromJson(new FileReader(Paths.get(SettingsPath.toString(), "Settings.json").toString()), com.chameleonvision.vision.GeneralSettings.class);
GeneralSettings = new Gson().fromJson(new FileReader(Paths.get(SettingsPath.toString(), "settings.json").toString()), com.chameleonvision.vision.GeneralSettings.class);
} catch (FileNotFoundException e) {
GeneralSettings = new GeneralSettings();
}

View File

@@ -0,0 +1,11 @@
package com.chameleonvision.util;
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);
}
}

View File

@@ -1,11 +1,13 @@
package com.chameleonvision.vision.camera;
import com.chameleonvision.CameraException;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.vision.Pipeline;
import com.chameleonvision.web.ServerHandler;
import edu.wpi.cscore.*;
import edu.wpi.first.cameraserver.CameraServer;
import org.opencv.core.Mat;
import org.springframework.core.env.Environment;
import java.util.Arrays;
import java.util.HashMap;
@@ -34,8 +36,6 @@ public class Camera {
private CamVideoMode camVideoMode;
private int currentPipelineIndex;
private HashMap<Integer, Pipeline> pipelines;
private long initTimeout;
public Camera(String cameraName) {
this(cameraName, DEFAULT_FOV);
@@ -69,7 +69,7 @@ public class Camera {
// set up video modes according to minimums
if (SettingsManager.getCurrentPlatform() == SettingsManager.Platform.WINDOWS_64 && !UsbCam.isConnected()) {
System.out.print("Waiting on camera... ");
initTimeout = System.nanoTime();
long initTimeout = System.nanoTime();
while(!UsbCam.isConnected())
{
//TODO add a time sleep, can wait only so long before giving up
@@ -80,7 +80,12 @@ public class Camera {
var initTimeMs = (System.nanoTime() - initTimeout) / 1e6;
System.out.printf("Camera initialized in %.2fms\n", initTimeMs);
}
availableVideoModes = Arrays.stream(UsbCam.enumerateVideoModes()).filter(v -> v.fps >= MINIMUM_FPS && v.width >= MINIMUM_WIDTH && v.height >= MINIMUM_HEIGHT).toArray(VideoMode[]::new);
var trueVideoModes = UsbCam.enumerateVideoModes();
availableVideoModes = Arrays.stream(trueVideoModes).filter(v -> v.fps >= MINIMUM_FPS && v.width >= MINIMUM_WIDTH && v.height >= MINIMUM_HEIGHT && v.pixelFormat == VideoMode.PixelFormat.kYUYV).toArray(VideoMode[]::new);
if (availableVideoModes.length == 0) {
System.err.println("Camera not supported!");
throw new RuntimeException(new CameraException(CameraException.CameraExceptionType.BAD_CAMERA));
}
if (videoModeIndex <= availableVideoModes.length - 1) {
setCamVideoMode(videoModeIndex, false);
} else {
@@ -89,8 +94,6 @@ public class Camera {
cvSink = cs.getVideo(UsbCam);
cvSource = cs.putVideo(name, camVals.ImageWidth, camVals.ImageHeight);
var s = (MjpegServer) cs.getServer("serve_" + name);
CameraManager.CameraPorts.put(name, s.getPort());
}
VideoMode[] getAvailableVideoModes() {
@@ -109,9 +112,7 @@ public class Camera {
private void setCamVideoMode(CamVideoMode newVideoMode, boolean updateCvSource) {
var prevVideoMode = this.camVideoMode;
this.camVideoMode = newVideoMode;
UsbCam.setPixelFormat(newVideoMode.getActualPixelFormat());
UsbCam.setFPS(newVideoMode.fps);
UsbCam.setResolution(newVideoMode.width, newVideoMode.height);
UsbCam.setVideoMode(newVideoMode.getActualPixelFormat(), newVideoMode.width, newVideoMode.height, newVideoMode.fps);
// update camera values
camVals = new CameraValues(this);

View File

@@ -3,7 +3,9 @@ package com.chameleonvision.vision.camera;
import com.chameleonvision.CameraException;
import com.chameleonvision.FileHelper;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.vision.GeneralSettings;
import com.chameleonvision.vision.Pipeline;
import com.chameleonvision.vision.process.VisionProcess;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import edu.wpi.cscore.UsbCamera;
@@ -14,15 +16,17 @@ import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
public class CameraManager {
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "Cams");
public static HashMap<String, Integer> CameraPorts = new HashMap<>();
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "cameras");
private static HashMap<String, Camera> AllCamerasByName = new HashMap<>();
private static HashMap<String, VisionProcess> AllVisionProcessesByName = new HashMap<>();
static HashMap<String, UsbCameraInfo> AllUsbCameraInfosByName = new HashMap<>() {{
var suffix = 0;
@@ -47,30 +51,38 @@ public class CameraManager {
public static boolean initializeCameras() {
if (AllUsbCameraInfosByName.size() == 0) return false;
FileHelper.CheckPath(CamConfigPath);
for (var entry : AllUsbCameraInfosByName.entrySet()) {
var camPath = Paths.get(CamConfigPath.toString(), String.format("%s.json", entry.getKey()));
AllUsbCameraInfosByName.forEach((key, value) -> {
var camPath = Paths.get(CamConfigPath.toString(), String.format("%s.json", key));
File camJsonFile = new File(camPath.toString());
if (camJsonFile.exists() && camJsonFile.length() != 0) {
try {
Gson gson = new GsonBuilder().registerTypeAdapter(Camera.class, new CameraDeserializer()).create();
var camJsonFileReader = new FileReader(camPath.toString());
var gsonRead = gson.fromJson(camJsonFileReader, Camera.class);
AllCamerasByName.put(entry.getKey(), gsonRead);
AllCamerasByName.put(key, gsonRead);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
} else {
if (!addCamera(new Camera(entry.getKey()), entry.getKey())) {
if (!addCamera(new Camera(key), key)) {
System.err.println("Failed to add camera! Already exists!");
}
}
}
});
return true;
}
public static void initializeThreads(){
AllCamerasByName.forEach((key, value) -> {
VisionProcess visionProcess = new VisionProcess(value);
AllVisionProcessesByName.put(key, visionProcess);
new Thread(visionProcess).start();
});
}
private static boolean addCamera(Camera camera, String cameraName) {
if (AllCamerasByName.containsKey(cameraName)) return false;
for (int i = 0; i < 10;i++){
for (int i = 0; i < 10; i++){
camera.addPipeline(); // simple fix to create more pipelines for now
}
AllCamerasByName.put(cameraName, camera);
@@ -108,11 +120,14 @@ public class CameraManager {
public static List<String> getResolutionList() throws CameraException {
if (!SettingsManager.GeneralSettings.curr_camera.equals("")) {
List<String> list = new ArrayList<>();
for (var res : CameraManager.getCamera(SettingsManager.GeneralSettings.curr_camera).getAvailableVideoModes()) {
list.add(String.format("%s X %s at %s fps", res.width, res.height, res.fps));
}
return list;
return Arrays.stream(CameraManager.getCamera(SettingsManager.GeneralSettings.curr_camera).getAvailableVideoModes())
.map(res -> String.format("%s X %s at %s fps", res.width, res.height, res.fps)).collect(Collectors.toList());
}
throw new CameraException(CameraException.CameraExceptionType.NO_CAMERA);
}
public static VisionProcess getCurrentCameraProcess() throws CameraException{
if (!SettingsManager.GeneralSettings.curr_camera.equals("")){
return AllVisionProcessesByName.get(SettingsManager.GeneralSettings.curr_camera);
}
throw new CameraException(CameraException.CameraExceptionType.NO_CAMERA);
}

View File

@@ -1,11 +1,11 @@
package com.chameleonvision.vision.process;
import com.chameleonvision.vision.camera.CameraValues;
import com.chameleonvision.Handler.MathHandler;
import org.apache.commons.math3.util.FastMath;
import org.jetbrains.annotations.NotNull;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import java.util.*;
@SuppressWarnings("WeakerAccess")
@@ -57,8 +57,8 @@ public class CVProcess {
for (MatOfPoint Contour : InputContours) {
try {
double contourArea = Imgproc.contourArea(Contour);
double minArea = (area.get(0) * CamVals.ImageArea) / 100;
double maxArea = (area.get(1) * CamVals.ImageArea) / 100;
double minArea = (MathHandler.sigmoid(area.get(0)) * CamVals.ImageArea) / 100;
double maxArea = (MathHandler.sigmoid(area.get(1)) * CamVals.ImageArea) / 100;
if (contourArea <= minArea || contourArea >= maxArea) {
continue;
}

View File

@@ -8,5 +8,6 @@ public class PipelineResult {
public double CalibratedY = 0.0;
public double Pitch = 0.0;
public double Yaw = 0.0;
public double Area = 0.0;
RotatedRect RawPoint;
}

View File

@@ -20,8 +20,8 @@ public class VisionProcess implements Runnable {
private final String cameraName;
private final CameraProcess cameraProcess;
// NetworkTables
private NetworkTableEntry ntPipelineEntry;
private NetworkTableEntry ntDriverModeEntry;
public NetworkTableEntry ntPipelineEntry;
public NetworkTableEntry ntDriverModeEntry;
private NetworkTableEntry ntYawEntry;
private NetworkTableEntry ntPitchEntry;
private NetworkTableEntry ntDistanceEntry;
@@ -46,17 +46,17 @@ public class VisionProcess implements Runnable {
// NetworkTables
NetworkTable ntTable = NetworkTableInstance.getDefault().getTable("/chameleon-vision/" + cameraName);
ntPipelineEntry = ntTable.getEntry("Pipeline");
ntDriverModeEntry = ntTable.getEntry("Driver_Mode");
ntPitchEntry = ntTable.getEntry("Pitch");
ntYawEntry = ntTable.getEntry("Yaw");
ntDistanceEntry = ntTable.getEntry("Distance");
ntTimeStampEntry = ntTable.getEntry("TimeStamp");
ntValidEntry = ntTable.getEntry("Valid");
ntPipelineEntry = ntTable.getEntry("pipeline");
ntDriverModeEntry = ntTable.getEntry("driver_mode");
ntPitchEntry = ntTable.getEntry("pitch");
ntYawEntry = ntTable.getEntry("yaw");
ntDistanceEntry = ntTable.getEntry("distance");
ntTimeStampEntry = ntTable.getEntry("timestamp");
ntValidEntry = ntTable.getEntry("is_valid");
ntDriverModeEntry.addListener(this::DriverModeListener, EntryListenerFlags.kUpdate);
ntPipelineEntry.addListener(this::PipelineListener, EntryListenerFlags.kUpdate);
ntDriverModeEntry.setBoolean(false);
ntPipelineEntry.setString("pipeline" + camera.getCurrentPipelineIndex());
ntPipelineEntry.setNumber(camera.getCurrentPipelineIndex());
// camera settings
cvProcess = new CVProcess(camera.getCamVals());
@@ -75,7 +75,7 @@ public class VisionProcess implements Runnable {
}
private void PipelineListener(EntryNotification entryNotification) {
var ntPipelineIndex = Integer.parseInt(entryNotification.value.getString().replace("pipeline", ""));
var ntPipelineIndex = (int) entryNotification.value.getDouble();
if (camera.getPipelines().containsKey(ntPipelineIndex)) {
// camera.setEntryNotification.value.getString());
var pipeline = camera.getCurrentPipeline();
@@ -87,13 +87,15 @@ public class VisionProcess implements Runnable {
System.err.println(e.toString());
}
camera.setBrightness(pipeline.brightness);
HashMap<String, Object> pipeChange = new HashMap<>();
pipeChange.put("curr_pipeline", ntPipelineIndex);
ServerHandler.broadcastMessage(pipeChange);
ServerHandler.sendFullSettings();
if (SettingsManager.GeneralSettings.curr_camera.equals(cameraName)){
SettingsManager.GeneralSettings.curr_pipeline = ntPipelineIndex;
HashMap<String, Object> pipeChange = new HashMap<>();
pipeChange.put("curr_pipeline", ntPipelineIndex);
ServerHandler.broadcastMessage(pipeChange);
ServerHandler.sendFullSettings();
}
} else {
ntPipelineEntry.setString("pipeline" + camera.getCurrentPipelineIndex());
ntPipelineEntry.setNumber(camera.getCurrentPipelineIndex());
}
}
@@ -112,6 +114,8 @@ public class VisionProcess implements Runnable {
if (pipelineResult.IsValid) {
ntYawEntry.setNumber(pipelineResult.Yaw);
ntPitchEntry.setNumber(pipelineResult.Pitch);
ntDistanceEntry.setNumber(pipelineResult.Area);
NetworkTableInstance.getDefault().flush();
}
ntTimeStampEntry.setNumber(TimeStamp);
}
@@ -158,6 +162,7 @@ public class VisionProcess implements Runnable {
}
pipelineResult.Pitch = camera.getCamVals().CalculatePitch(finalRect.center.y, pipelineResult.CalibratedY);
pipelineResult.Yaw = camera.getCamVals().CalculateYaw(finalRect.center.x, pipelineResult.CalibratedX);
pipelineResult.Area = finalRect.size.area();
drawContour(outputImage, finalRect);
}
}

View File

@@ -99,11 +99,10 @@ public class ServerHandler {
sendFullSettings();
break;
case "curr_pipeline":
String newPipeline = value.toString();
var pipelineNumber = Integer.parseInt(newPipeline.replace("pipeline", ""));
int newPipeline = (int) value;
System.out.printf("Changing pipeline to %s\n", newPipeline);
CameraManager.setCurrentPipeline(pipelineNumber);
// broadcastMessage(allFieldsToMap(CameraManager.getCurrentPipeline()));
CameraManager.setCurrentPipeline(newPipeline);
CameraManager.getCurrentCameraProcess().ntPipelineEntry.setNumber(newPipeline);
broadcastMessage(allFieldsToMap(CameraManager.getCurrentPipeline()));
break;