3#include <wpi/raw_ostream.h>
4#include <wpi/MemoryBuffer.h>
5#include <wpi/StringExtras.h>
6#include <networktables/NetworkTableInstance.h>
8#include "cpp-tools/src/resources.h"
13 std::unique_ptr<wpi::MemoryBuffer> file_buffer = wpi::MemoryBuffer::GetFile(file, ec);
14 if (file_buffer ==
nullptr || ec) {
15 wpi::errs() <<
"Could not open '" << file <<
"': " << ec.message() << newline;
18 try { j = wpi::json::parse(file_buffer->begin(), file_buffer->end()); }
19 catch (
const wpi::json::parse_error& e) {
20 wpi::errs() <<
"Config error in " << file <<
": " << e.what() << newline;
24 wpi::errs() <<
"Config error in " << file <<
": must be JSON object\n";
33 if(!
loadJson(j, file)) {
return false; }
35 if(j.count(
"ntmode") != 0) {
37 std::string str = j.at(
"ntmode").get<std::string>();
38 if(wpi::equals_lower(str,
"client")) {
39 wpi::outs() <<
"Setting up NetworkTables in CLIENT mode\n";
41#if NT_CLIENT_VERSION == 4
42 nt::NetworkTableInstance::GetDefault().StartClient4(
"VisionServer");
44 nt::NetworkTableInstance::GetDefault().StartClient3(
"VisionServer");
46 nt::NetworkTableInstance::GetDefault().SetServerTeam(j.at(
"team").get<
unsigned int>());
47 nt::NetworkTableInstance::GetDefault().StartDSClient();
49 catch (
const wpi::json::exception& e) {
50 wpi::errs() <<
"Config error in " << file <<
": could not read team number: " << e.what() << newline;
53 }
else if (wpi::equals_lower(str,
"server")) {
54 wpi::outs() <<
"Setting up NetworkTables in SERVER mode\n";
55 nt::NetworkTableInstance::GetDefault().StartServer();
57 wpi::outs() <<
"Setting up NetworkTables for SIMULATION mode - host: " << str << newline;
58#if NT_CLIENT_VERSION == 4
59 nt::NetworkTableInstance::GetDefault().StartClient4(
"VisionServer");
61 nt::NetworkTableInstance::GetDefault().StartClient3(
"VisionServer");
63 nt::NetworkTableInstance::GetDefault().SetServer(str.c_str());
65 }
catch (
const wpi::json::exception& e) {
66 wpi::errs() <<
"Config error in " << file <<
": coud not read ntmode: " << e.what() << newline;
75 wpi::outs() <<
"Setting up NetworkTables for SIMULATION mode - host: " << sim_ip << newline;
76#if NT_CLIENT_VERSION == 4
77 nt::NetworkTableInstance::GetDefault().StartClient4(
"VisionServer");
79 nt::NetworkTableInstance::GetDefault().StartClient3(
"VisionServer");
81 nt::NetworkTableInstance::GetDefault().SetServer(sim_ip);
86bool createCameras(std::vector<VisionCamera>& cameras,
const char* file) {
89 if(!
loadJson(j, file)) {
return false; }
91 if(j.count(
"cameras") < 1) {
92 wpi::errs() <<
"Config error in " << file <<
": no camera configs found, this program requires cameras to function\n";
95 for(
const wpi::json& camera : j.at(
"cameras")) {
96 if(camera.count(
"calibration") > 0 && j.count(
"calibrations") > 0) {
97 wpi::json calibration;
99 calibration = j.at(
"calibrations").at(camera.at(
"calibration").get<std::string>());
100 cameras.emplace_back(camera, calibration);
102 }
catch (
const wpi::json::exception& e) {
103 wpi::errs() <<
"Config error in " << file <<
": failed to get configuration object: " << e.what() << newline;
104 cameras.emplace_back(camera);
107 cameras.emplace_back(camera);
109#ifdef REMOVE_DISCONNECTED_CAMERAS
110 if(!cameras.back().IsConnected()) { cameras.pop_back(); }
114 catch (
const wpi::json::exception& e) {
115 wpi::errs() <<
"Config error in " << file <<
": could not read cameras: " << e.what() << newline;
125 if(!
loadJson(j, file)) {
return false; }
127 if(j.count(
"cameras") < 1) {
128 wpi::errs() <<
"Config error in " << file <<
": no camera configs found, this program requires cameras to function\n";
131 bool has_calibs = j.count(
"calibrations") > 0;
132 for(
const wpi::json& camera : j.at(
"cameras")) {
133 cameras.emplace_back(camera);
134 if(camera.count(
"properties") && camera.at(
"properties").count(
"type")) {
136 std::string type = camera.at(
"properties").at(
"type").get<std::string>();
139 cv::Size2i sz = cameras.back().getResolution();
140 if(
auto* cal =
findCalib(type, sz, calibrations)) {
141 cameras.back().setCameraMatrix(cal->at(0));
142 cameras.back().setDistortionCoefs(cal->at(1));
155 }
catch (
const wpi::json::exception& e) {
156 wpi::errs() <<
"Config error in " << file <<
": failed to get 'type' property: " << e.what() << newline;
158 }
else if(has_calibs && camera.count(
"calibration") > 0) {
160 wpi::json calibration = j.at(
"calibrations").at(camera.at(
"calibration").get<std::string>());
161 cameras.back().setCalibrationJson(calibration);
162 }
catch (
const wpi::json::exception& e) {
163 wpi::errs() <<
"Config error in " << file <<
": failed to get configuration object: " << e.what() << newline;
166#ifdef REMOVE_DISCONNECTED_CAMERAS
167 if(!cameras.back().IsConnected()) { cameras.pop_back(); }
171 catch (
const wpi::json::exception& e) {
172 wpi::errs() <<
"Config error in " << file <<
": could not read cameras: " << e.what() << newline;
182bool readConfig(std::vector<VisionCamera>& cameras,
const char* file) {
185 if(!
loadJson(j, file)) {
return false; }
187 if(j.count(
"ntmode") != 0) {
189 std::string str = j.at(
"ntmode").get<std::string>();
190 if(wpi::equals_lower(str,
"client")) {
191 wpi::outs() <<
"Setting up NetworkTables in CLIENT mode\n";
193#if NT_CLIENT_VERSION == 4
194 nt::NetworkTableInstance::GetDefault().StartClient4(
"VisionServer");
196 nt::NetworkTableInstance::GetDefault().StartClient3(
"VisionServer");
198 nt::NetworkTableInstance::GetDefault().SetServerTeam(j.at(
"team").get<
unsigned int>());
199 nt::NetworkTableInstance::GetDefault().StartDSClient();
201 catch (
const wpi::json::exception& e) {
202 wpi::errs() <<
"Config error in " << file <<
": could not read team number: " << e.what() << newline;
205 }
else if (wpi::equals_lower(str,
"server")) {
206 wpi::outs() <<
"Setting up NetworkTables in SERVER mode\n";
207 nt::NetworkTableInstance::GetDefault().StartServer();
209 wpi::outs() <<
"Setting up NetworkTables for SIMULATION mode - host: " << str << newline;
210#if NT_CLIENT_VERSION == 4
211 nt::NetworkTableInstance::GetDefault().StartClient4(
"VisionServer");
213 nt::NetworkTableInstance::GetDefault().StartClient3(
"VisionServer");
215 nt::NetworkTableInstance::GetDefault().SetServer(str.c_str());
217 }
catch (
const wpi::json::exception& e) {
218 wpi::errs() <<
"Config error in " << file <<
": coud not read ntmode: " << e.what() << newline;
222 if(j.count(
"cameras") < 1) {
223 wpi::errs() <<
"Config error in " << file <<
": no camera configs found, this program requires cameras to function\n";
226 for(
const wpi::json& camera : j.at(
"cameras")) {
227 if(camera.count(
"calibration") > 0 && j.count(
"calibrations") > 0) {
228 wpi::json calibration;
230 calibration = j.at(
"calibrations").at(camera.at(
"calibration").get<std::string>());
231 cameras.emplace_back(camera, calibration);
233 }
catch (
const wpi::json::exception& e) {
234 wpi::errs() <<
"Config error in " << file <<
": failed to get configuration object: " << e.what() << newline;
235 cameras.emplace_back(camera);
238 cameras.emplace_back(camera);
240#ifdef REMOVE_DISCONNECTED_CAMERAS
241 if(!cameras.back().IsConnected()) { cameras.pop_back(); }
245 catch (
const wpi::json::exception& e) {
246 wpi::errs() <<
"Config error in " << file <<
": could not read cameras: " << e.what() << newline;
const Set::Cal_T * findCalib(const cv::Size2i &sz, const Set &set)
bool initNT(const char *file)
bool readConfig(std::vector< VisionCamera > &cameras, const char *file)
bool createCameras(std::vector< VisionCamera > &cameras, const char *file)
bool initSimNT(const char *sim_ip)
bool loadJson(wpi::json &j, const char *file)