38 #ifndef WIN32_LEAN_AND_MEAN
39 #define WIN32_LEAN_AND_MEAN 1
55 #include <MultiSense/MultiSenseChannel.hh>
65 void usage(
const char *name)
67 std::cerr <<
"USAGE: " << name <<
" -e <extrinsics-file> -i <intrinsics-file> [<options>]" << std::endl;
68 std::cerr <<
"Where <options> are:" << std::endl;
69 std::cerr <<
"\t-a <current_address> : CURRENT IPV4 address (default=10.66.171.21)" << std::endl;
70 std::cerr <<
"\t-m <mtu> : MTU to use to communicate with the camera (default=1500)" << std::endl;
71 std::cerr <<
"\t-s : Set the input calibration(default=false)" << std::endl;
72 std::cerr <<
"\t-y : Disable confirmation prompt (default=false)" << std::endl;
76 template <
size_t H,
size_t W>
77 std::array<std::array<float, W>, H> convert_matrix(
const std::vector<float> &source)
79 if ((H * W) != source.size())
81 throw std::runtime_error(
"Matrix sizes do not match");
84 std::array<std::array<float, W>, H> output;
86 memcpy(&output[0][0], source.data(),
sizeof(
float) * source.size());
96 return lms::CameraCalibration::DistortionType::NONE;
98 return lms::CameraCalibration::DistortionType::PLUMBBOB;
100 return lms::CameraCalibration::DistortionType::RATIONAL_POLYNOMIAL;
103 return lms::CameraCalibration::DistortionType::NONE;
107 const std::map<std::string, std::vector<float>> &extrinsics,
112 output.
K = convert_matrix<3, 3>(intrinsics.at(
"M" +
std::to_string(index)));
113 output.R = convert_matrix<3, 3>(extrinsics.at(
"R" +
std::to_string(index)));
114 output.P = convert_matrix<3, 4>(extrinsics.at(
"P" +
std::to_string(index)));
116 output.distortion_type = get_distortion_type(output.D.size());
131 int main(
int argc,
char** argv)
133 std::string ip_address =
"10.66.171.21";
135 std::filesystem::path intrinsics_path{};
136 std::filesystem::path extrinsics_path{};
137 bool set_cal =
false;
138 bool disable_confirmation =
false;
141 while(-1 != (c =
getopt(argc, argv,
"a:m:e:i:sy")))
145 case 'a': ip_address = std::string(
optarg);
break;
146 case 'm': mtu =
static_cast<uint16_t
>(atoi(
optarg));
break;
147 case 'i': intrinsics_path =
optarg;
break;
148 case 'e': extrinsics_path =
optarg;
break;
149 case 's': set_cal =
true;
break;
150 case 'y': disable_confirmation =
true;
break;
151 default:
usage(*argv);
break;
155 if (set_cal && (!std::filesystem::exists(intrinsics_path) || !std::filesystem::exists(extrinsics_path)))
157 std::cerr <<
"Invalid input or calibration paths" << std::endl;
162 if (!set_cal && !disable_confirmation &&
163 (std::filesystem::exists(intrinsics_path) || std::filesystem::exists(extrinsics_path)))
165 std::cout <<
"One or both of the input file already exists\n" << std::endl;
166 std::cout <<
"Really overwrite these files? (y/n):" << std::endl;
168 if (
const int reply = getchar(); reply !=
'Y' && reply !=
'y')
170 std::cerr <<
"Aborting" << std::endl;
178 std::cerr <<
"Failed to create channel" << std::endl;
182 auto calibration = channel->get_calibration();
186 std::cout <<
"Attempting to set the MultiSense calibration" << std::endl;
187 std::ifstream intrinsics{};
188 std::ifstream extrinsics{};
190 intrinsics.open(intrinsics_path);
191 extrinsics.open(extrinsics_path);
193 if (!intrinsics.is_open() || !extrinsics.is_open())
195 std::cerr <<
"Error opening calibration files" << std::endl;
199 std::map<std::string, std::vector<float>> intrinsics_data{};
202 std::map<std::string, std::vector<float>> extrinsics_data{};
205 calibration.left =
read_cal(intrinsics_data, extrinsics_data, 1);
206 calibration.right =
read_cal(intrinsics_data, extrinsics_data, 2);
210 calibration.aux =
read_cal(intrinsics_data, extrinsics_data, 3);
213 if (
const auto status = channel->set_calibration(calibration); status != lms::Status::OK)
215 std::cerr <<
"Unable to set the calibration" << std::endl;
219 std::cout <<
"Image calibration successfully updated" << std::endl;
223 std::ofstream intrinsics{};
224 std::ofstream extrinsics{};
226 intrinsics.open(intrinsics_path, std::ios_base::out | std::ios_base::trunc);
227 extrinsics.open(extrinsics_path, std::ios_base::out | std::ios_base::trunc);
229 if (!intrinsics.is_open() || !extrinsics.is_open())
231 std::cerr <<
"Error opening calibration files" << std::endl;
235 intrinsics <<
"%YAML:1.0\n";
236 extrinsics <<
"%YAML:1.0\n";
238 write_cal(intrinsics, extrinsics, calibration.left, 1);
239 write_cal(intrinsics, extrinsics, calibration.right, 2);
243 write_cal(intrinsics, extrinsics, calibration.aux.value(), 3);