10 #include <Eigen/Dense> 12 #include <Eigen/Geometry> 13 #include <unsupported/Eigen/MatrixFunctions> 15 using namespace Eigen;
27 Eigen::Quaterniond
addQ(Eigen::Quaterniond a, Eigen::Quaterniond b) {
28 Eigen::Quaterniond retval;
29 if (a.x() * b.x() + a.y() * b.y() + a.z() * b.z() + a.w() * b.w() < 0.0) {
35 retval.x() = a.x() + b.x();
36 retval.y() = a.y() + b.y();
37 retval.z() = a.z() + b.z();
38 retval.w() = a.w() + b.w();
43 std::ifstream infile(
pkg_loc +
"/conf/points.txt");
50 MatrixXd lidar(3, num_points), camera(3, num_points);
52 std::cout <<
"Num points is:" << num_points << std::endl;
54 for (
int i = 0; i < num_points; i++) {
55 infile >> lidar(0, i) >> lidar(1, i) >> lidar(2, i);
57 for (
int i = 0; i < num_points; i++) {
58 infile >> camera(0, i) >> camera(1, i) >> camera(2, i);
64 return std::pair<MatrixXd, MatrixXd>(lidar, camera);
71 std::ofstream clean_file(
pkg_loc +
"/log/avg_values.txt", std::ios_base::trunc);
81 int num_points = lidar.cols();
82 std::cout <<
"Number of points: " << num_points << std::endl;
83 Vector3d mu_lidar, mu_camera;
85 mu_lidar << 0.0, 0.0, 0.0;
86 mu_camera << 0.0, 0.0, 0.0;
88 for (
int i = 0; i < num_points; i++) {
89 mu_lidar(0) += lidar(0, i);
90 mu_lidar(1) += lidar(1, i);
91 mu_lidar(2) += lidar(2, i);
93 for (
int i = 0; i < num_points; i++) {
94 mu_camera(0) += camera(0, i);
95 mu_camera(1) += camera(1, i);
96 mu_camera(2) += camera(2, i);
99 mu_lidar = mu_lidar / num_points;
100 mu_camera = mu_camera / num_points;
103 std::cout <<
"mu_lidar: \n" << mu_lidar << std::endl;
104 std::cout <<
"mu_camera: \n" << mu_camera << std::endl;
107 MatrixXd lidar_centered = lidar.colwise() - mu_lidar;
108 MatrixXd camera_centered = camera.colwise() - mu_camera;
111 std::cout <<
"lidar_centered: \n" << lidar_centered << std::endl;
112 std::cout <<
"camera_centered: \n" << camera_centered << std::endl;
115 Matrix3d cov = camera_centered * lidar_centered.transpose();
117 std::cout << cov << std::endl;
119 JacobiSVD <MatrixXd> svd(cov, ComputeFullU | ComputeFullV);
122 rotation = svd.matrixU() * svd.matrixV().transpose();
123 if (rotation.determinant() < 0) {
124 Vector3d diag_correct;
125 diag_correct << 1.0, 1.0, -1.0;
127 rotation = svd.matrixU() * diag_correct.asDiagonal() * svd.matrixV().transpose();
130 Vector3d translation = mu_camera - rotation * mu_lidar;
134 Quaterniond temp_q(rotation);
141 Vector3d ea = rotation.eulerAngles(2, 1, 0);
143 std::cout <<
"Rotation matrix: \n" << rotation << std::endl;
144 std::cout <<
"Rotation in Euler angles: \n" << ea * 57.3 << std::endl;
145 std::cout <<
"Translation: \n" << translation << std::endl;
147 MatrixXd eltwise_error = (camera - ((rotation * lidar).colwise() + translation)).array().square().colwise().sum();
148 double error = sqrt(eltwise_error.sum() / num_points);
149 std::cout <<
"RMSE: " << error << std::endl;
155 T.topLeftCorner(3, 3) = rotation;
156 T.col(3).head(3) = translation;
158 std::cout <<
"Rigid-body transformation: \n" << T << std::endl;
163 std::ofstream log_avg_values(
pkg_loc +
"/log/avg_values.txt", std::ios_base::app);
165 std::cout <<
"--------------------------------------------------------------------\n";
167 std::cout <<
"--------------------------------------------------------------------\n";
169 std::cout <<
"Average translation is:" <<
"\n" <<
translation_sum / iteration_counter <<
"\n";
170 log_avg_values << iteration_counter <<
"\n";
187 Eigen::Matrix3d rotation_avg =
rotation_sum.toRotationMatrix();
188 std::cout <<
"Average rotation is:" <<
"\n" << rotation_avg <<
"\n";
189 Eigen::Matrix3d final_rotation = rotation_avg *
lidarToCamera;
190 Eigen::Vector3d final_angles = final_rotation.eulerAngles(2, 1, 0);
192 log_avg_values << std::fixed << std::setprecision(8)
193 << rotation_avg(0, 0) <<
" " << rotation_avg(0, 1) <<
" " << rotation_avg(0, 2) <<
"\n" 194 << rotation_avg(1, 0) <<
" " << rotation_avg(1, 1) <<
" " << rotation_avg(1, 2) <<
"\n" 195 << rotation_avg(2, 0) <<
" " << rotation_avg(2, 1) <<
" " << rotation_avg(2, 2) <<
"\n";
199 T.topLeftCorner(3, 3) = rotation_avg;
201 std::cout <<
"Average transformation is: \n" << T <<
"\n";
202 std::cout <<
"Final rotation is:" <<
"\n" << final_rotation <<
"\n";
203 std::cout <<
"Final ypr is:" <<
"\n" << final_angles <<
"\n";
205 std::cout <<
"Average RMSE is: " <<
rmse_avg * 1.0 / iteration_counter <<
"\n";
207 MatrixXd eltwise_error_temp = (camera - ((rotation_avg * lidar).colwise() + (
translation_sum /
209 double error_temp = sqrt(eltwise_error_temp.sum() / num_points);
211 std::cout <<
"RMSE on average transformation is: " << error_temp << std::endl;
212 log_avg_values << std::fixed << std::setprecision(8) << error_temp <<
"\n";
220 void readArucoPose(std::vector<float> marker_info,
int num_of_marker_in_config) {
221 std::vector <Matrix4d> marker_pose;
223 ROS_ASSERT(marker_info.size() / 7 == num_of_marker_in_config);
226 for (
int i = 0; i < marker_info.size() / 7; i++) {
229 int marker_id = marker_info[j++];
230 trans(0) = marker_info[j++];
231 trans(1) = marker_info[j++];
232 trans(2) = marker_info[j++];
233 rot(0) = marker_info[j++];
234 rot(1) = marker_info[j++];
235 rot(2) = marker_info[j++];
237 Transform<double, 3, Affine> aa;
238 aa = AngleAxis<double>(rot.norm(), rot / rot.norm());
246 T.topLeftCorner(3, 3) = g.topLeftCorner(3, 3);
247 T.col(3).head(3) = trans;
249 marker_pose.push_back(T);
254 std::ifstream infile(
pkg_loc +
"/conf/marker_coordinates.txt");
255 std::ofstream outfile(
pkg_loc +
"/conf/points.txt", std::ios_base::app);
258 infile >> num_of_markers;
260 for (
int i = 0; i < num_of_markers; i++) {
262 std::vector<float> board;
263 for (
int j = 0; j < 5; j++) {
265 board.push_back(temp / 100.0);
268 la = board[4] / 2 + board[2];
269 ba = board[4] / 2 + board[3];
271 Matrix4d points_board;
272 points_board << ba, 0, board[0] - la, 1,
273 ba - board[1], 0, board[0] - la, 1,
274 ba - board[1], 0, -la, 1,
277 points_board = marker_pose[i] * (points_board.transpose());
279 for (
int k = 0; k < 4; k++) {
280 outfile << points_board(0, k) <<
" " << points_board(1, k) <<
" " << points_board(2, k) <<
"\n";
292 std::pair <MatrixXd, MatrixXd> point_clouds =
readArray();
293 Matrix4d T =
calc_RT(point_clouds.first, point_clouds.second, MAX_ITERS, lidarToCamera);
void readArucoPose(std::vector< float > marker_info, int num_of_marker_in_config)
Eigen::Matrix3d rotation_avg_by_mult
Eigen::Quaterniond rotation_sum
Matrix4d calc_RT(MatrixXd lidar, MatrixXd camera, int MAX_ITERS, Eigen::Matrix3d lidarToCamera)
ROSLIB_DECL std::string getPath(const std::string &package_name)
Eigen::Matrix3d lidarToCamera
Eigen::Vector3d translation_sum
std::pair< MatrixXd, MatrixXd > readArray()
void find_transformation(std::vector< float > marker_info, int num_of_marker_in_config, int MAX_ITERS, Eigen::Matrix3d lidarToCamera)
Eigen::Quaterniond addQ(Eigen::Quaterniond a, Eigen::Quaterniond b)