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
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
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
00067 it.reset(new image_transport::ImageTransport(nh));
00068
00069
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
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
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 }
00148
00149 PLUGINLIB_DECLARE_CLASS(omnicamera, lady_saw, omnicamera::LadySawNodelet, nodelet::Nodelet)