calibration_service.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2014, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *   http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #include <industrial_extrinsic_cal/runtime_utils.h>
00020 #include <std_srvs/Empty.h>
00021 #include <ros/ros.h>
00022 #include <ros/package.h>
00023 
00024 bool calibrated=false;
00025 bool callback(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response);
00026 std::vector<tf::Transform> b_transforms;
00027 
00028 int main(int argc, char **argv)
00029 {
00030   ros::init(argc, argv, "calibration_service_node");
00031 
00032   ros::NodeHandle nh;
00033   ros::ServiceServer service=nh.advertiseService("calibration_service", callback);
00034   industrial_extrinsic_cal::ROSRuntimeUtils utils;
00035   ros::NodeHandle priv_nh_("~");
00036 
00037   priv_nh_.getParam("camera_file", utils.camera_file_);
00038   priv_nh_.getParam("target_file", utils.target_file_);
00039   priv_nh_.getParam("cal_job_file", utils.caljob_file_);
00040   std::string path = ros::package::getPath("industrial_extrinsic_cal");
00041   std::string file_path=path+"/yaml/";
00042   industrial_extrinsic_cal::CalibrationJob cal_job(file_path+utils.camera_file_, file_path+utils.target_file_, file_path+utils.caljob_file_);
00043 
00044   if (cal_job.load())
00045   {
00046     ROS_INFO_STREAM("Calibration job (cal_job, target and camera) yaml parameters loaded.");
00047   }
00048 
00049   utils.world_frame_=cal_job.getReferenceFrame();
00050   utils.camera_optical_frame_=cal_job.getCameraOpticalFrame();
00051   utils.camera_intermediate_frame_=cal_job.getCameraIntermediateFrame();
00052   utils.initial_extrinsics_ = cal_job.getOriginalExtrinsics();
00053   utils.target_frame_=cal_job.getTargetFrames();
00054   industrial_extrinsic_cal::P_BLOCK orig_extrinsics;
00055   tf::Transform tf_camera_orig;
00056   for (int k=0; k<utils.initial_extrinsics_.size(); k++ )
00057   {
00058     orig_extrinsics=utils.initial_extrinsics_[k];
00059     ROS_INFO_STREAM("Original Camera "<<k);
00060     tf_camera_orig= utils.pblockToPose(orig_extrinsics);
00061     utils.initial_transforms_.push_back(tf_camera_orig);
00062   }
00063 
00064   ROS_INFO_STREAM("Target frame1: "<<utils.target_frame_[0]);
00065   ROS_INFO_STREAM("World frame: "<<utils.world_frame_);
00066   ROS_INFO_STREAM("Init tf size: "<<utils.initial_transforms_.size());
00067   tf::StampedTransform temp_tf;
00068   try
00069   {
00070     utils.listener_.waitForTransform( utils.world_frame_,utils.target_frame_[0],
00071                                       ros::Time(0), ros::Duration(3.0));
00072     utils.listener_.lookupTransform(utils.world_frame_,utils.target_frame_[0], ros::Time(0), temp_tf);
00073     utils.points_to_world_transforms_.push_back(temp_tf);
00074   }
00075   catch (tf::TransformException &ex)
00076   {
00077     ROS_ERROR("%s",ex.what());
00078   }
00079   for (int k=0; k<utils.initial_transforms_.size(); k++ )
00080   {
00081     utils.initial_transforms_[k]=utils.points_to_world_transforms_[0]*utils.initial_transforms_[k];
00082   }
00083 
00084 
00085   utils.broadcasters_.resize(utils.initial_extrinsics_.size());
00086 
00087   ros::Rate r(5); // 5 hz
00088   while (ros::ok())
00089   {
00090     if(!calibrated)
00091     {
00092       b_transforms=utils.initial_transforms_;
00093       for (int k=0; k<b_transforms.size(); k++ )
00094       {
00095         utils.broadcasters_[k].sendTransform(tf::StampedTransform(b_transforms[k], ros::Time::now(),
00096                                                                   utils.world_frame_, utils.camera_intermediate_frame_[k]));
00097       }
00098     }
00099     else if(calibrated)
00100     {
00101       for (int k=0; k<b_transforms.size(); k++ )
00102       {
00103         utils.broadcasters_[k].sendTransform(tf::StampedTransform(b_transforms[k], ros::Time::now(),
00104                                                                   utils.world_frame_, utils.camera_intermediate_frame_[k]));
00105       }
00106     }
00107     ros::spinOnce();
00108     r.sleep();
00109   }
00110 
00111 
00112   ros::spin();
00113   return 0;
00114 }
00115 
00116 bool callback(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response)
00117 {
00118   industrial_extrinsic_cal::ROSRuntimeUtils utils;
00119   ros::NodeHandle priv_nh_("~");
00120 
00121   std::string ros_package_name;
00122   std::string launch_file_name;
00123   priv_nh_.getParam("camera_file", utils.camera_file_);
00124   priv_nh_.getParam("target_file", utils.target_file_);
00125   priv_nh_.getParam("cal_job_file", utils.caljob_file_);
00126   priv_nh_.getParam("store_results_package_name", ros_package_name);
00127   priv_nh_.getParam("store_results_file_name", launch_file_name);
00128   std::string path = ros::package::getPath("industrial_extrinsic_cal");
00129   std::string file_path=path+"/yaml/";
00130   industrial_extrinsic_cal::CalibrationJob cal_job(file_path+utils.camera_file_, file_path+utils.target_file_, file_path+utils.caljob_file_);
00131 
00132   cal_job.load();
00133   utils.world_frame_=cal_job.getReferenceFrame();
00134   utils.camera_optical_frame_=cal_job.getCameraOpticalFrame();
00135   utils.camera_intermediate_frame_=cal_job.getCameraIntermediateFrame();
00136   utils.target_frame_=cal_job.getTargetFrames();
00137   if (cal_job.run())
00138   {
00139     ROS_INFO_STREAM("Calibration job observations and optimization complete");
00140   }
00141   utils.calibrated_extrinsics_ = cal_job.getExtrinsics();
00142   utils.target_poses_ = cal_job.getTargetPose();
00143   ROS_DEBUG_STREAM("Size of optimized_extrinsics_: "<<utils.calibrated_extrinsics_.size());
00144   ROS_DEBUG_STREAM("Size of targets_: "<<utils.target_poses_.size());
00145 
00146   industrial_extrinsic_cal::P_BLOCK optimized_extrinsics, target;
00147   tf::Transform tf_camera, tf_target;
00148   for (int k=0; k<utils.calibrated_extrinsics_.size(); k++ )
00149   {
00150     optimized_extrinsics=utils.calibrated_extrinsics_[k];
00151     ROS_INFO_STREAM("Optimized Camera "<<k);
00152      tf_camera= utils.pblockToPose(optimized_extrinsics);
00153     utils.calibrated_transforms_.push_back(tf_camera);
00154   }
00155   for (int k=0; k<utils.target_poses_.size(); k++ )
00156   {
00157     target=utils.target_poses_[k];
00158     ROS_INFO_STREAM("Optimized Target "<<k);
00159     tf_target = utils.pblockToPose(target);
00160     utils.target_transforms_.push_back(tf_target);
00161   }
00162   tf::StampedTransform temp_tf;
00163   for (int i=0; i<utils.calibrated_extrinsics_.size(); i++ )
00164   {
00165     try
00166     {
00167       utils.listener_.waitForTransform( utils.camera_optical_frame_[i],utils.camera_intermediate_frame_[i],
00168                                         ros::Time(0), ros::Duration(3.0));
00169       utils.listener_.lookupTransform( utils.camera_optical_frame_[i],utils.camera_intermediate_frame_[i],
00170                                        ros::Time(0), temp_tf);
00171       utils.camera_internal_transforms_.push_back(temp_tf);
00172     }
00173     catch (tf::TransformException &ex)
00174     {
00175       ROS_ERROR("%s",ex.what());
00176     }
00177   }
00178   ROS_INFO_STREAM("Size of internal_transforms: "<<utils.camera_internal_transforms_.size());
00179   for (int k=0; k<utils.calibrated_transforms_.size(); k++ )
00180   {
00181     utils.calibrated_transforms_[k]=utils.calibrated_transforms_[k]*utils.camera_internal_transforms_[k];
00182   }
00183   ROS_INFO_STREAM("Target frame1: "<<utils.target_frame_[0]);
00184   ROS_INFO_STREAM("World frame: "<<utils.world_frame_);
00185   try
00186   {
00187     utils.listener_.waitForTransform(utils.world_frame_,utils.target_frame_[0], ros::Time(0), ros::Duration(3.0));
00188     utils.listener_.lookupTransform(utils.world_frame_,utils.target_frame_[0], ros::Time(0), temp_tf);
00189     utils.points_to_world_transforms_.push_back(temp_tf);
00190   }
00191   catch (tf::TransformException &ex)
00192   {
00193     ROS_ERROR("%s",ex.what());
00194   }
00195   for (int k=0; k<utils.calibrated_transforms_.size(); k++ )
00196   {
00197     utils.calibrated_transforms_[k]=utils.points_to_world_transforms_[0]*utils.calibrated_transforms_[k];
00198   }
00199 
00200   b_transforms=utils.calibrated_transforms_;
00201   calibrated=true;
00202 
00203   if (cal_job.store())
00204   {
00205     ROS_INFO_STREAM("Calibration job optimization camera results saved");
00206   }
00207 
00208   std::string save_package_path = ros::package::getPath(ros_package_name);
00209   std::string save_file_path = "/launch/"+launch_file_name;
00210   if (utils.store_tf_broadcasters(save_package_path, save_file_path))
00211   {
00212     ROS_INFO_STREAM("Calibration job optimization camera to world transforms saved");
00213   }
00214 
00215   ROS_INFO_STREAM("Camera pose(s) published");
00216 
00217   return true;
00218 }


industrial_extrinsic_cal
Author(s): Chris Lewis
autogenerated on Wed Aug 26 2015 12:00:27