Save calibration data and show preliminary GUI (#1078)

* Serialize all calibration data

* Run lint

* typing nit

* fix code

* move these tables around some

* Add cool formatting

* add request to get snapshots by resolution and camera

* re-enable all resolutions

* add wip so i can change computers (SQUASH ME AND KILL ME AHHHH)

* Get everything working but viewing snapshots

* Update RequestHandler.java

* Update CameraCalibrationInfoCard.vue

* Update CameraCalibrationInfoCard.vue

* add observation viewer

* round

* fix illiegal import

* Swap to PNG and serialize insolution

* move import/export buttons TO THE TOP

* Update WebsocketDataTypes.ts

* Add snapshotname to observation

* Refactor to serialize snapshot image itself

* Run lint

* Use new base64 image data in info card

* Update SettingTypes.ts

* Create calibration json -> mrcal converter script

* Update calibrationUtils.py

* Fix calibrate NPEs in teest

* Run lint

* Always run cornersubpix

* Update CameraCalibrationInfoCard.vue

Update CameraCalibrationInfoCard.vue

* Update OpenCVHelp.java

* Update OpenCVHelp.java

* Replace test mode camera JSONs

* Run wpiformat

* Revert intrinsics but keep other data

* Remove misc comments

* Rename JsonMat->JsonImageMat and add calobject_warp

* Update Server.java

* Rename cameraExtrinsics to distCoeffs

* fix typing issues

* use util methods

* Formatting fixes

* fix styling

* move to devTools

* remove unneeded or unused imports

* Remove fixed-right css

If its really that big of a deal, we can add it back later, kind of a drag to fix rn.

* Create util method

* Remove extra legacy calibration things

---------

Co-authored-by: Sriman Achanta <68172138+srimanachanta@users.noreply.github.com>
This commit is contained in:
Matt
2024-01-03 14:32:04 -07:00
committed by GitHub
parent e685334baa
commit 7f09f9e4f5
43 changed files with 1247 additions and 396 deletions

View File

@@ -460,7 +460,7 @@ public class RequestHandler {
}
}
public static void onCalibrationImportRequest(Context ctx) {
public static void onCalibDBCalibrationImportRequest(Context ctx) {
var data = ctx.body();
try {
@@ -492,6 +492,38 @@ public class RequestHandler {
}
}
public static void onDataCalibrationImportRequest(Context ctx) {
try {
var data = kObjectMapper.readTree(ctx.body());
int cameraIndex = data.get("cameraIndex").asInt();
var coeffs =
kObjectMapper.convertValue(data.get("calibration"), CameraCalibrationCoefficients.class);
var uploadCalibrationEvent =
new IncomingWebSocketEvent<>(
DataChangeDestination.DCD_ACTIVEMODULE,
"calibrationUploaded",
coeffs,
cameraIndex,
null);
DataChangeService.getInstance().publishEvent(uploadCalibrationEvent);
ctx.status(200);
ctx.result("Calibration imported successfully from imported data!");
logger.info("Calibration imported successfully from imported data!");
} catch (JsonProcessingException e) {
ctx.status(400);
ctx.result("The provided calibration data was malformed");
logger.error("The provided calibration data was malformed", e);
} catch (Exception e) {
ctx.status(500);
ctx.result("An error occurred while uploading calibration data");
logger.error("An error occurred while uploading calibration data", e);
}
}
public static void onProgramRestartRequest(Context ctx) {
// TODO, check if this was successful or not
ctx.status(204);
@@ -567,6 +599,50 @@ public class RequestHandler {
ctx.json(snapshots);
}
public static void onCameraCalibImagesRequest(Context ctx) {
try {
HashMap<String, HashMap<String, ArrayList<HashMap<String, Object>>>> snapshots =
new HashMap<>();
var cameraDirs = ConfigManager.getInstance().getCalibDir().toFile().listFiles();
if (cameraDirs != null) {
var camData = new HashMap<String, ArrayList<HashMap<String, Object>>>();
for (var cameraDir : cameraDirs) {
var resolutionDirs = cameraDir.listFiles();
if (resolutionDirs == null) continue;
for (var resolutionDir : resolutionDirs) {
var calibImages = resolutionDir.listFiles();
if (calibImages == null) continue;
var resolutionImages = new ArrayList<HashMap<String, Object>>();
for (var calibImg : calibImages) {
var snapshotData = new HashMap<String, Object>();
var bufferedImage = ImageIO.read(calibImg);
var buffer = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", buffer);
byte[] data = buffer.toByteArray();
snapshotData.put("snapshotData", data);
snapshotData.put("snapshotFilename", calibImg.getName());
resolutionImages.add(snapshotData);
}
camData.put(resolutionDir.getName(), resolutionImages);
}
var cameraName = cameraDir.getName();
snapshots.put(cameraName, camData);
}
}
ctx.json(snapshots);
} catch (Exception e) {
ctx.status(500);
ctx.result("An error occurred while getting calib data");
logger.error("An error occurred while getting calib data", e);
}
}
/**
* Create a temporary file using the UploadedFile from Javalin.
*

View File

@@ -38,6 +38,10 @@ public class Server {
corsContainer.add(CorsPluginConfig::anyHost);
});
// Increase the upload size limit (arbitrary, but need to be able to deal with large
// calibration JSONs)
javalinConfig.http.maxRequestSize = (long) (50 * 1e6);
javalinConfig.requestLogger.http(
(ctx, ms) -> {
StringJoiner joiner =
@@ -90,6 +94,7 @@ public class Server {
app.post("/api/settings/general", RequestHandler::onGeneralSettingsRequest);
app.post("/api/settings/camera", RequestHandler::onCameraSettingsRequest);
app.post("/api/settings/camera/setNickname", RequestHandler::onCameraNicknameChangeRequest);
app.get("/api/settings/camera/getCalibImages", RequestHandler::onCameraCalibImagesRequest);
// Utilities
app.post("/api/utils/offlineUpdate", RequestHandler::onOfflineUpdateRequest);
@@ -101,7 +106,9 @@ public class Server {
// Calibration
app.post("/api/calibration/end", RequestHandler::onCalibrationEndRequest);
app.post("/api/calibration/importFromCalibDB", RequestHandler::onCalibrationImportRequest);
app.post(
"/api/calibration/importFromCalibDB", RequestHandler::onCalibDBCalibrationImportRequest);
app.post("/api/calibration/importFromData", RequestHandler::onDataCalibrationImportRequest);
app.start(port);
}