Skip to content

Commit

Permalink
Refactor program configuration broadcast hashmap spaghetti (PhotonVis…
Browse files Browse the repository at this point in the history
…ion#1592)

WAS: we used raw hash-maps to encode program state
S/B: we use Jackson to do this encoding for us for free. We have
Objects, and we should use them to represent structured data.

---------

Co-authored-by: Craig Schardt <crschardt@fastem.com>
  • Loading branch information
mcm001 and crschardt authored Nov 19, 2024
1 parent 7d1e748 commit adb18fe
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ public NetworkConfig(
setShouldManage(shouldManage);
}

public NetworkConfig(NetworkConfig config) {
this(
config.ntServerAddress,
config.connectionType,
config.staticIp,
config.hostname,
config.runNTServer,
config.shouldManage,
config.shouldPublishProto,
config.networkManagerIface,
config.setStaticCommand,
config.setDHCPcommand,
config.matchCamerasOnlyByPath);
}

public Map<String, Object> toHashMap() {
try {
var ret = new ObjectMapper().convertValue(this, JacksonUtils.UIMap.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,6 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.photonvision.PhotonVersion;
import org.photonvision.common.hardware.Platform;
import org.photonvision.common.networking.NetworkManager;
import org.photonvision.common.networking.NetworkUtils;
import org.photonvision.common.util.SerializationUtils;
import org.photonvision.mrcal.MrCalJNILoader;
import org.photonvision.raspi.LibCameraJNILoader;
import org.photonvision.vision.calibration.UICameraCalibrationCoefficients;
import org.photonvision.vision.camera.QuirkyCamera;
import org.photonvision.vision.processes.VisionModule;
import org.photonvision.vision.processes.VisionModuleManager;
import org.photonvision.vision.processes.VisionSource;

public class PhotonConfiguration {
Expand Down Expand Up @@ -124,81 +111,6 @@ public boolean removeCameraConfig(String name) {
return cameraConfigurations.remove(name) != null;
}

public Map<String, Object> toHashMap() {
Map<String, Object> map = new HashMap<>();
var settingsSubmap = new HashMap<String, Object>();

// Hack active interfaces into networkSettings
var netConfigMap = networkConfig.toHashMap();
netConfigMap.put("networkInterfaceNames", NetworkUtils.getAllActiveWiredInterfaces());
netConfigMap.put("networkingDisabled", NetworkManager.getInstance().networkingIsDisabled);

settingsSubmap.put("networkSettings", netConfigMap);

var lightingConfig = new UILightingConfig();
lightingConfig.brightness = hardwareSettings.ledBrightnessPercentage;
lightingConfig.supported = !hardwareConfig.ledPins.isEmpty();
settingsSubmap.put("lighting", SerializationUtils.objectToHashMap(lightingConfig));
// General Settings
var generalSubmap = new HashMap<String, Object>();
generalSubmap.put("version", PhotonVersion.versionString);
generalSubmap.put(
"gpuAcceleration",
LibCameraJNILoader.isSupported()
? "Zerocopy Libcamera Working"
: ""); // TODO add support for other types of GPU accel
generalSubmap.put("mrCalWorking", MrCalJNILoader.getInstance().isLoaded());
generalSubmap.put("availableModels", NeuralNetworkModelManager.getInstance().getModels());
generalSubmap.put(
"supportedBackends", NeuralNetworkModelManager.getInstance().getSupportedBackends());
generalSubmap.put(
"hardwareModel",
hardwareConfig.deviceName.isEmpty()
? Platform.getHardwareModel()
: hardwareConfig.deviceName);
generalSubmap.put("hardwarePlatform", Platform.getPlatformName());
settingsSubmap.put("general", generalSubmap);
// AprilTagFieldLayout
settingsSubmap.put("atfl", this.atfl);

map.put(
"cameraSettings",
VisionModuleManager.getInstance().getModules().stream()
.map(VisionModule::toUICameraConfig)
.map(SerializationUtils::objectToHashMap)
.collect(Collectors.toList()));
map.put("settings", settingsSubmap);

return map;
}

public static class UILightingConfig {
public int brightness = 0;
public boolean supported = true;
}

public static class UICameraConfiguration {
@SuppressWarnings("unused")
public double fov;

public String nickname;
public String uniqueName;
public HashMap<String, Object> currentPipelineSettings;
public int currentPipelineIndex;
public List<String> pipelineNicknames;
public HashMap<Integer, HashMap<String, Object>> videoFormatList;
public int outputStreamPort;
public int inputStreamPort;
public List<UICameraCalibrationCoefficients> calibrations;
public boolean isFovConfigurable = true;
public QuirkyCamera cameraQuirks;
public boolean isCSICamera;
public double minExposureRaw;
public double maxExposureRaw;
public double minWhiteBalanceTemp;
public double maxWhiteBalanceTemp;
}

@Override
public String toString() {
return "PhotonConfiguration [\n hardwareConfig="
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.photonvision.common.configuration.NetworkConfig;
import org.photonvision.common.dataflow.DataChangeService;
import org.photonvision.common.dataflow.events.OutgoingUIEvent;
import org.photonvision.common.dataflow.websocket.UIPhotonConfiguration;
import org.photonvision.common.hardware.HardwareManager;
import org.photonvision.common.logging.LogGroup;
import org.photonvision.common.logging.LogLevel;
Expand Down Expand Up @@ -165,7 +166,8 @@ private void onFieldLayoutChanged(NetworkTableEvent event) {
DataChangeService.getInstance()
.publishEvent(
new OutgoingUIEvent<>(
"fullsettings", ConfigManager.getInstance().getConfig().toHashMap()));
"fullsettings",
UIPhotonConfiguration.programStateToUi(ConfigManager.getInstance().getConfig())));
} catch (IOException e) {
logger.error("Error deserializing atfl!");
logger.error(atfl_json);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.dataflow.websocket;

import java.util.HashMap;
import java.util.List;
import org.photonvision.vision.calibration.UICameraCalibrationCoefficients;
import org.photonvision.vision.camera.QuirkyCamera;

public class UICameraConfiguration {
@SuppressWarnings("unused")
public double fov;

public String nickname;
public String uniqueName;
public HashMap<String, Object> currentPipelineSettings;
public int currentPipelineIndex;
public List<String> pipelineNicknames;
public HashMap<Integer, HashMap<String, Object>> videoFormatList;
public int outputStreamPort;
public int inputStreamPort;
public List<UICameraCalibrationCoefficients> calibrations;
public boolean isFovConfigurable = true;
public QuirkyCamera cameraQuirks;
public boolean isCSICamera;
public double minExposureRaw;
public double maxExposureRaw;
public double minWhiteBalanceTemp;
public double maxWhiteBalanceTemp;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.dataflow.websocket;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class UIGeneralSettings {
public UIGeneralSettings(
String version,
String gpuAcceleration,
boolean mrCalWorking,
Map<String, ArrayList<String>> availableModels,
List<String> supportedBackends,
String hardwareModel,
String hardwarePlatform) {
this.version = version;
this.gpuAcceleration = gpuAcceleration;
this.mrCalWorking = mrCalWorking;
this.availableModels = availableModels;
this.supportedBackends = supportedBackends;
this.hardwareModel = hardwareModel;
this.hardwarePlatform = hardwarePlatform;
}

public String version;
public String gpuAcceleration;
public boolean mrCalWorking;
public Map<String, ArrayList<String>> availableModels;
public List<String> supportedBackends;
public String hardwareModel;
public String hardwarePlatform;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.dataflow.websocket;

public class UILightingConfig {
public UILightingConfig(int brightness, boolean supported) {
this.brightness = brightness;
this.supported = supported;
}

public int brightness = 0;
public boolean supported = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.dataflow.websocket;

import java.util.List;
import org.photonvision.common.configuration.NetworkConfig;
import org.photonvision.common.networking.NetworkUtils.NMDeviceInfo;

public class UINetConfig extends NetworkConfig {
public UINetConfig(
NetworkConfig config, List<NMDeviceInfo> networkInterfaceNames, boolean networkingDisabled) {
super(config);
this.networkInterfaceNames = networkInterfaceNames;
this.networkingDisabled = networkingDisabled;
}

public List<NMDeviceInfo> networkInterfaceNames;
public boolean networkingDisabled;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.dataflow.websocket;

import java.util.List;
import java.util.stream.Collectors;
import org.photonvision.PhotonVersion;
import org.photonvision.common.configuration.NeuralNetworkModelManager;
import org.photonvision.common.configuration.PhotonConfiguration;
import org.photonvision.common.hardware.Platform;
import org.photonvision.common.networking.NetworkManager;
import org.photonvision.common.networking.NetworkUtils;
import org.photonvision.mrcal.MrCalJNILoader;
import org.photonvision.raspi.LibCameraJNILoader;
import org.photonvision.vision.processes.VisionModule;
import org.photonvision.vision.processes.VisionModuleManager;

public class UIPhotonConfiguration {
public List<UICameraConfiguration> cameraSettings;
public UIProgramSettings settings;

public UIPhotonConfiguration(
UIProgramSettings settings, List<UICameraConfiguration> cameraSettings) {
this.cameraSettings = cameraSettings;
this.settings = settings;
}

public static UIPhotonConfiguration programStateToUi(PhotonConfiguration c) {
return new UIPhotonConfiguration(
new UIProgramSettings(
new UINetConfig(
c.getNetworkConfig(),
NetworkUtils.getAllActiveWiredInterfaces(),
NetworkManager.getInstance().networkingIsDisabled),
new UILightingConfig(
c.getHardwareSettings().ledBrightnessPercentage,
!c.getHardwareConfig().ledPins.isEmpty()),
new UIGeneralSettings(
PhotonVersion.versionString,
// TODO add support for other types of GPU accel
LibCameraJNILoader.isSupported() ? "Zerocopy Libcamera Working" : "",
MrCalJNILoader.getInstance().isLoaded(),
NeuralNetworkModelManager.getInstance().getModels(),
NeuralNetworkModelManager.getInstance().getSupportedBackends(),
c.getHardwareConfig().deviceName.isEmpty()
? Platform.getHardwareModel()
: c.getHardwareConfig().deviceName,
Platform.getPlatformName()),
c.getApriltagFieldLayout()),
VisionModuleManager.getInstance().getModules().stream()
.map(VisionModule::toUICameraConfig)
.collect(Collectors.toList()));
}
}
Loading

0 comments on commit adb18fe

Please sign in to comment.