LadySawNodelet.cpp
Go to the documentation of this file.
00001 
00002 #include <boost/format.hpp>
00003 #include <boost/make_shared.hpp>
00004 
00005 #include <ros/ros.h>
00006 #include <nodelet/nodelet.h>
00007 #include <pluginlib/class_list_macros.h>
00008 #include <cv_bridge/cv_bridge.h>
00009 #include <image_transport/image_transport.h>
00010 #include <opencv2/opencv.hpp>
00011 #include <camera_info_manager/camera_info_manager.h>
00012 
00013 #include "omnicamera/LadySaw.h"
00014 
00015 //#define USE_MT_NODE_HANDLE
00016 
00017 using std::string;
00018 
00019 namespace omnicamera {
00020 
00021 const int N_CAMS = 6;
00022 
00023 class LadySawNodelet : public nodelet::Nodelet {
00024 public:
00025   LadySawNodelet();
00026   virtual void onInit();
00027   void imageCallback(const sensor_msgs::ImageConstPtr& msg);
00028 private:
00029   omnicamera::LadySaw ladySaw;
00030   vector<Mat> cams;
00031 
00032   // Camera names parametrized by whatever affects calibration, e.g. GUID, capture mode.
00033   vector<camera_info_manager::CameraInfoManager*> cameraInfoManagers;
00034   string frameIdFormat;
00038   boost::shared_ptr<image_transport::ImageTransport> it;
00039   image_transport::Subscriber imageSub;
00040   image_transport::Publisher outPubs[N_CAMS];
00041   ros::Publisher camPubs[N_CAMS];
00042 };
00043 
00044 LadySawNodelet::LadySawNodelet() {
00045 }
00046 
00047 void LadySawNodelet::onInit() {
00048   NODELET_INFO("Initializing LadySawNodelet...");
00049 #ifdef USE_MT_NODE_HANDLE
00050   ros::NodeHandle &nh = getMTNodeHandle();
00051   ros::NodeHandle &pnh = getMTPrivateNodeHandle();
00052 #else
00053   ros::NodeHandle &nh = getNodeHandle();
00054   ros::NodeHandle &pnh = getPrivateNodeHandle();
00055 #endif
00056 
00057   bool rotate;
00058   pnh.param("rotate", rotate, true);
00059   ladySaw.setRotate(rotate);
00060   int width, height;
00061   pnh.param("width", width, 1232);
00062   pnh.param("height", height, 1616);
00063   ladySaw.setWidth(width);
00064   ladySaw.setHeight(height);
00065 
00066 //  image_transport::ImageTransport it(nh);
00067   it.reset(new image_transport::ImageTransport(nh));
00068 
00069   // Get camera name and frame ID formats.
00070   string cameraNameFmtStr;
00071   pnh.param(string("camera_name_format"), cameraNameFmtStr, string("camera_%d"));
00072   boost::format cameraNameFmt(cameraNameFmtStr);
00073   pnh.param(string("frame_id_format"), frameIdFormat, string("camera_%d"));
00074 
00075   // Get camera info URL format, parameterized by camera name.
00076   string cameraInfoUrlFmtStr;
00077   pnh.param(string("camera_info_url_format"), cameraInfoUrlFmtStr, string("package://omnicamera/res/camera_info/%s.ini"));
00078   boost::format cameraInfoUrlFmt(cameraInfoUrlFmtStr);
00079 
00080   boost::format cameraNsFmt("camera_%i");
00081 
00082   for (int i = 0; i < N_CAMS; i++) {
00083     ros::NodeHandle cnh = ros::NodeHandle(nh, (cameraNsFmt % i).str());
00084     string cameraName = (cameraNameFmt % i).str();
00085     string cameraInfoUrl = (cameraInfoUrlFmt % cameraName).str();
00086     NODELET_INFO("Setting up camera info manager for %s, %s...", cameraName.data(), cameraInfoUrl.data());
00087     cameraInfoManagers.push_back(new camera_info_manager::CameraInfoManager(cnh, cameraName.data(), cameraInfoUrl.data()));
00088     string imageOutTopic = cnh.resolveName("image", true);
00089     string camInfoTopic = cnh.resolveName("camera_info", true);
00090     NODELET_INFO("Advertising topics %s and %s...", imageOutTopic.data(), camInfoTopic.data());
00091     outPubs[i] = it->advertise(imageOutTopic, 1);
00092     camPubs[i] = nh.advertise<sensor_msgs::CameraInfo>(camInfoTopic, 1);
00093   }
00094 
00095   string imageTopic = nh.resolveName("camera/image", true);
00096   NODELET_INFO("Subscribing to topic %s...", imageTopic.data());
00097   imageSub = it->subscribe(imageTopic, 1, &LadySawNodelet::imageCallback, this);
00098 }
00099 
00100 void LadySawNodelet::imageCallback(const sensor_msgs::ImageConstPtr& msg) {
00101 //  NODELET_INFO("Entering image callback...");
00102 
00103   vector<int> camsOut;
00104   for (int i = 0; i < N_CAMS; i++) {
00105     if (outPubs[i].getNumSubscribers() > 0 || camPubs[i].getNumSubscribers() > 0) {
00106       camsOut.push_back(i);
00107     }
00108   }
00109   if (camsOut.size() == 0) {
00110     return;
00111   }
00112   ladySaw.setCamsOut(camsOut);
00113 
00114   cv_bridge::CvImageConstPtr cvPtr;
00115   try {
00116     cvPtr = cv_bridge::toCvShare(msg);
00117   } catch (cv_bridge::Exception& e) {
00118     NODELET_ERROR("cv_bridge exception: %s", e.what());
00119     return;
00120   }
00121 
00122   NODELET_DEBUG("Sawing started.");
00123   ladySaw.saw(cvPtr->image, cams);
00124   NODELET_DEBUG("Sawing finished.");
00125 
00126   boost::format frameIdFmt(frameIdFormat);
00127   camsOut = ladySaw.getCamsOut();
00128   for (size_t i = 0; i < camsOut.size(); i++) {
00129     int iCam = camsOut[i];
00130     string frameId = (frameIdFmt % iCam).str();
00131 
00132     cv_bridge::CvImage out;
00133     out.encoding = cvPtr->encoding;
00134     out.header = msg->header;
00135     out.header.frame_id = frameId;
00136     out.image = cams[i];
00137     outPubs[iCam].publish(out.toImageMsg());
00138 
00139     sensor_msgs::CameraInfo camMsg = cameraInfoManagers[iCam]->getCameraInfo();
00140     camMsg.header = out.header;
00141     camMsg.height = out.image.rows;
00142     camMsg.width = out.image.cols;
00143     camPubs[iCam].publish(camMsg);
00144   }
00145 }
00146 
00147 } // namespace omnicamera
00148 
00149 PLUGINLIB_DECLARE_CLASS(omnicamera, lady_saw, omnicamera::LadySawNodelet, nodelet::Nodelet)
 All Classes Namespaces Files Functions Variables Typedefs Defines


omnicamera
Author(s): Tomas Petricek / petrito1@cmp.felk.cvut.cz
autogenerated on Tue Dec 10 2013 14:26:53