mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Update for jart/json.cpp change
This commit is contained in:
@@ -70,9 +70,6 @@ void Analyzer::UpdateFeedforwardGains() {
|
||||
} catch (const AnalysisManager::FileReadingError& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
} catch (const std::exception& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
@@ -298,9 +295,6 @@ void Analyzer::PrepareData() {
|
||||
} catch (const AnalysisManager::FileReadingError& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
} catch (const std::exception& e) {
|
||||
m_state = AnalyzerState::kFileError;
|
||||
HandleError(e.what());
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -27,7 +26,10 @@
|
||||
#include "wpi/gui/wpigui.hpp"
|
||||
#include "wpi/gui/wpigui_openurl.hpp"
|
||||
#include "wpi/math/util/MathUtil.hpp"
|
||||
#include "wpi/util/MemoryBuffer.hpp"
|
||||
#include "wpi/util/fs.hpp"
|
||||
#include "wpi/util/json.hpp"
|
||||
#include "wpi/util/raw_ostream.hpp"
|
||||
|
||||
namespace gui = wpi::gui;
|
||||
|
||||
@@ -175,14 +177,26 @@ void CameraCalibrationSelectorButton(const char* text,
|
||||
if (selector && selector->ready(0)) {
|
||||
auto selectedFiles = selector->result();
|
||||
if (!selectedFiles.empty()) {
|
||||
auto fileBuffer = wpi::util::MemoryBuffer::GetFile(selectedFiles[0]);
|
||||
if (!fileBuffer) {
|
||||
goto err;
|
||||
}
|
||||
auto buffer = fileBuffer.value()->GetCharBuffer();
|
||||
auto j = wpi::util::json::parse({buffer.data(), buffer.size()});
|
||||
if (!j) {
|
||||
goto err;
|
||||
}
|
||||
try {
|
||||
cameraModel = wpi::util::json::parse(std::ifstream(selectedFiles[0]))
|
||||
.get<wpical::CameraModel>();
|
||||
cameraModel = j->get<wpical::CameraModel>();
|
||||
} catch (...) {
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("Camera Calibration Loading Error");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
err:
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("Camera Calibration Loading Error");
|
||||
done:
|
||||
selector.reset();
|
||||
}
|
||||
}
|
||||
@@ -199,15 +213,29 @@ void FieldSelectorButton(const char* text,
|
||||
auto selectedFiles = selector->result();
|
||||
if (!selectedFiles.empty()) {
|
||||
std::string idealLayoutPath = selectedFiles[0];
|
||||
auto fileBuffer = wpi::util::MemoryBuffer::GetFile(idealLayoutPath);
|
||||
if (!fileBuffer) {
|
||||
gInvalidLayoutPath = idealLayoutPath;
|
||||
goto err;
|
||||
}
|
||||
auto buffer = fileBuffer.value()->GetCharBuffer();
|
||||
auto j = wpi::util::json::parse({buffer.data(), buffer.size()});
|
||||
if (!j) {
|
||||
gInvalidLayoutPath = idealLayoutPath;
|
||||
goto err;
|
||||
}
|
||||
try {
|
||||
layout = wpi::util::json::parse(std::ifstream(idealLayoutPath))
|
||||
.get<wpi::apriltag::AprilTagFieldLayout>();
|
||||
layout = j->get<wpi::apriltag::AprilTagFieldLayout>();
|
||||
} catch (...) {
|
||||
gInvalidLayoutPath = idealLayoutPath;
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("AprilTag Field Layout Loading Error");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
err:
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("AprilTag Field Layout Loading Error");
|
||||
done:
|
||||
selector.reset();
|
||||
}
|
||||
if (layout.GetTags().size() > 0) {
|
||||
@@ -226,11 +254,18 @@ void SaveCalibratedField(const wpi::apriltag::AprilTagFieldLayout& field,
|
||||
static std::string saveDir;
|
||||
ProcessDirectorySelector(saveDirSelector, saveDir);
|
||||
if (!saveDir.empty()) {
|
||||
std::ofstream out(saveDir + "/" + outputName + ".json");
|
||||
out << wpi::util::json{field}.dump(4);
|
||||
std::error_code ec;
|
||||
wpi::util::raw_fd_ostream out(saveDir + "/" + outputName + ".json", ec,
|
||||
fs::OF_Text);
|
||||
if (!ec) {
|
||||
wpi::util::json{field}.marshal(out, true, 4);
|
||||
}
|
||||
|
||||
std::ofstream fmap(saveDir + "/" + outputName + ".fmap");
|
||||
fmap << wpi::util::json{fmap::Fieldmap(field)}.dump(4);
|
||||
wpi::util::raw_fd_ostream fmap(saveDir + "/" + outputName + ".fmap", ec,
|
||||
fs::OF_Text);
|
||||
if (!ec) {
|
||||
wpi::util::json{fmap::Fieldmap(field)}.marshal(fmap, true, 4);
|
||||
}
|
||||
|
||||
saveDir.clear();
|
||||
}
|
||||
@@ -286,8 +321,12 @@ void CalibrateCamera() {
|
||||
std::filesystem::path myPath(cameraVideoPath);
|
||||
auto outputPath = myPath.parent_path() / "cameracalibration.json";
|
||||
|
||||
std::ofstream output_file(outputPath);
|
||||
output_file << wpi::util::json(gCameraModel).dump(4) << std::endl;
|
||||
std::error_code ec;
|
||||
wpi::util::raw_fd_ostream output_file(outputPath.string(), ec,
|
||||
fs::OF_Text);
|
||||
if (!ec) {
|
||||
wpi::util::json{gCameraModel}.marshal(output_file, true, 4);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
calibrating = false;
|
||||
} else if (!videoProcessor->IsFinished()) {
|
||||
@@ -350,16 +389,30 @@ void CombineCalibrations() {
|
||||
if (!selectedFiles.empty()) {
|
||||
std::map<std::string, wpi::apriltag::AprilTagFieldLayout> fieldLayouts;
|
||||
for (auto& path : selectedFiles) {
|
||||
auto fileBuffer = wpi::util::MemoryBuffer::GetFile(path);
|
||||
if (!fileBuffer) {
|
||||
gInvalidLayoutPath = path;
|
||||
goto err;
|
||||
}
|
||||
auto buffer = fileBuffer.value()->GetCharBuffer();
|
||||
auto j = wpi::util::json::parse({buffer.data(), buffer.size()});
|
||||
if (!j) {
|
||||
gInvalidLayoutPath = path;
|
||||
goto err;
|
||||
}
|
||||
try {
|
||||
fieldLayouts.emplace(
|
||||
path, wpi::util::json::parse(std::ifstream(path))
|
||||
.get<wpi::apriltag::AprilTagFieldLayout>());
|
||||
fieldLayouts.emplace(path,
|
||||
j->get<wpi::apriltag::AprilTagFieldLayout>());
|
||||
} catch (...) {
|
||||
gInvalidLayoutPath = path;
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("AprilTag Field Layout Loading Error");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
goto good;
|
||||
err:
|
||||
ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Always);
|
||||
ImGui::OpenPopup("AprilTag Field Layout Loading Error");
|
||||
good:
|
||||
calibratedFieldLayouts = fieldLayouts;
|
||||
}
|
||||
calibratedFieldLayoutMultiselector.reset();
|
||||
|
||||
@@ -306,47 +306,71 @@ void to_json(wpi::util::json& json, const CameraModel& cameraModel) {
|
||||
cameraModel.distortionCoefficients.data(),
|
||||
cameraModel.distortionCoefficients.data() +
|
||||
cameraModel.distortionCoefficients.size());
|
||||
json = {{"camera_matrix", cameraMatrix},
|
||||
{"distortion_coefficients", distortionCoefficients},
|
||||
{"avg_reprojection_error", cameraModel.avgReprojectionError}};
|
||||
json = wpi::util::json::object();
|
||||
json["camera_matrix"] = cameraMatrix;
|
||||
json["distortion_coefficients"] = distortionCoefficients;
|
||||
json["avg_reprojection_error"] = cameraModel.avgReprojectionError;
|
||||
}
|
||||
|
||||
void from_json(const wpi::util::json& json, CameraModel& cameraModel) {
|
||||
bool isCalibdb = json.contains("camera");
|
||||
Eigen::Matrix3d cameraMatrix;
|
||||
std::vector<double> distortionCoeffs;
|
||||
auto mat = json.at("camera_matrix");
|
||||
auto distortionCoefficients = json.at("distortion_coefficients");
|
||||
auto jmat = json.at("camera_matrix");
|
||||
auto jdistortionCoefficients = json.at("distortion_coefficients");
|
||||
if (isCalibdb) {
|
||||
// OpenCV format has data key
|
||||
if (mat.contains("data")) {
|
||||
auto data = mat.at("data").get<std::vector<double>>();
|
||||
if (auto jdata = jmat.lookup("data")) {
|
||||
auto& arr = jdata->get_array();
|
||||
std::vector<double> data;
|
||||
data.reserve(arr.size());
|
||||
for (const auto& item : arr) {
|
||||
data.push_back(item.get_number());
|
||||
}
|
||||
cameraMatrix = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>{data.data()};
|
||||
} else {
|
||||
for (int i = 0; i < cameraMatrix.rows(); i++) {
|
||||
auto& jcols = jmat.at(i);
|
||||
for (int j = 0; j < cameraMatrix.cols(); j++) {
|
||||
cameraMatrix(i, j) = mat[i][j];
|
||||
cameraMatrix(i, j) = jcols.at(j).get_number();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OpenCV format has data key
|
||||
if (distortionCoefficients.contains("data")) {
|
||||
distortionCoeffs =
|
||||
distortionCoefficients.at("data").get<std::vector<double>>();
|
||||
wpi::util::json::array_t* arr;
|
||||
if (auto jdata = jdistortionCoefficients.lookup("data")) {
|
||||
arr = &jdata->get_array();
|
||||
} else {
|
||||
distortionCoeffs = distortionCoefficients.get<std::vector<double>>();
|
||||
arr = &jdistortionCoefficients.get_array();
|
||||
}
|
||||
distortionCoeffs.reserve(arr->size());
|
||||
for (const auto& item : *arr) {
|
||||
distortionCoeffs.push_back(item.get_number());
|
||||
}
|
||||
} else {
|
||||
cameraMatrix = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>{
|
||||
mat.get<std::vector<double>>().data()};
|
||||
distortionCoeffs = distortionCoefficients.get<std::vector<double>>();
|
||||
{
|
||||
auto& arr = jmat.get_array();
|
||||
std::vector<double> data;
|
||||
data.reserve(arr.size());
|
||||
for (const auto& item : arr) {
|
||||
data.push_back(item.get_number());
|
||||
}
|
||||
cameraMatrix = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>{data.data()};
|
||||
}
|
||||
{
|
||||
auto& arr = jdistortionCoefficients.get_array();
|
||||
distortionCoeffs.reserve(arr.size());
|
||||
for (const auto& item : arr) {
|
||||
distortionCoeffs.push_back(item.get_number());
|
||||
}
|
||||
}
|
||||
}
|
||||
// CalibDB generates JSONs with 5 values. Just zero out the remaining 3 to get
|
||||
// it to 8
|
||||
distortionCoeffs.resize(8, 0);
|
||||
cameraModel = {cameraMatrix,
|
||||
Eigen::Matrix<double, 8, 1>{distortionCoeffs.data()},
|
||||
json.at("avg_reprojection_error")};
|
||||
json.at("avg_reprojection_error").get_number()};
|
||||
}
|
||||
} // namespace wpical
|
||||
|
||||
@@ -29,25 +29,39 @@ Fieldmap::Fieldmap(const wpi::apriltag::AprilTagFieldLayout& layout)
|
||||
}
|
||||
|
||||
void fmap::to_json(wpi::util::json& json, const Fiducial& layout) {
|
||||
json = {{"family", layout.family},
|
||||
{"id", layout.id},
|
||||
{"size", layout.size},
|
||||
{"transform", std::vector<double>{layout.transform.data(),
|
||||
layout.transform.data() +
|
||||
layout.transform.size()}},
|
||||
{"unique", layout.unique}};
|
||||
json = wpi::util::json::object();
|
||||
json["family"] = layout.family;
|
||||
json["id"] = layout.id;
|
||||
json["size"] = layout.size;
|
||||
json["transform"] =
|
||||
std::vector<double>{layout.transform.data(),
|
||||
layout.transform.data() + layout.transform.size()};
|
||||
json["unique"] = layout.unique;
|
||||
}
|
||||
|
||||
void fmap::from_json(const wpi::util::json& json, Fiducial& layout) {
|
||||
auto vec = json.at("transform").get<std::vector<double>>();
|
||||
layout = {json.at("family"), json.at("id"), json.at("size"),
|
||||
Eigen::Matrix4d{vec.data()}, json.at("unique")};
|
||||
auto& arr = json.at("transform").get_array();
|
||||
std::vector<double> vec;
|
||||
vec.reserve(arr.size());
|
||||
for (auto& elem : arr) {
|
||||
vec.push_back(elem.get_number());
|
||||
}
|
||||
layout = {json.at("family").get_string(),
|
||||
static_cast<int>(json.at("id").get_int()),
|
||||
json.at("size").get_number(), Eigen::Matrix4d{vec.data()},
|
||||
static_cast<int>(json.at("unique").get_int())};
|
||||
}
|
||||
|
||||
void fmap::to_json(wpi::util::json& json, const Fieldmap& layout) {
|
||||
json = {{"type", "frc"}, {"fiducials", layout.fiducials}};
|
||||
json = wpi::util::json::object("type", "frc", "fiducials", layout.fiducials);
|
||||
}
|
||||
|
||||
void fmap::from_json(const wpi::util::json& json, Fieldmap& layout) {
|
||||
layout = {json.at("type"), json.at("fiducials")};
|
||||
auto& arr = json.at("fiducials").get_array();
|
||||
std::vector<Fiducial> fiducials;
|
||||
fiducials.reserve(arr.size());
|
||||
for (auto& elem : arr) {
|
||||
fiducials.emplace_back(elem.get<Fiducial>());
|
||||
}
|
||||
layout = {json.at("type").get_string(), fiducials};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -13,7 +12,10 @@
|
||||
#include "path_lookup.hpp"
|
||||
#include "wpi/apriltag/AprilTagFieldLayout.hpp"
|
||||
#include "wpi/apriltag/AprilTagFields.hpp"
|
||||
#include "wpi/util/MemoryBuffer.hpp"
|
||||
#include "wpi/util/fs.hpp"
|
||||
#include "wpi/util/json.hpp"
|
||||
#include "wpi/util/raw_ostream.hpp"
|
||||
|
||||
const std::string projectRootPath = PROJECT_ROOT_PATH;
|
||||
|
||||
@@ -42,8 +44,10 @@ TEST(CameraCalibrationTest, Typical) {
|
||||
}
|
||||
auto ret = calibrator.GetCameraModel();
|
||||
EXPECT_NE(ret, std::nullopt);
|
||||
std::ofstream output_file(calSavePath + "/cameracalibration.json");
|
||||
output_file << wpi::util::json(ret.value()).dump(4) << std::endl;
|
||||
std::error_code ec;
|
||||
wpi::util::raw_fd_ostream output_file(calSavePath + "/cameracalibration.json",
|
||||
ec, fs::OF_Text);
|
||||
wpi::util::json(ret.value()).marshal(output_file, true, 4);
|
||||
}
|
||||
|
||||
TEST(CameraCalibrationTest, Atypical) {
|
||||
@@ -58,8 +62,10 @@ TEST(CameraCalibrationTest, Atypical) {
|
||||
}
|
||||
|
||||
TEST(FieldCalibrationTest, Typical) {
|
||||
auto model = wpi::util::json::parse(
|
||||
std::ifstream(calSavePath + "/cameracalibration.json"))
|
||||
auto buffer =
|
||||
wpi::util::MemoryBuffer::GetFile(calSavePath + "/cameracalibration.json");
|
||||
auto buf = buffer.value()->GetCharBuffer();
|
||||
auto model = wpi::util::json::parse_or_throw({buf.data(), buf.size()})
|
||||
.get<wpical::CameraModel>();
|
||||
auto ret =
|
||||
wpical::calibrate(LookupPath(projectRootPath + videoLocation), model,
|
||||
@@ -80,8 +86,10 @@ TEST(FieldCalibrationTest, Atypical_Bad_Camera_Model) {
|
||||
}
|
||||
|
||||
TEST(FieldCalibrationTest, Atypical_Bad_Field_Layout) {
|
||||
auto model = wpi::util::json::parse(
|
||||
std::ifstream(calSavePath + "/cameracalibration.json"))
|
||||
auto buffer =
|
||||
wpi::util::MemoryBuffer::GetFile(calSavePath + "/cameracalibration.json");
|
||||
auto buf = buffer.value()->GetCharBuffer();
|
||||
auto model = wpi::util::json::parse_or_throw({buf.data(), buf.size()})
|
||||
.get<wpical::CameraModel>();
|
||||
auto ret =
|
||||
wpical::calibrate(LookupPath(projectRootPath + videoLocation), model,
|
||||
@@ -90,8 +98,10 @@ TEST(FieldCalibrationTest, Atypical_Bad_Field_Layout) {
|
||||
}
|
||||
|
||||
TEST(FieldCalibrationTest, Atypical_Bad_Input_Directory) {
|
||||
auto model = wpi::util::json::parse(
|
||||
std::ifstream(calSavePath + "/cameracalibration.json"))
|
||||
auto buffer =
|
||||
wpi::util::MemoryBuffer::GetFile(calSavePath + "/cameracalibration.json");
|
||||
auto buf = buffer.value()->GetCharBuffer();
|
||||
auto model = wpi::util::json::parse_or_throw({buf.data(), buf.size()})
|
||||
.get<wpical::CameraModel>();
|
||||
auto ret =
|
||||
wpical::calibrate(LookupPath(projectRootPath), model,
|
||||
@@ -102,8 +112,10 @@ TEST(FieldCalibrationTest, Atypical_Bad_Input_Directory) {
|
||||
}
|
||||
|
||||
TEST(FieldCalibrationTest, Atypical_Bad_Pinned_Tag) {
|
||||
auto model = wpi::util::json::parse(
|
||||
std::ifstream(calSavePath + "/cameracalibration.json"))
|
||||
auto buffer =
|
||||
wpi::util::MemoryBuffer::GetFile(calSavePath + "/cameracalibration.json");
|
||||
auto buf = buffer.value()->GetCharBuffer();
|
||||
auto model = wpi::util::json::parse_or_throw({buf.data(), buf.size()})
|
||||
.get<wpical::CameraModel>();
|
||||
auto ret =
|
||||
wpical::calibrate(LookupPath(projectRootPath + videoLocation), model,
|
||||
@@ -114,8 +126,10 @@ TEST(FieldCalibrationTest, Atypical_Bad_Pinned_Tag) {
|
||||
}
|
||||
|
||||
TEST(FieldCalibrationTest, Atypical_Bad_Pinned_Tag_Negative) {
|
||||
auto model = wpi::util::json::parse(
|
||||
std::ifstream(calSavePath + "/cameracalibration.json"))
|
||||
auto buffer =
|
||||
wpi::util::MemoryBuffer::GetFile(calSavePath + "/cameracalibration.json");
|
||||
auto buf = buffer.value()->GetCharBuffer();
|
||||
auto model = wpi::util::json::parse_or_throw({buf.data(), buf.size()})
|
||||
.get<wpical::CameraModel>();
|
||||
auto ret =
|
||||
wpical::calibrate(LookupPath(projectRootPath + videoLocation), model,
|
||||
|
||||
Reference in New Issue
Block a user