mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-22 01:11:40 +00:00
general settings and camera settings as http requests
This commit is contained in:
@@ -2,14 +2,13 @@ package com.chameleonvision.vision.camera;
|
||||
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import com.chameleonvision.vision.Pipeline;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import com.chameleonvision.web.SocketHandler;
|
||||
import edu.wpi.cscore.*;
|
||||
import edu.wpi.first.cameraserver.CameraServer;
|
||||
import edu.wpi.first.networktables.NetworkTable;
|
||||
import edu.wpi.first.networktables.NetworkTableInstance;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -157,7 +156,7 @@ public class Camera {
|
||||
var newHeight = camVideoMode.height / streamDivisor.value;
|
||||
cvSource = cs.putVideo(name, newWidth, newHeight);
|
||||
}
|
||||
ServerHandler.sendFullSettings();
|
||||
SocketHandler.sendFullSettings();
|
||||
}
|
||||
|
||||
public void addPipeline() {
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.vision.Orientation;
|
||||
import com.chameleonvision.vision.Pipeline;
|
||||
import com.chameleonvision.vision.camera.Camera;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import com.chameleonvision.web.SocketHandler;
|
||||
import edu.wpi.cscore.VideoException;
|
||||
import edu.wpi.first.networktables.*;
|
||||
import org.opencv.core.*;
|
||||
@@ -76,8 +76,8 @@ public class VisionProcess implements Runnable {
|
||||
SettingsManager.GeneralSettings.currentPipeline = ntPipelineIndex;
|
||||
HashMap<String, Object> pipeChange = new HashMap<>();
|
||||
pipeChange.put("currentPipeline", ntPipelineIndex);
|
||||
ServerHandler.broadcastMessage(pipeChange);
|
||||
ServerHandler.sendFullSettings();
|
||||
SocketHandler.broadcastMessage(pipeChange);
|
||||
SocketHandler.sendFullSettings();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -245,7 +245,7 @@ public class VisionProcess implements Runnable {
|
||||
point.put("calculated", calculated);
|
||||
point.put("rawPoint", center);
|
||||
WebSend.put("point", point);
|
||||
ServerHandler.broadcastMessage(WebSend);
|
||||
SocketHandler.broadcastMessage(WebSend);
|
||||
}
|
||||
|
||||
cameraProcess.setOutputFrame(streamOutputMat);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.chameleonvision.web;
|
||||
|
||||
import com.chameleonvision.network.NetworkIPMode;
|
||||
import com.chameleonvision.settings.GeneralSettings;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.vision.camera.CameraException;
|
||||
import com.chameleonvision.vision.camera.CameraManager;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.javalin.http.Context;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Requesthandler {
|
||||
|
||||
public static void onGeneralSettings(Context ctx) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
Map map = objectMapper.readValue(ctx.body(), Map.class);
|
||||
SettingsManager.GeneralSettings.teamNumber = (int) map.get("teamNumber");
|
||||
SettingsManager.GeneralSettings.connectionType = NetworkIPMode.values()[(int) map.get("connectionType")];
|
||||
SettingsManager.GeneralSettings.ip = (String) map.get("ip");
|
||||
SettingsManager.GeneralSettings.netmask = (String) map.get("netmask");
|
||||
SettingsManager.GeneralSettings.gateway = (String) map.get("gateway");
|
||||
SettingsManager.GeneralSettings.hostname = (String) map.get("hostname");
|
||||
SettingsManager.saveSettings();
|
||||
SocketHandler.sendFullSettings();
|
||||
ctx.status(200);
|
||||
} catch (JsonProcessingException e) {
|
||||
ctx.status(500);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onCameraSettings(Context ctx) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
Map camSettings = objectMapper.readValue(ctx.body(), Map.class);
|
||||
var curCam = CameraManager.getCurrentCamera();
|
||||
|
||||
Number newFOV = (Number) camSettings.get("fov");
|
||||
Integer newStreamDivisor = (Integer) camSettings.get("streamDivisor");
|
||||
Integer newResolution = (Integer) camSettings.get("resolution");
|
||||
|
||||
curCam.setFOV(newFOV);
|
||||
|
||||
var currentStreamDivisorOrdinal = curCam.getStreamDivisor().ordinal();
|
||||
if (currentStreamDivisorOrdinal != newStreamDivisor) {
|
||||
curCam.setStreamDivisor(newStreamDivisor, true);
|
||||
}
|
||||
|
||||
var currentResolutionIndex = curCam.getVideoModeIndex();
|
||||
if (currentResolutionIndex != newResolution) {
|
||||
curCam.setCamVideoMode(newResolution, true);
|
||||
}
|
||||
|
||||
CameraManager.saveCameras();
|
||||
SocketHandler.sendFullSettings();
|
||||
ctx.status(200);
|
||||
} catch (JsonProcessingException | CameraException e) {
|
||||
e.printStackTrace();
|
||||
ctx.status(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,30 +3,33 @@ package com.chameleonvision.web;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import io.javalin.Javalin;
|
||||
|
||||
|
||||
public class Server {
|
||||
public static ServerHandler handler;
|
||||
private static SocketHandler socketHandler;
|
||||
|
||||
public static void main(int port) {
|
||||
handler = new ServerHandler();
|
||||
socketHandler = new SocketHandler();
|
||||
|
||||
Javalin app = Javalin.create(javalinConfig -> javalinConfig.showJavalinBanner=false);
|
||||
app.config.addStaticFiles("web");
|
||||
Javalin app = Javalin.create(javalinConfig -> {
|
||||
javalinConfig.showJavalinBanner = false;
|
||||
javalinConfig.addStaticFiles("web");
|
||||
javalinConfig.enableCorsForAllOrigins();
|
||||
});
|
||||
app.ws("/websocket", ws -> {
|
||||
ws.onConnect(ctx -> {
|
||||
handler.onConnect(ctx);
|
||||
socketHandler.onConnect(ctx);
|
||||
System.out.println("Socket Connected");
|
||||
});
|
||||
ws.onClose(ctx -> {
|
||||
handler.onClose(ctx);
|
||||
socketHandler.onClose(ctx);
|
||||
System.out.println("Socket Disconnected");
|
||||
SettingsManager.saveSettings();
|
||||
});
|
||||
ws.onBinaryMessage(ctx -> {
|
||||
handler.onBinaryMessage(ctx);
|
||||
socketHandler.onBinaryMessage(ctx);
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/api/settings/general", Requesthandler::onGeneralSettings);
|
||||
app.post("/api/settings/camera", Requesthandler::onCameraSettings);
|
||||
app.start(port);
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,12 @@ import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class ServerHandler {
|
||||
public class SocketHandler {
|
||||
|
||||
private static List<WsContext> users;
|
||||
private static ObjectMapper objectMapper;
|
||||
|
||||
ServerHandler() {
|
||||
SocketHandler() {
|
||||
users = new ArrayList<>();
|
||||
objectMapper = new ObjectMapper(new MessagePackFactory());
|
||||
}
|
||||
@@ -47,14 +47,6 @@ public class ServerHandler {
|
||||
for (Map.Entry<String, Object> entry : deserialized.entrySet()) {
|
||||
try {
|
||||
switch (entry.getKey()) {
|
||||
case "generalSettings": {
|
||||
for (HashMap.Entry<String, Object> e : ((HashMap<String, Object>) entry.getValue()).entrySet()) {
|
||||
setField(SettingsManager.GeneralSettings, e.getKey(), e.getValue());
|
||||
}
|
||||
SettingsManager.saveSettings();
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "driverMode": {
|
||||
for (HashMap.Entry<String, Object> e : ((HashMap<String, Object>) entry.getValue()).entrySet()) {
|
||||
setField(CameraManager.getCurrentCamera(), e.getKey(), e.getValue());
|
||||
@@ -63,30 +55,6 @@ public class ServerHandler {
|
||||
CameraManager.saveCameras();
|
||||
break;
|
||||
}
|
||||
case "cameraSettings": {
|
||||
HashMap camSettings = (HashMap) entry.getValue();
|
||||
var curCam = CameraManager.getCurrentCamera();
|
||||
|
||||
Number newFOV = (Number) camSettings.get("fov");
|
||||
Integer newStreamDivisor = (Integer) camSettings.get("streamDivisor");
|
||||
Integer newResolution = (Integer) camSettings.get("resolution");
|
||||
|
||||
curCam.setFOV(newFOV);
|
||||
|
||||
var currentStreamDivisorOrdinal = curCam.getStreamDivisor().ordinal();
|
||||
if (currentStreamDivisorOrdinal != newStreamDivisor) {
|
||||
curCam.setStreamDivisor(newStreamDivisor, true);
|
||||
}
|
||||
|
||||
var currentResolutionIndex = curCam.getVideoModeIndex();
|
||||
if (currentResolutionIndex != newResolution) {
|
||||
curCam.setCamVideoMode(newResolution, true);
|
||||
}
|
||||
|
||||
CameraManager.saveCameras();
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "changeCameraName": {
|
||||
CameraManager.getCurrentCamera().setNickname((String) entry.getValue());
|
||||
sendFullSettings();
|
||||
@@ -183,7 +151,7 @@ public class ServerHandler {
|
||||
private void setField(Object obj, String fieldName, Object value) {
|
||||
try {
|
||||
if (obj instanceof Camera) {
|
||||
var cam = (Camera)obj;
|
||||
var cam = (Camera) obj;
|
||||
switch (fieldName) {
|
||||
case "driverBrightness":
|
||||
cam.setDriverBrightness((Integer) value);
|
||||
@@ -192,7 +160,7 @@ public class ServerHandler {
|
||||
cam.setDriverExposure((Integer) value);
|
||||
break;
|
||||
case "isDriver":
|
||||
cam.setDriverMode((boolean)value);
|
||||
cam.setDriverMode((boolean) value);
|
||||
break;
|
||||
default:
|
||||
Field field = obj.getClass().getField(fieldName);
|
||||
@@ -207,8 +175,7 @@ public class ServerHandler {
|
||||
Field field = obj.getClass().getField(fieldName);
|
||||
if (field.getType().isEnum()) {
|
||||
field.set(obj, field.getType().getEnumConstants()[(Integer) value]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
field.set(obj, value);
|
||||
}
|
||||
}
|
||||
@@ -296,7 +263,7 @@ public class ServerHandler {
|
||||
fullSettings.put("cameraList", CameraManager.getAllCameraByNickname());
|
||||
fullSettings.put("pipeline", getOrdinalPipeline());
|
||||
var currentCamera = CameraManager.getCurrentCamera();
|
||||
fullSettings.put("driverMode",getOrdinalDriver());
|
||||
fullSettings.put("driverMode", getOrdinalDriver());
|
||||
fullSettings.put("pipelineList", currentCamera.getPipelinesNickname());
|
||||
fullSettings.put("resolutionList", currentCamera.getResolutionList());
|
||||
fullSettings.put("port", currentCamera.getStreamPort());
|
||||
63
chameleon-client/package-lock.json
generated
63
chameleon-client/package-lock.json
generated
@@ -1947,6 +1947,43 @@
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
|
||||
"integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10",
|
||||
"is-buffer": "^2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||
"requires": {
|
||||
"debug": "=3.1.0"
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
|
||||
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
@@ -10957,6 +10994,11 @@
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
|
||||
"integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
|
||||
},
|
||||
"vue-axios": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-2.1.5.tgz",
|
||||
"integrity": "sha512-th5xVbInVoyIoe+qY+9GCflEVezxAvztD4xpFF39SRQYqpoKD2qkmX8yv08jJG9a2SgNOCjirjJGSwg/wTrbmA=="
|
||||
},
|
||||
"vue-cli-plugin-vuetify": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-0.6.3.tgz",
|
||||
@@ -13493,8 +13535,7 @@
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
@@ -13503,8 +13544,7 @@
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -13607,8 +13647,7 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -13618,7 +13657,6 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -13631,20 +13669,17 @@
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -13661,7 +13696,6 @@
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -13734,8 +13768,7 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
"bundled": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -13745,7 +13778,6 @@
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -13851,7 +13883,6 @@
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"core-js": "^2.6.5",
|
||||
"material-design-icons-iconfont": "^5.0.1",
|
||||
"msgpack5": "^4.2.1",
|
||||
"vue": "^2.6.10",
|
||||
"vue-axios": "^2.1.5",
|
||||
"vue-native-websocket": "^2.0.13",
|
||||
"vue-router": "^3.0.3",
|
||||
"vuetify": "^2.0.0",
|
||||
|
||||
@@ -5,11 +5,17 @@ import store from './store'
|
||||
import vuetify from './plugins/vuetify';
|
||||
import VueNativeSock from 'vue-native-websocket';
|
||||
import msgPack from 'msgpack5';
|
||||
import axios from 'axios';
|
||||
import VueAxios from "vue-axios";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
// Vue.use(VueNativeSock,'ws://' + location.host + '/websocket',{format: 'json'});
|
||||
Vue.use(VueNativeSock, 'ws://' + location.hostname + ':5800/websocket');
|
||||
Vue.prototype.$address = location.hostname + ":5800";
|
||||
// Vue.prototype.$address = location.host;
|
||||
|
||||
Vue.use(VueNativeSock, 'ws://' + Vue.prototype.$address + '/websocket');
|
||||
Vue.use(VueAxios, axios);
|
||||
Vue.prototype.$msgPack = msgPack(true);
|
||||
|
||||
Vue.mixin({
|
||||
methods: {
|
||||
handleInput(key, value) {
|
||||
|
||||
@@ -29,7 +29,12 @@
|
||||
},
|
||||
methods: {
|
||||
sendGeneralSettings() {
|
||||
this.handleInput('generalSettings', this.settings);
|
||||
// this.handleInput('generalSettings', this.settings);
|
||||
this.axios.post("http://" + this.$address + "/api/settings/general", this.settings).then(
|
||||
function (response) {
|
||||
console.log(response);
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
Reference in New Issue
Block a user