00001 #include <ros/ros.h>
00002 #include <ros/package.h>
00003 #include <opencv2/imgproc/imgproc.hpp>
00004 #include <opencv2/highgui/highgui.hpp>
00005
00006 #include <cv_bridge/cv_bridge.h>
00007 #include <sensor_msgs/image_encodings.h>
00008 #include <image_geometry/stereo_camera_model.h>
00009 #include <image_transport/image_transport.h>
00010 #include <sensor_msgs/Image.h>
00011 #include <stereo_msgs/DisparityImage.h>
00012 #include <std_msgs/Int32.h>
00013 #include <sensor_msgs/fill_image.h>
00014 #include <camera_info_manager/camera_info_manager.h>
00015 #include <sstream>
00016
00017 #include <pcl_conversions/pcl_conversions.h>
00018
00019 #include <signal.h>
00020
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <linux/videodev2.h>
00024 #include <stdint.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <sys/ioctl.h>
00028 #include <sys/mman.h>
00029 #include <unistd.h>
00030
00031 #include "orsens.h"
00032 #include <orsens/Obstacles.h>
00033 #include <orsens/Way.h>
00034
00035 using namespace cv;
00036 using namespace sensor_msgs;
00037 using namespace camera_info_manager;
00038
00040 CameraInfoManager *cinfo_left;
00041 CameraInfoManager *cinfo_right;
00042
00043 static Orsens orsens_device;
00044
00045 static bool working = false;
00046
00047 void sigint_handler(int sig)
00048 {
00049 working = false;
00050 delete cinfo_left;
00051 delete cinfo_right;
00052 orsens_device.stop();
00053 printf("stopped\n");
00054 ros::shutdown();
00055 }
00056
00057 int main (int argc, char** argv)
00058 {
00059
00060 ros::init (argc, argv, "orsens_node");
00061 ros::NodeHandle nh;
00062 string node_name = ros::this_node::getName();
00063
00064 string frame_id;
00065 string camera_namespace;
00066 string left_camera_info_url, right_camera_info_url;
00067 string capture_mode_string;
00068 string data_path;
00069 int color_width, depth_width;
00070 int color_rate, depth_rate;
00071 bool compress_color, compress_depth;
00072 bool publish_color, publish_disp, publish_depth, publish_cloud, publish_obstacles, publish_cam_info;
00073
00074 nh.param<string>(node_name+"/capture_mode", capture_mode_string, "depth_only");
00075 nh.param<string>(node_name+"/data_path", data_path, "data");
00076 nh.param<string>(node_name+"/left_camera_info_url", left_camera_info_url, "file://");
00077 nh.param<string>(node_name+"/right_camera_info_url", right_camera_info_url, "file://");
00078 nh.param<string>(node_name+"/frame_id", frame_id, "orsens_camera");
00079 nh.param<string>(node_name+"/camera_namespace", camera_namespace, "/orsens/");
00080 nh.param<int>(node_name+"/color_width", color_width, 640);
00081 nh.param<int>(node_name+"/depth_width", depth_width, 640);
00082 nh.param<int>(node_name+"/color_rate", color_rate, 15);
00083 nh.param<int>(node_name+"/depth_rate", depth_rate, 15);
00084 nh.param<bool>(node_name+"/compress_color", compress_color, false);
00085 nh.param<bool>(node_name+"/compress_depth", compress_depth, false);
00086 nh.param<bool>(node_name+"/publish_depth", publish_depth, true);
00087 nh.param<bool>(node_name+"/publish_cloud", publish_cloud, false);
00088 nh.param<bool>(node_name+"/publish_obstacles", publish_obstacles, false);
00089 bool pub_obstacle = true;
00090
00091 if(left_camera_info_url=="file://" || right_camera_info_url=="file://")
00092 publish_cam_info=false;
00093 else
00094 publish_cam_info=true;
00095
00096 Orsens::CaptureMode capture_mode = Orsens::captureModeFromString(capture_mode_string);
00097
00098 if (!orsens_device.start(capture_mode, data_path, color_width, depth_width, color_rate, depth_rate, compress_color, compress_depth))
00099 {
00100 ROS_ERROR("unable to start OrSens device, check connection\n");
00101 return -1;
00102 }
00103
00104
00105 ros::Publisher pub_left = nh.advertise<sensor_msgs::Image> (camera_namespace+"left/image_raw", 1);
00106 ros::Publisher pub_right = nh.advertise<sensor_msgs::Image> (camera_namespace+"right/image_raw", 1);
00107 ros::Publisher pub_disp = nh.advertise<sensor_msgs::Image> (camera_namespace+"disp", 1);
00108 ros::Publisher pub_depth = nh.advertise<sensor_msgs::Image> (camera_namespace+"depth", 1);
00109 ros::Publisher pub_left_info = nh.advertise<sensor_msgs::CameraInfo>(camera_namespace+"left/camera_info", 1);
00110 ros::Publisher pub_right_info = nh.advertise<sensor_msgs::CameraInfo>(camera_namespace+"right/camera_info", 1);
00111 ros::Publisher pub_cloud = nh.advertise<pcl::PCLPointCloud2>(camera_namespace+"cloud", 1);
00112 ros::Publisher pub_obs = nh.advertise<orsens::Obstacles>(camera_namespace+"obstacles", 1);
00113
00114 ros::Rate loop_rate(15);
00115
00116 sensor_msgs::Image ros_left, ros_right, ros_disp, ros_depth, ros_mask;
00117 sensor_msgs::CameraInfo l_info_msg, r_info_msg;
00118 orsens::Obstacles obs;
00119
00120 bool caminfo_loaded = false;
00121
00122 if (publish_cam_info)
00123 {
00124 cinfo_left = new CameraInfoManager(nh, "/orsens/left", left_camera_info_url);
00125 cinfo_right = new CameraInfoManager(nh, "/orsens/right", right_camera_info_url);
00126
00127 caminfo_loaded = cinfo_left->isCalibrated() && cinfo_right->isCalibrated();
00128 if (!caminfo_loaded)
00129 ROS_WARN("Failed to load calibration data, check path");
00130 else
00131 {
00132 ROS_INFO("Calibration data loaded\n");
00133
00134 l_info_msg.header.frame_id = frame_id;
00135
00136 l_info_msg.height = color_width*3/4;
00137 l_info_msg.width = color_width;
00138
00139 r_info_msg.header.frame_id = frame_id;
00140
00141 r_info_msg.height = color_width*3/4;
00142 r_info_msg.width = color_width;
00143 }
00144 }
00145
00146 working = true;
00147
00148 while (nh.ok() && working)
00149 {
00150 orsens_device.grabSensorData();
00151 orsens_device.filterDisp();
00152
00153 Mat left, right, disp, depth, cloud;
00154
00155 switch (capture_mode)
00156 {
00157 case Orsens::CAPTURE_DEPTH_ONLY:
00158 disp = orsens_device.getDisp();
00159 break;
00160
00161 case Orsens::CAPTURE_LEFT_ONLY:
00162 left = orsens_device.getLeft();
00163 break;
00164
00165 case Orsens::CAPTURE_DEPTH_LEFT:
00166 disp = orsens_device.getDisp();
00167 left = orsens_device.getLeft();
00168 break;
00169
00170 case Orsens::CAPTURE_LEFT_RIGHT:
00171 left = orsens_device.getLeft();
00172 right = orsens_device.getRight();
00173 break;
00174 }
00175
00176 ros::Time time = ros::Time::now();
00177
00178 if (caminfo_loaded)
00179 {
00180 if (publish_cam_info)
00181 {
00182 l_info_msg = cinfo_left->getCameraInfo();
00183 l_info_msg.header.frame_id = frame_id;
00184 l_info_msg.header.stamp = time;
00185 pub_left_info.publish(l_info_msg);
00186
00187 r_info_msg = cinfo_right->getCameraInfo();
00188 r_info_msg.header.frame_id = frame_id;
00189 r_info_msg.header.stamp = time;
00190 pub_right_info.publish(r_info_msg);
00191 }
00192 }
00193
00194 if (!left.empty())
00195 {
00196 fillImage(ros_left, "bgr8", left.rows, left.cols, left.step.buf[0], left.data);
00197
00198 ros_left.header.stamp = time;
00199 ros_left.header.frame_id = frame_id;
00200
00201 pub_left.publish(ros_left);
00202 }
00203
00204 if (!right.empty())
00205 {
00206 fillImage(ros_right, "bgr8", right.rows, right.cols, right.step.buf[0], right.data);
00207
00208 ros_right.header.stamp = time;
00209 ros_right.header.frame_id = frame_id;
00210
00211 pub_right.publish(ros_right);
00212 }
00213
00214 if (!disp.empty())
00215 {
00216 fillImage(ros_disp, "mono8", disp.rows, disp.cols, disp.cols, disp.data);
00217
00218 ros_disp.header.stamp = time;
00219 ros_disp.header.frame_id = frame_id;
00220
00221 pub_disp.publish(ros_disp);
00222
00223 if (publish_depth)
00224 {
00225 Mat depth = orsens_device.getDepth();
00226 if (!depth.empty())
00227 {
00228 fillImage(ros_depth, "16UC1", depth.rows, depth.cols, 2*depth.cols, depth.data);
00229
00230 ros_depth.header.stamp = time;
00231 ros_depth.header.frame_id = frame_id;
00232
00233 pub_depth.publish(ros_depth);
00234 }
00235 }
00236
00237 if (publish_cloud)
00238 {
00239 Mat cloud = orsens_device.getPointCloud();
00240 if (!cloud.empty())
00241 {
00242 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudOut (new pcl::PointCloud<pcl::PointXYZRGB>);
00243
00244
00245 cloudOut->clear();
00246 cloudOut->width = cloud.cols;
00247 cloudOut->height = cloud.rows;
00248 cloudOut->points.resize(cloudOut->width * cloudOut->height);
00249
00250 float px, py, pz;
00251 uchar pb=0, pr=0, pg=0;
00252 int index = 0;
00253
00254 for (int y=0; y<cloud.rows; y++)
00255 for (int x=0; x<cloud.cols; x++)
00256 {
00257
00258 px = cloud.at<cv::Vec3f>(y,x)[0];
00259 py = cloud.at<cv::Vec3f>(y,x)[1];
00260 pz = cloud.at<cv::Vec3f>(y,x)[2];
00261
00262 if (!left.empty())
00263 {
00264 pb = left.at<cv::Vec3b>(y,x)[0];
00265 pg = left.at<cv::Vec3b>(y,x)[1];
00266 pr = left.at<cv::Vec3b>(y,x)[2];
00267 }
00268
00269 cloudOut->points[index].x = px;
00270 cloudOut->points[index].y = py;
00271 cloudOut->points[index].z = pz;
00272 cloudOut->points[index].r = pr;
00273 cloudOut->points[index].g = pg;
00274 cloudOut->points[index].b = pb;
00275
00276 index ++;
00277 }
00278
00279 pcl::PCLPointCloud2::Ptr cloudOutROS(new pcl::PCLPointCloud2);
00280 pcl::toPCLPointCloud2 (*cloudOut, *cloudOutROS);
00281 cloudOutROS->header.frame_id = frame_id;
00282 pub_cloud.publish(cloudOutROS);
00283 }
00284 }
00285
00286 if(publish_obstacles)
00287 {
00288 if(pub_obstacle)
00289 {
00290 SceneInfo scene_info = orsens_device.getSceneInfo();
00291 obs.u = scene_info.nearest_obstacle.centre.x;
00292 obs.v = scene_info.nearest_obstacle.centre.y;
00293 obs.centre_pt.x = scene_info.nearest_obstacle.centre_world.x;
00294 obs.centre_pt.y = scene_info.nearest_obstacle.centre_world.y;
00295 obs.centre_pt.z = scene_info.nearest_obstacle.centre_world.z;
00296 obs.dist = scene_info.nearest_obstacle.dist;
00297 obs.angle = scene_info.nearest_obstacle.angle;
00298 obs.min_pt.x = scene_info.nearest_obstacle.min_pt_world.x;
00299 obs.min_pt.y = scene_info.nearest_obstacle.min_pt_world.y;
00300 obs.min_pt.z = scene_info.nearest_obstacle.min_pt_world.z;
00301 obs.max_pt.x = scene_info.nearest_obstacle.max_pt_world.x;
00302 obs.max_pt.y = scene_info.nearest_obstacle.max_pt_world.y;
00303 obs.max_pt.z = scene_info.nearest_obstacle.max_pt_world.z;
00304 }
00305 else
00306 {
00307 SceneInfo scene_info = orsens_device.getSceneInfo(false);
00308
00309 obs.u = scene_info.nearest_point.pt_image.x;
00310 obs.v = scene_info.nearest_point.pt_image.y;
00311 obs.centre_pt.x = scene_info.nearest_point.pt_world.x;
00312 obs.centre_pt.y = scene_info.nearest_point.pt_world.y;
00313 obs.centre_pt.z = scene_info.nearest_point.pt_world.z;
00314 }
00315
00316 obs.header.stamp = time;
00317 obs.header.frame_id = "orsens_camera";
00318 pub_obs.publish(obs);
00319 }
00320
00321 }
00322
00323 ros::spinOnce();
00324 loop_rate.sleep();
00325 }
00326
00327 sigint_handler(0);
00328
00329 }