00001 #include <ros/ros.h> 00002 //for ImageTransport, Publisher 00003 #include <image_transport/image_transport.h> 00004 // for a ton of boost-related shit 00005 #include <boost/thread.hpp> 00006 // for CameraInfo 00007 #include <sensor_msgs/CameraInfo.h> 00008 00009 class ImageSync 00010 { 00011 private: 00012 ros::NodeHandle nh_priv_; 00013 image_transport::ImageTransport it_; 00014 00015 sensor_msgs::ImagePtr left_img_, right_img_; 00016 sensor_msgs::CameraInfo left_info_, right_info_; 00017 00018 image_transport::Subscriber l_img_sub_, r_img_sub_; 00019 image_transport::Publisher l_img_pub_, r_img_pub_; 00020 00021 ros::Subscriber l_info_sub_, r_info_sub_; 00022 ros::Publisher l_info_pub_, r_info_pub_; 00023 00024 boost::mutex l_img_mutex_, r_img_mutex_, l_info_mutex_, r_info_mutex_, flag_mutex_; 00025 00026 bool new_left_img_; 00027 bool new_right_img_; 00028 bool new_left_info_; 00029 bool new_right_info_; 00030 00031 public: 00032 ImageSync( ros::NodeHandle & nh ) : 00033 nh_priv_( "~" ), it_( nh_priv_ ) 00034 { 00035 new_left_img_ = new_right_img_ = new_left_info_ = new_right_info_ = false; 00036 00037 l_img_sub_ = it_.subscribe( "image_l", 1, &ImageSync::imageLeftCB, this ); 00038 r_img_sub_ = it_.subscribe( "image_r", 1, &ImageSync::imageRightCB, this ); 00039 00040 l_info_sub_ = nh_priv_.subscribe( "info_l", 1, &ImageSync::infoLeftCB, this ); 00041 r_info_sub_ = nh_priv_.subscribe( "info_r", 1, &ImageSync::infoRightCB, this ); 00042 00043 l_img_pub_ = it_.advertise( "image_l_sync", 1 ); 00044 00045 r_img_pub_ = it_.advertise( "image_r_sync", 1 ); 00046 00047 l_info_pub_ = nh_priv_.advertise<sensor_msgs::CameraInfo> ( "info_l_sync", 1 ); 00048 00049 r_info_pub_ = nh_priv_.advertise<sensor_msgs::CameraInfo> ( "info_r_sync", 1 ); 00050 } 00051 00052 ~ImageSync() 00053 { 00054 00055 } 00056 00057 void publishSyncdImgs() 00058 { 00059 if ( new_left_img_ && new_right_img_ && new_left_info_ && new_right_info_ ) 00060 { 00061 ROS_DEBUG( "publishing..." ); 00062 boost::lock_guard<boost::mutex> limgguard( l_img_mutex_ ); 00063 boost::lock_guard<boost::mutex> rimgguard( r_img_mutex_ ); 00064 boost::lock_guard<boost::mutex> linfoguard( l_info_mutex_ ); 00065 boost::lock_guard<boost::mutex> rinfoguard( r_info_mutex_ ); 00066 00067 ros::Time now = ros::Time::now(); 00068 00069 left_img_->header.stamp = now; 00070 right_img_->header.stamp = now; 00071 left_info_.header.stamp = now; 00072 right_info_.header.stamp = now; 00073 00074 l_img_pub_.publish( left_img_ ); 00075 r_img_pub_.publish( right_img_ ); 00076 l_info_pub_.publish( left_info_ ); 00077 r_info_pub_.publish( right_info_ ); 00078 00079 00080 //Reset new flags 00081 new_left_img_ = false; 00082 new_right_img_ = false; 00083 new_left_info_ = false; 00084 new_right_info_ = false; 00085 00086 ROS_DEBUG( "done" ); 00087 } 00088 } 00089 00090 void imageLeftCB( const sensor_msgs::ImageConstPtr& msg ) 00091 { 00092 ROS_DEBUG( "got left img" ); 00093 l_img_mutex_.lock(); 00094 left_img_ = boost::const_pointer_cast<sensor_msgs::Image>( msg ); 00095 00096 l_img_mutex_.unlock(); 00097 00098 boost::lock_guard<boost::mutex> guard( flag_mutex_ ); 00099 new_left_img_ = true; 00100 00101 publishSyncdImgs(); 00102 } 00103 00104 void imageRightCB( const sensor_msgs::ImageConstPtr& msg ) 00105 { 00106 ROS_DEBUG( "got right img" ); 00107 r_img_mutex_.lock(); 00108 right_img_ = boost::const_pointer_cast<sensor_msgs::Image>( msg ); 00109 00110 r_img_mutex_.unlock(); 00111 00112 boost::lock_guard<boost::mutex> guard( flag_mutex_ ); 00113 new_right_img_ = true; 00114 00115 publishSyncdImgs(); 00116 } 00117 00118 void infoLeftCB( const sensor_msgs::CameraInfoConstPtr& msg ) 00119 { 00120 ROS_DEBUG( "got left info" ); 00121 l_info_mutex_.lock(); 00122 left_info_ = *msg; 00123 00124 l_info_mutex_.unlock(); 00125 00126 boost::lock_guard<boost::mutex> guard( flag_mutex_ ); 00127 new_left_info_ = true; 00128 00129 publishSyncdImgs(); 00130 } 00131 00132 void infoRightCB( const sensor_msgs::CameraInfoConstPtr& msg ) 00133 { 00134 ROS_DEBUG( "got right info" ); 00135 r_info_mutex_.lock(); 00136 right_info_ = *msg; 00137 00138 r_info_mutex_.unlock(); 00139 00140 boost::lock_guard<boost::mutex> guard( flag_mutex_ ); 00141 new_right_info_ = true; 00142 00143 publishSyncdImgs(); 00144 } 00145 00146 void spin() 00147 { 00148 ros::spin(); 00149 } 00150 00151 }; 00152 00153 int main( int argc, char * argv[] ) 00154 { 00155 ros::init( argc, argv, "image_sync" ); 00156 ros::NodeHandle nh; 00157 00158 ImageSync image_sync( nh ); 00159 image_sync.spin(); 00160 00161 return 0; 00162 }