Update log viewer, add uncalibrated modal (#108)

Adds a prettier log viewer, with the ability to filter logs. Also warns user and prevents switching into 3d mode if the resolution is uncalibrated.
This commit is contained in:
Matt
2020-09-04 18:18:44 -07:00
committed by GitHub
parent ec9e3dcf79
commit 8a7318f5dd
25 changed files with 1047 additions and 433 deletions

View File

@@ -57,17 +57,17 @@ public class ConfigManager {
}
public static void saveUploadedSettingsZip(File uploadPath) {
logger.info(uploadPath.getAbsolutePath());
var folderPath = Path.of(System.getProperty("java.io.tmpdir"), "photonvision").toFile();
folderPath.mkdirs();
ZipUtil.unpack(uploadPath, folderPath);
FileUtils.deleteDirectory(getRootFolder());
try {
org.apache.commons.io.FileUtils.copyDirectory(folderPath, getRootFolder().toFile());
logger.info("Copied settings successfully!");
} catch (IOException e) {
e.printStackTrace();
logger.error("Exception copying uploaded settings!", e);
return;
}
System.exit(666);
}
public PhotonConfiguration getConfig() {
@@ -159,8 +159,6 @@ public class ConfigManager {
}
public void saveToDisk() {
logger.info("Saving settings...");
// Delete old configs
FileUtils.deleteDirectory(camerasFolder.toPath());
@@ -214,6 +212,7 @@ public class ConfigManager {
}
}
}
logger.info("Settings saved!");
}
private HashMap<String, CameraConfiguration> loadCameraConfigs() {
@@ -341,7 +340,7 @@ public class ConfigManager {
}
public void requestSave() {
logger.debug("Requesting save...");
logger.trace("Requesting save...");
saveRequestTimestamp = System.currentTimeMillis();
}

View File

@@ -18,12 +18,11 @@
package org.photonvision.common.logging;
public enum LogLevel {
OFF(0, Logger.ANSI_BLACK),
ERROR(1, Logger.ANSI_RED),
WARN(2, Logger.ANSI_YELLOW),
INFO(3, Logger.ANSI_GREEN),
DEBUG(4, Logger.ANSI_WHITE),
TRACE(5, Logger.ANSI_CYAN);
ERROR(0, Logger.ANSI_RED),
WARN(1, Logger.ANSI_YELLOW),
INFO(2, Logger.ANSI_GREEN),
DEBUG(3, Logger.ANSI_WHITE),
TRACE(4, Logger.ANSI_CYAN);
public final String colorCode;
public final int code;

View File

@@ -25,6 +25,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair;
import org.photonvision.common.configuration.ConfigManager;
import org.photonvision.common.dataflow.DataChangeService;
import org.photonvision.common.dataflow.events.OutgoingUIEvent;
@@ -47,6 +48,11 @@ public class Logger {
private static final SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final List<Pair<String, LogLevel>> uiBacklog = new ArrayList<>();
private static boolean connected = false;
private static UILogAppender uiLogAppender = new UILogAppender();
private final String className;
private final LogGroup group;
@@ -97,7 +103,7 @@ public class Logger {
static {
currentAppenders.add(new ConsoleLogAppender());
currentAppenders.add(new UILogAppender());
currentAppenders.add(uiLogAppender);
addFileAppender(ConfigManager.getInstance().getLogPath());
}
@@ -126,6 +132,15 @@ public class Logger {
var formattedMessage = format(message, level, group, clazz, shouldColor);
a.log(formattedMessage, level);
}
if (!connected) uiBacklog.add(Pair.of(format(message, level, group, clazz, false), level));
}
public static void sendConnectedBacklog() {
for (var message : uiBacklog) {
uiLogAppender.log(message.getLeft(), message.getRight());
}
connected = true;
uiBacklog.clear();
}
public boolean shouldLog(LogLevel logLevel) {
@@ -244,6 +259,7 @@ public class Logger {
private static class FileLogAppender implements LogAppender {
private OutputStream out;
private boolean wantsFlush;
public FileLogAppender(Path logFilePath) {
try {
@@ -253,7 +269,10 @@ public class Logger {
"FileLogAppender",
() -> {
try {
out.flush();
if (wantsFlush) {
out.flush();
wantsFlush = false;
}
} catch (IOException ignored) {
}
},
@@ -269,6 +288,7 @@ public class Logger {
message += "\n";
try {
out.write(message.getBytes());
wantsFlush = true;
} catch (IOException e) {
e.printStackTrace();
}

View File

@@ -32,6 +32,7 @@ import org.photonvision.common.configuration.ConfigManager;
import org.photonvision.common.configuration.NetworkConfig;
import org.photonvision.common.dataflow.networktables.NetworkTablesManager;
import org.photonvision.common.hardware.HardwareManager;
import org.photonvision.common.hardware.Platform;
import org.photonvision.common.logging.LogGroup;
import org.photonvision.common.logging.Logger;
import org.photonvision.common.networking.NetworkManager;
@@ -56,9 +57,17 @@ public class RequestHandler {
e.printStackTrace();
}
ConfigManager.saveUploadedSettingsZip(tempZipPath);
// restartDevice();
ctx.status(200);
logger.info("Settings uploaded, going down for restart.");
if (!Platform.isRaspberryPi()) {
logger.info("(On non-PI platforms, the program may not restart manually...)");
}
System.exit(0);
} else {
logger.error("Couldn't read uploaded settings ZIP! Ignoring.");
ctx.status(500);
}
}

View File

@@ -53,7 +53,7 @@ public class Server {
ws ->
ws.onBinaryMessage(
ctx ->
logger.debug(
logger.trace(
() -> {
var insa = ctx.session.getRemote().getInetSocketAddress();
var host = insa.getAddress().toString() + ":" + insa.getPort();

View File

@@ -105,14 +105,15 @@ public class SocketHandler {
var entryValue = entry.getValue();
var socketMessageType = SocketMessageType.fromEntryKey(entryKey);
logger.debug(
"Got WS message: ["
+ socketMessageType
+ "] ==> ["
+ entryKey
+ "], ["
+ entryValue
+ "]");
logger.trace(
() ->
"Got WS message: ["
+ socketMessageType
+ "] ==> ["
+ entryKey
+ "], ["
+ entryValue
+ "]");
if (socketMessageType == null) {
logger.warn("Got unknown socket message type: " + entryKey);

View File

@@ -26,6 +26,7 @@ import org.photonvision.common.dataflow.DataChangeSubscriber;
import org.photonvision.common.dataflow.events.DataChangeEvent;
import org.photonvision.common.dataflow.events.IncomingWebSocketEvent;
import org.photonvision.common.dataflow.events.OutgoingUIEvent;
import org.photonvision.common.logging.Logger;
public class UIInboundSubscriber extends DataChangeSubscriber {
@@ -46,6 +47,7 @@ public class UIInboundSubscriber extends DataChangeSubscriber {
var message =
new OutgoingUIEvent<>("fullsettings", settings, incomingWSEvent.originContext);
DataChangeService.getInstance().publishEvent(message);
Logger.sendConnectedBacklog();
}
}
}

View File

@@ -41,8 +41,21 @@ public class SolvePNPPipe
private final MatOfPoint2f imagePoints = new MatOfPoint2f();
private boolean hasWarned = false;
@Override
protected List<TrackedTarget> process(List<TrackedTarget> targetList) {
if (params.cameraCoefficients == null
|| params.cameraCoefficients.getCameraIntrinsicsMat() == null
|| params.cameraCoefficients.getCameraExtrinsicsMat() == null) {
if (!hasWarned) {
logger.warn(
"Cannot perform solvePNP an uncalibrated camera! Please calibrate this resolution...");
hasWarned = true;
}
return targetList;
}
for (var target : targetList) {
calculateTargetPose(target);
}
@@ -55,6 +68,7 @@ public class SolvePNPPipe
var corners = target.getTargetCorners();
if (corners == null
|| corners.isEmpty()
|| params.cameraCoefficients == null
|| params.cameraCoefficients.getCameraIntrinsicsMat() == null
|| params.cameraCoefficients.getCameraExtrinsicsMat() == null) {
return;

View File

@@ -40,6 +40,7 @@ public class VisionSourceManager {
final List<UsbCameraInfo> knownUsbCameras = new CopyOnWriteArrayList<>();
final List<CameraConfiguration> unmatchedLoadedConfigs = new CopyOnWriteArrayList<>();
private boolean hasWarned;
private static class SingletonHolder {
private static final VisionSourceManager INSTANCE = new VisionSourceManager();
@@ -132,12 +133,14 @@ public class VisionSourceManager {
// Match camera configs to physical cameras
var matchedCameras = matchUSBCameras(notYetLoadedCams, unmatchedLoadedConfigs);
unmatchedLoadedConfigs.removeAll(matchedCameras);
if (!unmatchedLoadedConfigs.isEmpty())
if (!unmatchedLoadedConfigs.isEmpty() && !hasWarned) {
logger.warn(
() ->
"After matching, "
+ unmatchedLoadedConfigs.size()
+ " configs remained unmatched. Is your camera disconnected?");
hasWarned = true;
}
// We add the matched cameras to the known camera list
for (var cam : notYetLoadedCams) {