driver_nodelet.cpp
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*
00003  * Copyright (c) 2014 individual JSK Lab members.
00004  *
00005  * This code is licensed to you under the terms of the Apache License, version
00006  * 2.0, or, at your option, the terms of the GNU General Public License,
00007  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
00008  * or the following URLs:
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  * http://www.gnu.org/licenses/gpl-2.0.txt
00011  *
00012  * If you redistribute this file in source form, modified or unmodified, you
00013  * may:
00014  *   1) Leave this header intact and distribute it under the same terms,
00015  *      accompanying it with the APACHE20 and GPL20 files, or
00016  *   2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
00017  *   3) Delete the GPL v2 clause and accompany it with the APACHE20 file
00018  * In all cases you must keep the copyright notice intact and include a copy
00019  * of the CONTRIB file.
00020  *
00021  * Binary distributions must follow the binary distribution requirements of
00022  * either License.
00023  */
00024 
00025 #include "jsk_libfreenect2/driver.h"
00026 #include <cv_bridge/cv_bridge.h>
00027 #include <std_msgs/Header.h>
00028 #include <sensor_msgs/distortion_models.h>
00029 #include <limits>
00030 #include <boost/tuple/tuple.hpp>
00031 #include <boost/tuple/tuple_io.hpp>
00032 
00033 namespace jsk_libfreenect2
00034 {
00035   void Driver::onInit()
00036   {
00037     glfwInit();
00038     timer_ = getNodeHandle().createTimer(
00039       ros::Duration(5.0),
00040       boost::bind(&Driver::run, this, _1), true);
00041   }
00042   
00043   void Driver::run(const ros::TimerEvent&) {
00044     freenect2_ = new libfreenect2::Freenect2();
00045     dev_ = freenect2_->openDefaultDevice();
00046     if (dev_ == 0)
00047     {
00048       NODELET_FATAL("[Driver::run] no device connected");
00049       return;
00050     }
00051     listener_ = new libfreenect2::SyncMultiFrameListener(
00052       libfreenect2::Frame::Color |
00053       libfreenect2::Frame::Ir |
00054       libfreenect2::Frame::Depth);
00055     dev_->setColorFrameListener(listener_);
00056     dev_->setIrAndDepthFrameListener(listener_);
00057     dev_->start();
00058     NODELET_INFO_STREAM("[Driver::run] device serial: "
00059                         << dev_->getSerialNumber());
00060     NODELET_INFO_STREAM("[Driver::run] device firmware: "
00061                         << dev_->getFirmwareVersion());
00062 
00063     
00064     
00065     ros::NodeHandle nh = getNodeHandle();
00066     ros::NodeHandle pnh = getPrivateNodeHandle();
00067     image_transport::ImageTransport it(pnh);
00068     ros::NodeHandle rgb_nh(nh, "rgb");
00069     image_transport::ImageTransport rgb_it(rgb_nh);
00070     ros::NodeHandle ir_nh(nh, "ir");
00071     image_transport::ImageTransport ir_it(ir_nh);
00072     ros::NodeHandle depth_nh(nh, "depth");
00073     image_transport::ImageTransport depth_it(depth_nh);
00074     ros::NodeHandle depth_registered_nh(nh, "depth_registered");
00075     image_transport::ImageTransport depth_registered_it(depth_registered_nh);
00076     ros::NodeHandle projector_nh(nh, "projector");
00077     
00078     // read parameters
00079     // std::string rgb_camera_info_url, depth_camera_info_url;
00080     // pnh.param("rgb_camera_info_url", rgb_camera_info_url, std::string());
00081     // pnh.param("depth_camera_info_url", depth_camera_info_url, std::string());
00082 
00083     std::string rgb_frame_id, depth_frame_id;
00084     pnh.param("rgb_frame_id",   rgb_frame_id,   std::string("/openni_rgb_optical_frame"));
00085     pnh.param("depth_frame_id", depth_frame_id, std::string("/openni_depth_optical_frame"));
00086 
00087     default_rgb_params_ = dev_->getColorCameraParams();
00088     default_ir_params_ = dev_->getIrCameraParams();
00089     // rgb_caminfo_manager_ = boost::make_shared<camera_info_manager::CameraInfoManager>(
00090     //   rgb_nh, "rgb", rgb_camera_info_url);
00091     // ir_caminfo_manager_  = boost::make_shared<camera_info_manager::CameraInfoManager>(
00092     //   ir_nh,  "depth",  depth_camera_info_url);
00093     // if (!rgb_caminfo_manager_->isCalibrated())
00094     //   NODELET_WARN("Using default parameters for RGB camera calibration.");
00095     // if (!ir_caminfo_manager_->isCalibrated())
00096     //   NODELET_WARN("Using default parameters for IR/depth camera calibration.");
00097     
00098     libfreenect2::FrameMap frames;
00099     image_transport::CameraPublisher depth_pub
00100       = depth_it.advertiseCamera("image_raw", 1);
00101     image_transport::CameraPublisher ir_pub
00102       = ir_it.advertiseCamera("image_raw", 1);
00103     image_transport::CameraPublisher color_pub
00104       = rgb_it.advertiseCamera("image_raw", 1);
00105     
00106     while(ros::ok())
00107     {
00108       listener_->waitForNewFrame(frames);
00109       {
00110         boost::mutex::scoped_lock lock(mutex_);
00111         libfreenect2::Frame *rgb = frames[libfreenect2::Frame::Color];
00112         libfreenect2::Frame *ir = frames[libfreenect2::Frame::Ir];
00113         libfreenect2::Frame *depth = frames[libfreenect2::Frame::Depth];
00114         cv::Mat cvrgb(rgb->height, rgb->width, CV_8UC3, rgb->data);
00115         cv::Mat cvir(ir->height, ir->width, CV_32FC1, ir->data);
00116         cv::Mat cvdepth(depth->height, depth->width, CV_32FC1, depth->data);
00117         
00118         // int count = 0;
00119         // for (int i = 0; i < cvir.cols; i++) {
00120         //   for (int j = 0; j < cvir.rows; j++) {
00121         //     if (cvir.at<float>(j, i) == 65535) {
00122         //       NODELET_INFO("[%d, %d] is limit: %f", i, j, cvir.at<float>(j, i));
00123         //       ++count;
00124         //     }
00125         //   }
00126         // }
00127         // NODELET_INFO("%d limit", count);
00128         // quick hack
00129         // [76, 345], [82, 354], [103, 383], [212, 20], [340, 403], [479, 150]
00130         // is broken
00131         // std::vector<boost::tuple<int, int> > forbidden_pixels;
00132         // forbidden_pixels.push_back(boost::make_tuple(76, 345));
00133         // forbidden_pixels.push_back(boost::make_tuple(82, 354));
00134         // forbidden_pixels.push_back(boost::make_tuple(103, 383));
00135         // forbidden_pixels.push_back(boost::make_tuple(212, 20));
00136         // forbidden_pixels.push_back(boost::make_tuple(340, 403));
00137         // forbidden_pixels.push_back(boost::make_tuple(479, 150));
00138         // for (size_t i = 0; i < forbidden_pixels.size(); i++) {
00139         //   boost::tuple<int, int> pixel = forbidden_pixels[i];
00140         //   cvir.at<float>(pixel.get<1>(), pixel.get<0>()) = 0;
00141         // }
00142         
00143         ros::Time stamp = ros::Time::now();
00144         std_msgs::Header rgb_header, ir_header;
00145         rgb_header.stamp = stamp;
00146         ir_header.stamp = stamp;
00147         rgb_header.frame_id = rgb_frame_id;
00148         ir_header.frame_id = depth_frame_id;
00149         cv_bridge::CvImage rgb_cvimage(rgb_header, "bgr8", cvrgb);
00150         color_pub.publish(rgb_cvimage.toImageMsg(), getRGBCameraInfo(rgb, stamp, rgb_frame_id));
00151 
00152         // cv_bridge::CvImage depth_cvimage(ir_header, "16UC1", cvdepth / 1000.0);
00153         cv_bridge::CvImage depth_cvimage(ir_header, "32FC1", cvdepth / 1000.0);
00154         depth_pub.publish(depth_cvimage.toImageMsg(), getIRCameraInfo(depth, stamp, depth_frame_id));
00155 
00156 
00157         cv_bridge::CvImage ir_cvimage(ir_header, "32FC1", cvir / 1000.0);
00158         ir_pub.publish(ir_cvimage.toImageMsg(), getIRCameraInfo(ir, stamp, depth_frame_id));
00159         
00160         int key = cv::waitKey(1);
00161         listener_->release(frames);
00162       }
00163     }
00164     dev_->stop();
00165     dev_->close();
00166   }
00167 
00168   sensor_msgs::CameraInfo::Ptr Driver::getIRCameraInfo(
00169     libfreenect2::Frame* frame, ros::Time stamp, std::string frame_id)
00170   {
00171     if (ir_caminfo_manager_ && ir_caminfo_manager_->isCalibrated()) {
00172       sensor_msgs::CameraInfo info = ir_caminfo_manager_->getCameraInfo();
00173       info.header.stamp = stamp;
00174       info.header.frame_id = frame_id;
00175       return boost::make_shared<sensor_msgs::CameraInfo>(info);
00176     }
00177     else {
00178       sensor_msgs::CameraInfo info;
00179       info.width = frame->width;
00180       info.height = frame->height;
00181       info.header.stamp = stamp;
00182       info.header.frame_id = frame_id;
00183       info.D.resize(5, 0.0);
00184       info.K.assign(0.0);
00185       info.R.assign(0.0);
00186       info.P.assign(0.0);
00187       info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00188       info.D[0] = default_ir_params_.k1;
00189       info.D[1] = default_ir_params_.k2;
00190       info.D[2] = default_ir_params_.p1;
00191       info.D[3] = default_ir_params_.p2;
00192       info.D[4] = default_ir_params_.k3;
00193       info.K[0] = info.P[0] = default_ir_params_.fx;
00194       info.K[2] = info.P[2] = default_ir_params_.cx;
00195       info.K[4] = info.P[5] = default_ir_params_.fy;
00196       info.K[5] = info.P[6] = default_ir_params_.cy;
00197       info.K[8] = info.P[10] = 1.0;
00198       
00199       info.R[0] = info.R[4] = info.R[8] = 1.0;
00200       return boost::make_shared<sensor_msgs::CameraInfo>(info);
00201     }
00202   }
00203   
00204   sensor_msgs::CameraInfo::Ptr Driver::getRGBCameraInfo(
00205     libfreenect2::Frame* frame, ros::Time stamp, std::string frame_id)
00206   {
00207     if (rgb_caminfo_manager_ && rgb_caminfo_manager_->isCalibrated()) {
00208       sensor_msgs::CameraInfo info = rgb_caminfo_manager_->getCameraInfo();
00209       info.header.stamp = stamp;
00210       info.header.frame_id = frame_id;
00211       return boost::make_shared<sensor_msgs::CameraInfo>(info);
00212     }
00213     else {
00214       sensor_msgs::CameraInfo info;
00215       info.width = frame->width;
00216       info.height = frame->height;
00217       info.header.stamp = stamp;
00218       info.header.frame_id = frame_id;
00219       info.D.resize(5, 0.0);
00220       info.K.assign(0.0);
00221       info.R.assign(0.0);
00222       info.P.assign(0.0);
00223       info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00224       
00225       info.K[0] = info.P[0] = default_rgb_params_.fx;
00226       info.K[2] = info.P[2] = default_rgb_params_.cx;
00227       info.K[4] = info.P[5] = default_rgb_params_.fy;
00228       info.K[5] = info.P[6] = default_rgb_params_.cy;
00229       info.K[8] = info.P[10] = 1.0;
00230       
00231       info.R[0] = info.R[4] = info.R[8] = 1.0;
00232       return boost::make_shared<sensor_msgs::CameraInfo>(info);
00233     }
00234   }
00235 
00236 }
00237 
00238 #include <pluginlib/class_list_macros.h>
00239 typedef jsk_libfreenect2::Driver Driver;
00240 PLUGINLIB_DECLARE_CLASS (jsk_libfreenect2, Driver, Driver, nodelet::Nodelet);
00241 


jsk_libfreenect2
Author(s):
autogenerated on Mon Oct 6 2014 01:17:55