mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-20 00:51:41 +00:00
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:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user