2019-09-21 16:04:58 +03:00
|
|
|
package com.chameleonvision.web;
|
|
|
|
|
|
2019-11-22 14:34:21 -08:00
|
|
|
import com.chameleonvision.classabstraction.VisionManager;
|
2019-11-23 04:05:37 -05:00
|
|
|
import com.chameleonvision.classabstraction.VisionProcess;
|
|
|
|
|
import com.chameleonvision.classabstraction.camera.CameraProcess;
|
2019-11-22 14:34:21 -08:00
|
|
|
import com.chameleonvision.classabstraction.config.ConfigManager;
|
2019-11-23 04:05:37 -05:00
|
|
|
import com.chameleonvision.classabstraction.pipeline.CVPipeline;
|
|
|
|
|
import com.chameleonvision.classabstraction.pipeline.CVPipelineSettings;
|
2019-10-14 22:36:56 +03:00
|
|
|
import com.chameleonvision.vision.*;
|
2019-11-23 04:05:37 -05:00
|
|
|
import com.chameleonvision.vision.camera.StreamDivisor;
|
2019-11-02 10:10:02 -07:00
|
|
|
import com.chameleonvision.vision.camera.USBCamera;
|
2019-10-04 15:55:45 -04:00
|
|
|
import com.chameleonvision.vision.camera.CameraException;
|
2019-09-21 16:04:58 +03:00
|
|
|
import com.chameleonvision.settings.SettingsManager;
|
2019-10-14 11:21:20 +03:00
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
2019-10-11 02:25:25 +03:00
|
|
|
import io.javalin.websocket.*;
|
2019-10-14 11:21:20 +03:00
|
|
|
|
2019-10-11 02:25:25 +03:00
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
2019-10-14 11:21:20 +03:00
|
|
|
import org.msgpack.jackson.dataformat.MessagePackFactory;
|
2019-10-13 22:59:36 +03:00
|
|
|
|
2019-09-21 16:04:58 +03:00
|
|
|
import java.lang.reflect.Field;
|
2019-10-14 11:21:20 +03:00
|
|
|
import java.nio.ByteBuffer;
|
2019-10-11 02:25:25 +03:00
|
|
|
import java.util.*;
|
2019-09-21 16:04:58 +03:00
|
|
|
|
2019-10-12 03:38:42 +03:00
|
|
|
|
2019-09-21 16:04:58 +03:00
|
|
|
public class ServerHandler {
|
|
|
|
|
|
|
|
|
|
private static List<WsContext> users;
|
2019-10-14 11:21:20 +03:00
|
|
|
private static ObjectMapper objectMapper;
|
2019-09-21 16:04:58 +03:00
|
|
|
|
2019-09-21 13:05:00 -04:00
|
|
|
ServerHandler() {
|
|
|
|
|
users = new ArrayList<>();
|
2019-10-14 11:21:20 +03:00
|
|
|
objectMapper = new ObjectMapper(new MessagePackFactory());
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-09-21 13:05:00 -04:00
|
|
|
void onConnect(WsConnectContext context) {
|
2019-09-21 16:04:58 +03:00
|
|
|
users.add(context);
|
|
|
|
|
sendFullSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onClose(WsCloseContext context) {
|
|
|
|
|
users.remove(context);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-14 22:24:37 +03:00
|
|
|
void onBinaryMessage(WsBinaryMessageContext context) throws Exception {
|
2019-10-20 10:13:07 +03:00
|
|
|
Map<String, Object> deserialized = objectMapper.readValue(ArrayUtils.toPrimitive(context.data()), new TypeReference<Map<String, Object>>() {
|
|
|
|
|
});
|
|
|
|
|
for (Map.Entry<String, Object> entry : deserialized.entrySet()) {
|
2019-10-13 21:58:34 +03:00
|
|
|
try {
|
2019-11-23 04:05:37 -05:00
|
|
|
var data = (HashMap<String, Object>) entry.getValue();
|
|
|
|
|
VisionProcess currentProcess = VisionManager.getCurrentUIVisionProcess();
|
|
|
|
|
CameraProcess currentCamera = currentProcess.getCamera();
|
|
|
|
|
CVPipeline currentPipeline = currentProcess.getCurrentPipeline();
|
|
|
|
|
|
2019-10-14 11:21:20 +03:00
|
|
|
switch (entry.getKey()) {
|
2019-10-13 22:59:36 +03:00
|
|
|
case "generalSettings": {
|
2019-11-23 04:05:37 -05:00
|
|
|
for (HashMap.Entry<String, Object> e : data.entrySet()) {
|
2019-11-22 14:34:21 -08:00
|
|
|
setField(ConfigManager.settings, e.getKey(), e.getValue());
|
2019-10-15 21:00:18 +03:00
|
|
|
}
|
2019-10-21 20:22:39 +03:00
|
|
|
SettingsManager.saveSettings();
|
2019-10-26 23:41:45 +03:00
|
|
|
sendFullSettings();
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-11-01 17:01:10 +02:00
|
|
|
case "driverMode": {
|
2019-11-23 04:05:37 -05:00
|
|
|
for (HashMap.Entry<String, Object> e : data.entrySet()) {
|
|
|
|
|
setField(VisionManager.getCurrentUIVisionProcess(), e.getKey(), e.getValue());
|
2019-11-01 17:01:10 +02:00
|
|
|
}
|
2019-11-23 04:05:37 -05:00
|
|
|
VisionManager.getCurrentUIVisionProcess().setDriverMode((Boolean) data.get("isDriver"));
|
|
|
|
|
|
|
|
|
|
// TODO: (HIGH) create saveCameras() function in VisionManager
|
|
|
|
|
// VisionManager.saveCameras();
|
2019-11-01 17:01:10 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
case "cameraSettings": {
|
2019-10-20 10:13:07 +03:00
|
|
|
HashMap camSettings = (HashMap) entry.getValue();
|
2019-11-02 03:34:51 -04:00
|
|
|
|
|
|
|
|
Number newFOV = (Number) camSettings.get("fov");
|
2019-11-23 04:05:37 -05:00
|
|
|
StreamDivisor newStreamDivisor = StreamDivisor.values()[(Integer) camSettings.get("streamDivisor")];
|
2019-11-02 03:34:51 -04:00
|
|
|
Integer newResolution = (Integer) camSettings.get("resolution");
|
|
|
|
|
|
2019-11-23 04:05:37 -05:00
|
|
|
currentCamera.getProperties().FOV = (double) newFOV;
|
2019-11-02 03:34:51 -04:00
|
|
|
|
2019-11-23 04:05:37 -05:00
|
|
|
if (currentProcess.cameraStreamer.getDivisor() != newStreamDivisor) {
|
|
|
|
|
currentProcess.cameraStreamer.setDivisor(newStreamDivisor);
|
2019-11-02 03:34:51 -04:00
|
|
|
}
|
|
|
|
|
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO (HIGH) get and set video modes!
|
|
|
|
|
// var currentResolutionIndex = currentPipeline.getVideoModeIndex();
|
|
|
|
|
// if (currentResolutionIndex != newResolution) {
|
|
|
|
|
// currentCamera.getProperties().setCamVideoMode(newResolution, true);
|
|
|
|
|
// }
|
2019-11-02 03:34:51 -04:00
|
|
|
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) create saveCameras() function in VisionManager
|
|
|
|
|
// VisionManager.saveCameras();
|
2019-10-26 23:41:45 +03:00
|
|
|
sendFullSettings();
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
case "changeCameraName": {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentCamera.getProperties().setNickname((String) entry.getValue());
|
2019-10-25 14:02:42 +03:00
|
|
|
sendFullSettings();
|
2019-10-29 21:26:13 +02:00
|
|
|
SettingsManager.saveSettings();
|
2019-10-24 15:20:15 -04:00
|
|
|
break;
|
2019-10-19 17:45:40 +03:00
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
case "changePipelineName": {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentPipeline.settings.nickname = ((String) entry.getValue());
|
2019-10-25 15:57:46 +03:00
|
|
|
sendFullSettings();
|
2019-10-29 21:26:13 +02:00
|
|
|
SettingsManager.saveSettings();
|
2019-10-24 15:20:15 -04:00
|
|
|
break;
|
2019-10-19 17:45:40 +03:00
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
case "duplicatePipeline": {
|
2019-10-24 15:20:15 -04:00
|
|
|
HashMap pipelineVals = (HashMap) entry.getValue();
|
|
|
|
|
int pipelineIndex = (int) pipelineVals.get("pipeline");
|
|
|
|
|
int cameraIndex = (int) pipelineVals.get("camera");
|
|
|
|
|
|
2019-11-23 04:05:37 -05:00
|
|
|
CVPipeline origPipeline = currentProcess.getPipelineByIndex(pipelineIndex);
|
2019-10-24 15:20:15 -04:00
|
|
|
|
|
|
|
|
if (cameraIndex != -1) {
|
2019-11-23 04:05:37 -05:00
|
|
|
VisionProcess newProcess = VisionManager.getVisionProcessByIndex(cameraIndex);
|
|
|
|
|
if(newProcess != null) {
|
|
|
|
|
newProcess.addPipeline(origPipeline);
|
|
|
|
|
}
|
2019-10-24 15:20:15 -04:00
|
|
|
} else {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentProcess.addPipeline(origPipeline);
|
2019-10-24 15:20:15 -04:00
|
|
|
}
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) switch to ConfigManager
|
2019-10-29 21:26:13 +02:00
|
|
|
SettingsManager.saveSettings();
|
2019-10-24 15:20:15 -04:00
|
|
|
break;
|
2019-10-19 17:45:40 +03:00
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
case "command": {
|
2019-10-20 10:13:07 +03:00
|
|
|
switch ((String) entry.getValue()) {
|
2019-10-19 16:58:10 +03:00
|
|
|
case "addNewPipeline":
|
2019-11-23 04:05:37 -05:00
|
|
|
currentProcess.addPipeline();
|
2019-10-25 14:05:00 +03:00
|
|
|
sendFullSettings();
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) switch to ConfigManager
|
2019-10-29 21:26:13 +02:00
|
|
|
SettingsManager.saveSettings();
|
2019-10-19 16:58:10 +03:00
|
|
|
break;
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) this never worked before, re-visit now that VisionProcess is written sanely
|
2019-10-19 16:58:10 +03:00
|
|
|
case "deleteCurrentPipeline":
|
2019-11-23 04:05:37 -05:00
|
|
|
// int currentIndex = currentProcess.getCurrentPipelineIndex();
|
|
|
|
|
// int nextIndex;
|
|
|
|
|
// if (currentIndex == currentProcess.getPipelines().size() - 1) {
|
|
|
|
|
// nextIndex = currentIndex - 1;
|
|
|
|
|
// } else {
|
|
|
|
|
// nextIndex = currentIndex;
|
|
|
|
|
// }
|
|
|
|
|
// cam.deletePipeline();
|
|
|
|
|
// cam.setCurrentPipelineIndex(nextIndex);
|
|
|
|
|
// sendFullSettings();
|
|
|
|
|
// SettingsManager.saveSettings();
|
2019-10-29 21:26:13 +02:00
|
|
|
break;
|
|
|
|
|
case "save":
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) switch to ConfigManager
|
2019-10-29 21:26:13 +02:00
|
|
|
SettingsManager.saveSettings();
|
2019-11-01 17:10:48 +02:00
|
|
|
System.out.println("saved Settings");
|
2019-10-19 16:58:10 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
// used to define all incoming commands
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "currentCamera": {
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) find way to map cameras to indexes
|
|
|
|
|
VisionManager.setCurrentProcessByIndex((Integer) entry.getValue());
|
2019-10-25 15:57:46 +03:00
|
|
|
sendFullSettings();
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "currentPipeline": {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentProcess.setPipeline((Integer) entry.getValue());
|
2019-10-26 23:41:45 +03:00
|
|
|
sendFullSettings();
|
2019-10-25 15:02:17 +03:00
|
|
|
try {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentCamera.setBrightness((int) currentPipeline.settings.brightness);
|
|
|
|
|
currentCamera.setExposure((int) currentPipeline.settings.exposure);
|
2019-10-29 15:26:10 +02:00
|
|
|
} catch (Exception e) {
|
2019-10-25 15:02:17 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
default: {
|
2019-11-23 04:05:37 -05:00
|
|
|
setField(currentPipeline.settings, entry.getKey(), entry.getValue());
|
|
|
|
|
|
2019-10-20 10:13:07 +03:00
|
|
|
switch (entry.getKey()) {
|
|
|
|
|
case "exposure": {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentCamera.setExposure((Integer) entry.getValue());
|
2019-10-14 23:35:29 +03:00
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
case "brightness": {
|
2019-11-23 04:05:37 -05:00
|
|
|
currentCamera.setBrightness((Integer) entry.getValue());
|
2019-10-14 23:35:29 +03:00
|
|
|
}
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
break;
|
2019-10-13 21:58:34 +03:00
|
|
|
}
|
|
|
|
|
}
|
2019-10-13 22:59:36 +03:00
|
|
|
} catch (Exception e) {
|
2019-10-19 16:58:10 +03:00
|
|
|
System.err.println(e.getMessage());
|
2019-10-13 21:58:34 +03:00
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
broadcastMessage(deserialized, context);
|
2019-10-12 03:38:42 +03:00
|
|
|
}
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
|
2019-10-14 21:22:43 +03:00
|
|
|
private void setField(Object obj, String fieldName, Object value) {
|
2019-09-21 16:04:58 +03:00
|
|
|
try {
|
2019-11-02 10:10:02 -07:00
|
|
|
if (obj instanceof USBCamera) {
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO: (HIGH) FIXXX!!!! this won't work anymore
|
|
|
|
|
// the UI should instead understand that DriverMode is a pipeline (?)
|
|
|
|
|
USBCamera cam = (USBCamera)obj;
|
2019-11-02 04:37:28 -04:00
|
|
|
if (fieldName.equals("driverBrightness")) {
|
|
|
|
|
cam.setDriverBrightness((Integer)value);
|
|
|
|
|
} else if (fieldName.equals("driverExposure")) {
|
|
|
|
|
cam.setDriverExposure((Integer)value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
Field field = obj.getClass().getField(fieldName);
|
2019-10-30 14:32:57 +02:00
|
|
|
if (field.getType().isEnum())
|
|
|
|
|
field.set(obj, field.getType().getEnumConstants()[(Integer) value]);
|
|
|
|
|
else
|
2019-10-20 10:13:07 +03:00
|
|
|
field.set(obj, value);
|
2019-10-14 21:22:43 +03:00
|
|
|
} catch (NoSuchFieldException | IllegalAccessException ex) {
|
|
|
|
|
ex.printStackTrace();
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-12 03:38:42 +03:00
|
|
|
private static void broadcastMessage(Object obj, WsContext userToSkip) {
|
|
|
|
|
if (users != null)
|
2019-11-23 04:05:37 -05:00
|
|
|
for (WsContext user : users) {
|
2019-10-12 03:38:42 +03:00
|
|
|
if (userToSkip != null && user.getSessionId().equals(userToSkip.getSessionId())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
try {
|
2019-10-14 11:21:20 +03:00
|
|
|
ByteBuffer b = ByteBuffer.wrap(objectMapper.writeValueAsBytes(obj));
|
|
|
|
|
user.send(b);
|
|
|
|
|
} catch (JsonProcessingException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
2019-10-12 03:38:42 +03:00
|
|
|
}
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-10-16 14:13:12 +03:00
|
|
|
public static void broadcastMessage(Object obj) {
|
2019-10-11 02:25:25 +03:00
|
|
|
broadcastMessage(obj, null);//Broadcasts the message to every user
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
|
2019-10-20 10:13:07 +03:00
|
|
|
private static HashMap<String, Object> getOrdinalPipeline() throws CameraException, IllegalAccessException {
|
|
|
|
|
HashMap<String, Object> tmp = new HashMap<>();
|
|
|
|
|
for (Field f : Pipeline.class.getFields()) {
|
|
|
|
|
if (!f.getType().isEnum()) {
|
2019-11-23 04:05:37 -05:00
|
|
|
tmp.put(f.getName(), f.get(VisionManager.getCurrentUIVisionProcess().getCurrentPipeline()));
|
2019-10-20 10:13:07 +03:00
|
|
|
} else {
|
2019-11-23 04:05:37 -05:00
|
|
|
var i = (Enum) f.get(VisionManager.getCurrentUIVisionProcess().getCurrentPipeline());
|
2019-10-20 10:13:07 +03:00
|
|
|
tmp.put(f.getName(), i.ordinal());
|
2019-10-14 22:36:56 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
|
|
|
|
|
private static HashMap<String, Object> getOrdinalSettings() {
|
|
|
|
|
HashMap<String, Object> tmp = new HashMap<>();
|
2019-11-22 14:34:21 -08:00
|
|
|
tmp.put("teamNumber", ConfigManager.settings.teamNumber);
|
|
|
|
|
tmp.put("connectionType", ConfigManager.settings.connectionType.ordinal());
|
|
|
|
|
tmp.put("ip", ConfigManager.settings.ip);
|
|
|
|
|
tmp.put("gateway", ConfigManager.settings.gateway);
|
|
|
|
|
tmp.put("netmask", ConfigManager.settings.netmask);
|
|
|
|
|
tmp.put("hostname", ConfigManager.settings.hostname);
|
2019-10-15 21:00:18 +03:00
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
|
|
|
|
|
private static HashMap<String, Object> getOrdinalCameraSettings() {
|
|
|
|
|
HashMap<String, Object> tmp = new HashMap<>();
|
2019-11-23 04:05:37 -05:00
|
|
|
VisionProcess currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
|
|
|
|
CameraProcess currentCamera = VisionManager.getCurrentUIVisionProcess().getCamera();
|
|
|
|
|
tmp.put("fov", currentCamera.getProperties().FOV);
|
|
|
|
|
tmp.put("streamDivisor", currentVisionProcess.cameraStreamer.getDivisor().ordinal());
|
|
|
|
|
// TODO: (HIGH) get videomode index!
|
|
|
|
|
// tmp.put("resolution", currentCamera.getVideoModeIndex());
|
2019-10-16 14:13:12 +03:00
|
|
|
return tmp;
|
|
|
|
|
}
|
2019-10-20 10:13:07 +03:00
|
|
|
|
2019-11-01 17:01:10 +02:00
|
|
|
private static HashMap<String, Object> getOrdinalDriver() {
|
|
|
|
|
HashMap<String, Object> tmp = new HashMap<>();
|
2019-11-23 04:05:37 -05:00
|
|
|
VisionProcess currentProcess = VisionManager.getCurrentUIVisionProcess();
|
|
|
|
|
CVPipelineSettings driverModeSettings = currentProcess.getDriverModeSettings();
|
|
|
|
|
tmp.put("isDriver", currentProcess.getDriverMode());
|
|
|
|
|
tmp.put("driverBrightness", driverModeSettings.brightness);
|
|
|
|
|
tmp.put("driverExposure", driverModeSettings.exposure);
|
2019-11-01 17:01:10 +02:00
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-22 02:49:30 -04:00
|
|
|
public static void sendFullSettings() {
|
2019-09-21 16:04:58 +03:00
|
|
|
//General settings
|
2019-10-15 21:00:18 +03:00
|
|
|
Map<String, Object> fullSettings = new HashMap<>();
|
2019-09-21 16:04:58 +03:00
|
|
|
try {
|
2019-10-15 21:00:18 +03:00
|
|
|
fullSettings.put("settings", getOrdinalSettings());
|
2019-10-20 10:13:07 +03:00
|
|
|
fullSettings.put("cameraSettings", getOrdinalCameraSettings());
|
2019-11-23 04:05:37 -05:00
|
|
|
fullSettings.put("cameraList", VisionManager.getAllCameraNicknames());
|
2019-10-14 22:36:56 +03:00
|
|
|
fullSettings.put("pipeline", getOrdinalPipeline());
|
2019-11-23 04:05:37 -05:00
|
|
|
var currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
2019-11-01 17:01:10 +02:00
|
|
|
fullSettings.put("driverMode",getOrdinalDriver());
|
2019-11-23 04:05:37 -05:00
|
|
|
// TODO (HIGH) all of these settings!
|
|
|
|
|
// fullSettings.put("pipelineList", currentVisionProcess.getPipelinesNickname());
|
|
|
|
|
// fullSettings.put("resolutionList", currentVisionProcess.getResolutionList());
|
|
|
|
|
// fullSettings.put("port", currentVisionProcess.getStreamPort());
|
|
|
|
|
fullSettings.put("currentPipelineIndex", VisionManager.getCurrentUIVisionProcess().getCurrentPipelineIndex());
|
|
|
|
|
// fullSettings.put("currentCameraIndex", VisionManager.getCurrentCameraIndex());
|
2019-10-14 22:36:56 +03:00
|
|
|
} catch (CameraException | IllegalAccessException e) {
|
2019-09-21 16:04:58 +03:00
|
|
|
System.err.println("No camera found!");
|
|
|
|
|
}
|
2019-10-14 21:22:43 +03:00
|
|
|
broadcastMessage(fullSettings);
|
2019-09-21 16:04:58 +03:00
|
|
|
}
|
|
|
|
|
}
|