#include #include #include #include #include #include "opencv2/opencv.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lidar_camera_calibration/Corners.h" #include "lidar_camera_calibration/PreprocessUtils.h" #include "lidar_camera_calibration/Find_RT.h" #include "lidar_camera_calibration/marker_6dof.h" using namespace cv; using namespace std; using namespace ros; using namespace message_filters; using namespace pcl; string CAMERA_INFO_TOPIC; string VELODYNE_TOPIC; Mat projection_matrix; pcl::PointCloud point_cloud; Hesai::PointCloud point_cloud_hesai; Eigen::Quaterniond qlidarToCamera; Eigen::Matrix3d lidarToCamera; void callback_noCam(const sensor_msgs::PointCloud2ConstPtr& msg_pc, const lidar_camera_calibration::marker_6dof::ConstPtr& msg_rt) { ROS_INFO_STREAM("Velodyne scan received at " << msg_pc->header.stamp.toSec()); ROS_INFO_STREAM("marker_6dof received at " << msg_rt->header.stamp.toSec()); // Loading Velodyne point cloud_sub if (config.lidar_type == 0) // velodyne lidar { fromROSMsg(*msg_pc, point_cloud); } else if (config.lidar_type == 1) //hesai lidar { fromROSMsg(*msg_pc, point_cloud_hesai); point_cloud = *(toMyPointXYZRID(point_cloud_hesai)); } point_cloud = transform(point_cloud, config.initialTra[0], config.initialTra[1], config.initialTra[2], config.initialRot[0], config.initialRot[1], config.initialRot[2]); //Rotation matrix to transform lidar point cloud to camera's frame qlidarToCamera = Eigen::AngleAxisd(config.initialRot[2], Eigen::Vector3d::UnitZ()) *Eigen::AngleAxisd(config.initialRot[1], Eigen::Vector3d::UnitY()) *Eigen::AngleAxisd(config.initialRot[0], Eigen::Vector3d::UnitX()); lidarToCamera = qlidarToCamera.matrix(); std:: cout << "\n\nInitial Rot" << lidarToCamera << "\n"; point_cloud = intensityByRangeDiff(point_cloud, config); // x := x, y := -z, z := y //pcl::io::savePCDFileASCII ("/home/vishnu/PCDs/msg_point_cloud.pcd", pc); cv::Mat temp_mat(config.s, CV_8UC3); pcl::PointCloud retval = *(toPointsXYZ(point_cloud)); std::vector marker_info; for(std::vector::const_iterator it = msg_rt->dof.data.begin(); it != msg_rt->dof.data.end(); ++it) { marker_info.push_back(*it); std::cout << *it << " "; } std::cout << "\n"; bool no_error = getCorners(temp_mat, retval, config.P, config.num_of_markers, config.MAX_ITERS); if(no_error){ find_transformation(marker_info, config.num_of_markers, config.MAX_ITERS, lidarToCamera); } //ros::shutdown(); } void callback(const sensor_msgs::CameraInfoConstPtr& msg_info, const sensor_msgs::PointCloud2ConstPtr& msg_pc, const lidar_camera_calibration::marker_6dof::ConstPtr& msg_rt) { ROS_INFO_STREAM("Camera info received at " << msg_info->header.stamp.toSec()); ROS_INFO_STREAM("Velodyne scan received at " << msg_pc->header.stamp.toSec()); ROS_INFO_STREAM("marker_6dof received at " << msg_rt->header.stamp.toSec()); float p[12]; float *pp = p; for (boost::array::const_iterator i = msg_info->P.begin(); i != msg_info->P.end(); i++) { *pp = (float)(*i); pp++; } cv::Mat(3, 4, CV_32FC1, &p).copyTo(projection_matrix); // Loading Velodyne point cloud_sub if (config.lidar_type == 0) // velodyne lidar { fromROSMsg(*msg_pc, point_cloud); } else if (config.lidar_type == 1) //hesai lidar { fromROSMsg(*msg_pc, point_cloud_hesai); point_cloud = *(toMyPointXYZRID(point_cloud_hesai)); } point_cloud = transform(point_cloud, config.initialTra[0], config.initialTra[1], config.initialTra[2], config.initialRot[0], config.initialRot[1], config.initialRot[2]); //Rotation matrix to transform lidar point cloud to camera's frame qlidarToCamera = Eigen::AngleAxisd(config.initialRot[2], Eigen::Vector3d::UnitZ()) *Eigen::AngleAxisd(config.initialRot[1], Eigen::Vector3d::UnitY()) *Eigen::AngleAxisd(config.initialRot[0], Eigen::Vector3d::UnitX()); lidarToCamera = qlidarToCamera.matrix(); point_cloud = intensityByRangeDiff(point_cloud, config); // x := x, y := -z, z := y //pcl::io::savePCDFileASCII ("/home/vishnu/PCDs/msg_point_cloud.pcd", pc); cv::Mat temp_mat(config.s, CV_8UC3); pcl::PointCloud retval = *(toPointsXYZ(point_cloud)); std::vector marker_info; for(std::vector::const_iterator it = msg_rt->dof.data.begin(); it != msg_rt->dof.data.end(); ++it) { marker_info.push_back(*it); std::cout << *it << " "; } std::cout << "\n"; getCorners(temp_mat, retval, projection_matrix, config.num_of_markers, config.MAX_ITERS); find_transformation(marker_info, config.num_of_markers, config.MAX_ITERS, lidarToCamera); //ros::shutdown(); } int main(int argc, char** argv) { readConfig(); ros::init(argc, argv, "find_transform"); ros::NodeHandle n; if(config.useCameraInfo) { ROS_INFO_STREAM("Reading CameraInfo from topic"); n.getParam("/lidar_camera_calibration/camera_info_topic", CAMERA_INFO_TOPIC); n.getParam("/lidar_camera_calibration/velodyne_topic", VELODYNE_TOPIC); message_filters::Subscriber info_sub(n, CAMERA_INFO_TOPIC, 1); message_filters::Subscriber cloud_sub(n, VELODYNE_TOPIC, 1); message_filters::Subscriber rt_sub(n, "lidar_camera_calibration_rt", 1); std::cout << "done1\n"; typedef sync_policies::ApproximateTime MySyncPolicy; Synchronizer sync(MySyncPolicy(10), info_sub, cloud_sub, rt_sub); sync.registerCallback(boost::bind(&callback, _1, _2, _3)); ros::spin(); } else { ROS_INFO_STREAM("Reading CameraInfo from configuration file"); n.getParam("/lidar_camera_calibration/velodyne_topic", VELODYNE_TOPIC); message_filters::Subscriber cloud_sub(n, VELODYNE_TOPIC, 1); message_filters::Subscriber rt_sub(n, "lidar_camera_calibration_rt", 1); typedef sync_policies::ApproximateTime MySyncPolicy; Synchronizer sync(MySyncPolicy(10), cloud_sub, rt_sub); sync.registerCallback(boost::bind(&callback_noCam, _1, _2)); ros::spin(); } return EXIT_SUCCESS; }