orsens_node.cpp
Go to the documentation of this file.
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     // Initialize ROS
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     // Create a ROS publishers for the output messages
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); // 0-255
00108     ros::Publisher pub_depth = nh.advertise<sensor_msgs::Image> (camera_namespace+"depth", 1); // uint16 in mm
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                     // reset the point cloud
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); //output ROS message
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 }


orsens_ros
Author(s):
autogenerated on Sat Jun 8 2019 18:30:26