00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 {
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 {
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;
00132 narrow_left_image.width = cols_arg;
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;
00138 narrow_right_image.width = cols_arg;
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;
00144 wide_left_image.width = cols_arg;
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;
00150 wide_right_image.width = cols_arg;
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
00163 while (k > 0) {
00164
00165
00166
00167
00168
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::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
00197 ros::Time stamp = image.header.stamp;
00198
00199
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
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
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
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
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
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)