split_xb3_nodelet.cpp
Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2012-2013, Laboratorio de Robotica Movel - ICMC/USP
00003  *  Rafael Luiz Klaser <rlklaser@gmail.com>
00004  *  http://lrm.icmc.usp.br
00005  *
00006  *  Apoio FAPESP: 2012/04555-4
00007  *
00008  *  This program is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License
00019  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00030 #include <ros/ros.h>
00031 #include <nodelet/nodelet.h>
00032 #include <image_transport/image_transport.h>
00033 #include <sensor_msgs/image_encodings.h>
00034 #include <camera_info_manager/camera_info_manager.h>
00035 
00036 #include <lrm_camera_drivers/split_node.h>
00037 
00038 namespace lrm_camera_drivers {
00039 
00040 class SplitXB3Nodelet: public nodelet::Nodelet {
00041 
00042         struct st_stereo_camera wide_ctx_;
00043         struct st_stereo_camera narrow_ctx_;
00044 
00045         image_transport::Subscriber sub_;
00046         boost::shared_ptr<image_transport::ImageTransport> it_;
00047 
00048         void publishCam(const sensor_msgs::Image& image);
00049 
00050         bool fillImages(sensor_msgs::Image& narrow_left_image, sensor_msgs::Image&
00051                         narrow_right_image, sensor_msgs::Image& wide_left_image,
00052                         sensor_msgs::Image& wide_right_image, std::string encoding_arg,
00053                         uint32_t rows_arg, uint32_t cols_arg, const void* data_arg);
00054 
00055         virtual void onInit();
00056         void connectCb();
00057         void imageCb(const sensor_msgs::ImageConstPtr& raw_msg);
00058 };
00059 
00060 void SplitXB3Nodelet::onInit() {
00061         ros::NodeHandle &nh = getNodeHandle();
00062         ros::NodeHandle &nh_priv = getPrivateNodeHandle();
00063 
00064         it_.reset(new image_transport::ImageTransport(nh));
00065 
00066         std::string name;
00067         std::string narrow_frame_id;
00068         std::string wide_frame_id;
00069 
00070         nh_priv.param("name", name, std::string("camera"));
00071 
00072         narrow_ctx_.name = name;
00073         wide_ctx_.name = name;
00074 
00075         { //narrow
00076                 ros::NodeHandle nh_baseline(nh.getNamespace() + "/narrow");
00077                 ros::NodeHandle nh_left(nh_baseline.getNamespace() + "/left");
00078                 ros::NodeHandle nh_right(nh_baseline.getNamespace() + "/right");
00079 
00080                 nh_priv.param("narrow/frame_id", narrow_ctx_.frame_id, std::string(""));
00081                 nh_priv.param("narrow/left/camera_info_url", narrow_ctx_.left.url, std::string(""));
00082                 nh_priv.param("narrow/right/camera_info_url", narrow_ctx_.right.url, std::string(""));
00083 
00084                 narrow_ctx_.left.publisher = it_->advertiseCamera(nh_left.getNamespace() + "/image_raw", 1);
00085                 narrow_ctx_.right.publisher = it_->advertiseCamera(nh_right.getNamespace() + "/image_raw", 1);
00086 
00087                 narrow_ctx_.left.manager.reset(new camera_info_manager::CameraInfoManager(
00088                                 nh_left, narrow_ctx_.name + "_narrow_left", narrow_ctx_.left.url));
00089                 narrow_ctx_.right.manager.reset(new camera_info_manager::CameraInfoManager(
00090                                 nh_right, narrow_ctx_.name + "_narrow_right", narrow_ctx_.right.url));
00091         }
00092 
00093         { //wide
00094                 ros::NodeHandle nh_baseline(nh.getNamespace() + "/wide");
00095                 ros::NodeHandle nh_left(nh_baseline.getNamespace() + "/left");
00096                 ros::NodeHandle nh_right(nh_baseline.getNamespace() + "/right");
00097 
00098                 nh_priv.param("wide/frame_id", narrow_ctx_.frame_id, std::string(""));
00099                 nh_priv.param("wide/left/camera_info_url", wide_ctx_.left.url, std::string(""));
00100                 nh_priv.param("wide/right/camera_info_url", wide_ctx_.right.url, std::string(""));
00101 
00102                 wide_ctx_.left.publisher = it_->advertiseCamera(nh_left.getNamespace() + "/image_raw", 1);
00103                 wide_ctx_.right.publisher = it_->advertiseCamera(nh_right.getNamespace() + "/image_raw", 1);
00104 
00105                 wide_ctx_.left.manager.reset(new camera_info_manager::CameraInfoManager(
00106                                 nh_left, wide_ctx_.name + "_wide_left", wide_ctx_.left.url));
00107                 wide_ctx_.right.manager.reset(new camera_info_manager::CameraInfoManager(
00108                                 nh_right, wide_ctx_.name + "_wide_right", wide_ctx_.right.url));
00109         }
00110 
00111         image_transport::TransportHints hints("raw", ros::TransportHints(), nh);
00112         sub_ = it_->subscribe("camera/image_raw", 1, &SplitXB3Nodelet::imageCb, this, hints);
00113 }
00114 
00115 void SplitXB3Nodelet::connectCb() {
00116 }
00117 
00118 void SplitXB3Nodelet::imageCb(const sensor_msgs::ImageConstPtr& raw_msg) {
00119         publishCam(*raw_msg);
00120 }
00121 
00122 bool SplitXB3Nodelet::fillImages(sensor_msgs::Image& narrow_left_image, sensor_msgs::Image&
00123                 narrow_right_image, sensor_msgs::Image& wide_left_image, sensor_msgs::Image& wide_right_image,
00124                 std::string encoding_arg, uint32_t rows_arg, uint32_t cols_arg, const void* data_arg) {
00125 
00126         uint32_t step_arg = cols_arg * sensor_msgs::image_encodings::numChannels(encoding_arg);
00127 
00128         size_t st0 = (step_arg * rows_arg);
00129 
00130         narrow_left_image.encoding = encoding_arg;
00131         narrow_left_image.height = rows_arg;// / 2;
00132         narrow_left_image.width = cols_arg;// / 2;
00133         narrow_left_image.step = cols_arg;
00134         narrow_left_image.data.resize(st0);
00135 
00136         narrow_right_image.encoding = encoding_arg;
00137         narrow_right_image.height = rows_arg;// / 2;
00138         narrow_right_image.width = cols_arg;// / 2;
00139         narrow_right_image.step = cols_arg;
00140         narrow_right_image.data.resize(st0);
00141 
00142         wide_left_image.encoding = encoding_arg;
00143         wide_left_image.height = rows_arg;// / 2;
00144         wide_left_image.width = cols_arg;// / 2;
00145         wide_left_image.step = cols_arg;
00146         wide_left_image.data.resize(st0);
00147 
00148         wide_right_image.encoding = encoding_arg;
00149         wide_right_image.height = rows_arg;// / 2;
00150         wide_right_image.width = cols_arg;// / 2;
00151         wide_right_image.step = cols_arg;
00152         wide_right_image.data.resize(st0);
00153 
00154         char* crt = (char*) data_arg;
00155         char* narrow_left = (char*) &narrow_left_image.data[0];
00156         char* narrow_right = (char*) &narrow_right_image.data[0];
00157         char* wide_left = (char*) &wide_left_image.data[0];
00158         char* wide_right = (char*) &wide_right_image.data[0];
00159 
00160         int k = cols_arg * rows_arg;
00161 
00162         //deinterlace
00163         while (k > 0) {
00164                 /*
00165                 *(narrow_right++) = *crt;
00166                 *(wide_right++) = *(crt++);
00167                 *(narrow_left++) = *(crt++);
00168                 *(wide_left++) = *(crt++);
00169                 */
00170                 *(wide_right++) = *(crt++);
00171                 *(narrow_right++) = *(crt++);
00172                 *(narrow_left++) = *(crt);
00173                 *(wide_left++) = *(crt++);
00174                 k--;
00175         }
00176 
00177         narrow_left_image.is_bigendian = 0;
00178         narrow_right_image.is_bigendian = 0;
00179         wide_left_image.is_bigendian = 0;
00180         wide_right_image.is_bigendian = 0;
00181 
00182         return true;
00183 }
00184 
00185 void SplitXB3Nodelet::publishCam(const sensor_msgs::Image& image) {
00186         uint32_t imHeight = image.height;
00187         uint32_t imWidth = image.width;
00188         const void *imRaw = image.data.data();
00189 
00190         std::string encoding = /*sensor_msgs::image_encodings::MONO8;*/ sensor_msgs::image_encodings::BAYER_GBRG8;
00191 
00192         fillImages(narrow_ctx_.left.image, narrow_ctx_.right.image,
00193                         wide_ctx_.left.image, wide_ctx_.right.image,
00194                         encoding, imHeight, imWidth, imRaw);
00195 
00196         // Update diagnostics and publish
00197         ros::Time stamp = image.header.stamp;
00198 
00199         //narrow
00200         narrow_ctx_.frame_id = narrow_ctx_.frame_id == "" ? image.header.frame_id : narrow_ctx_.frame_id;
00201 
00202         narrow_ctx_.left.image.header.frame_id = narrow_ctx_.frame_id;
00203         narrow_ctx_.right.image.header.frame_id = narrow_ctx_.frame_id;
00204 
00205         narrow_ctx_.left.info = narrow_ctx_.left.manager->getCameraInfo();
00206         narrow_ctx_.left.info.header.frame_id = narrow_ctx_.frame_id;
00207         //narrow_ctx_.left.info.header.stamp = stamp;
00208         narrow_ctx_.left.info.height = imHeight;
00209         narrow_ctx_.left.info.width = imWidth;
00210 
00211         narrow_ctx_.right.info = narrow_ctx_.right.manager->getCameraInfo();
00212         narrow_ctx_.right.info.header.frame_id = narrow_ctx_.frame_id;
00213         //narrow_ctx_.right.info.header.stamp = stamp;
00214         narrow_ctx_.right.info.height = imHeight;
00215         narrow_ctx_.right.info.width = imWidth;
00216 
00217         narrow_ctx_.left.publisher.publish(narrow_ctx_.left.image, narrow_ctx_.left.info, stamp);
00218         narrow_ctx_.right.publisher.publish(narrow_ctx_.right.image, narrow_ctx_.right.info, stamp);
00219 
00220         //wide
00221         wide_ctx_.frame_id = wide_ctx_.frame_id == "" ? image.header.frame_id : wide_ctx_.frame_id;
00222 
00223         wide_ctx_.left.image.header.frame_id = wide_ctx_.frame_id;
00224         wide_ctx_.right.image.header.frame_id = wide_ctx_.frame_id;
00225 
00226         wide_ctx_.left.info = wide_ctx_.left.manager->getCameraInfo();
00227         wide_ctx_.left.info.header.frame_id = wide_ctx_.frame_id;
00228         //wide_ctx_.left.info.header.stamp = stamp;
00229         wide_ctx_.left.info.height = imHeight;
00230         wide_ctx_.left.info.width = imWidth;
00231 
00232         wide_ctx_.right.info = wide_ctx_.right.manager->getCameraInfo();
00233         wide_ctx_.right.info.header.frame_id = wide_ctx_.frame_id;
00234         //wide_ctx_.right.info.header.stamp = stamp;
00235         wide_ctx_.right.info.height = imHeight;
00236         wide_ctx_.right.info.width = imWidth;
00237 
00238         wide_ctx_.left.publisher.publish(wide_ctx_.left.image, wide_ctx_.left.info, stamp);
00239         wide_ctx_.right.publisher.publish(wide_ctx_.right.image, wide_ctx_.right.info, stamp);
00240 }
00241 
00242 }
00243 ;
00244 
00245 #include <pluginlib/class_list_macros.h>
00246 PLUGINLIB_EXPORT_CLASS(lrm_camera_drivers::SplitXB3Nodelet, nodelet::Nodelet)


lrm_camera_drivers
Author(s): Rafael Luiz Klaser
autogenerated on Mon Oct 6 2014 01:52:55