virtual_camera2.cpp
Go to the documentation of this file.
00001 
00019 #include <cv_bridge/CvBridge.h>
00020 #include <GL/glew.h> // glew.h must be included before gl.h
00021 #include <GL/gl.h>
00022 #include <GL/glut.h>
00023 #include <image_transport/image_transport.h>
00024 #include <math.h>
00025 #include <opencv2/core/core.hpp>
00026 #include <opencv2/highgui/highgui.hpp>
00027 #include <ros/ros.h>
00028 #include <sys/param.h>
00029 #include <sys/times.h>
00030 
00031 #include "LadybugCamera.h"
00032 #include "LadybugVirtualCamera.h"
00033 #include "omnicamera_msgs/GetVirtualCameraConfig.h"
00034 #include "omnicamera_msgs/VirtualCameraConfig.h"
00035 
00036 using std::string;
00037 
00038 using nifti::ladybug::LadybugVirtualCamera;
00039 using omnicamera_msgs::GetVirtualCameraConfig;
00040 using omnicamera_msgs::VirtualCameraConfig;
00041 
00042 namespace {
00046 LadybugVirtualCamera virtualCamera;
00050 VirtualCameraConfig virtualCameraConfig;
00055 double imageUpdateInterval = 5.0;
00056 long lastImageUpdate = 0l;
00057 sensor_msgs::CvBridge bridge;
00062 bool viewChanged = false;
00063 
00064 // For measuring cpu time.
00065 struct tms t1, t2;
00066 long r1 = 0l, r2 = 0l;
00067 
00071 bool
00072 getVirtualCameraConfigService(GetVirtualCameraConfig::Request& request, GetVirtualCameraConfig::Response& response);
00076 void virtualCameraConfigCallback(const VirtualCameraConfig::ConstPtr& msg);
00080 void imageCallback(const sensor_msgs::ImageConstPtr &msg);
00081 void startDuration();
00086 void logDuration(char* message);
00087 }
00088 
00089 int main(int argc, char** argv) {
00090 
00091   ros::init(argc, argv, "virtual_camera2");
00092   ros::NodeHandle nodeHandle;
00093 
00094   for (int i = 0; i < argc; i++) {
00095     printf("%d: %s\n", i, argv[i]);
00096   }
00097 
00098   // Check and parse command-line arguments.
00099   string meshFile;
00100   string alphamaskPrefix;
00101   if (argc < 3) {
00102     printf("Not enough arguments.\n");
00103     printf("Usage:   virtual_camera_filter <mesh file path> <alphamask file prefix>\n");
00104     printf("Example: virtual_camera_filter mesh.txt alphamask\n");
00105     return -1;
00106   } else {
00107     meshFile = string(argv[1]);
00108     alphamaskPrefix = string(argv[2]);
00109     glutInit(&argc, argv);
00110   }
00111 
00112   // Setup virtual camera config topic and service.
00113   ros::Subscriber virtualCameraConfigSubscriber;
00114   ros::ServiceServer getVirtualCameraConfigServer;
00115   virtualCameraConfigSubscriber = nodeHandle.subscribe("virtual_camera/config", 1, virtualCameraConfigCallback);
00116   getVirtualCameraConfigServer
00117       = nodeHandle.advertiseService("virtual_camera/get_config", getVirtualCameraConfigService);
00118 
00119   image_transport::ImageTransport it(nodeHandle);
00120   // Advertise virtual camera view.
00121   image_transport::Publisher virtualCameraPub = it.advertise("virtual_camera/image", 1);
00122   // Subscribe to composite images to be used in rendering virtual camera view.
00123   image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);
00124 
00125   try {
00126     uint32_t seq = 0;
00127     virtualCamera.initialize(true);
00128     virtualCamera.loadMesh(meshFile);
00129     virtualCamera.loadAlphamask(alphamaskPrefix);
00130 
00131     while (nodeHandle.ok()) {
00132       // No synchronization needed since only one thread is used
00133       // both for callback processing and virtual camera rendering.
00134       // Process all pending callbacks.
00135       ros::spinOnce();
00136 
00137       if (viewChanged && virtualCameraPub.getNumSubscribers() > 0) {
00138         ROS_INFO("Rendering virtual camera view...");
00139         cv::Mat virtualCameraView;
00140         startDuration();
00141         virtualCamera.renderView(virtualCameraView);
00142         logDuration("Rendering view");
00143 
00144 //        IplImage iplImage = virtualCameraView;
00145         IplImage iplImage = virtualCameraView.operator _IplImage();
00146 //        sensor_msgs::ImagePtr msg = bridge.cvToImgMsg(&iplImage, "bgr8");
00147         sensor_msgs::ImagePtr msg = bridge.cvToImgMsg(&iplImage);
00148         msg->header.frame_id = "tfladylink";
00149         msg->header.seq = seq++;
00150         msg->header.stamp = ros::Time::now();
00151 
00152         startDuration();
00153         virtualCameraPub.publish(msg);
00154         logDuration("Publishing images");
00155 
00156         viewChanged = false;
00157       }
00158     }
00159   } catch (std::runtime_error& e) {
00160     ROS_ERROR("Runtime error: %s", e.what());
00161     return -1;
00162   } catch (...) {
00163     ROS_ERROR("Unexpected exception occurred.");
00164     return -1;
00165   }
00166 
00167   return 0;
00168 }
00169 
00170 namespace {
00171 
00172 void imageCallback(const sensor_msgs::ImageConstPtr &msg) {
00173   struct tms t;
00174   long r;
00175   r = times(&t);
00176   double sinceLastUpdate = (double) (r - lastImageUpdate) / HZ;
00177   if (sinceLastUpdate >= imageUpdateInterval) {
00178     try {
00179       IplImage* iplImg = bridge.imgMsgToCv(msg, "bgr8");
00180 //      IplImage* iplImg = bridge.imgMsgToCv(msg);
00181 //      IplImage* iplImg = sensor_msgs::CvBridge::imgMsgToCv(msg);
00182 
00183       cv::Mat composite(iplImg);
00184 
00185       startDuration();
00186       virtualCamera.setImages(composite);
00187       logDuration("Updating virtual camera images");
00188     } catch (sensor_msgs::CvBridgeException& e) {
00189       ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
00190     }
00191     lastImageUpdate = r;
00192     viewChanged = true;
00193   }
00194 }
00195 
00196 bool getVirtualCameraConfigService(GetVirtualCameraConfig::Request& request, GetVirtualCameraConfig::Response& response) {
00197   ROS_DEBUG("getVirtualCameraConfigService called");
00198   // There is nothing interesting in the request...
00199   // Fill the response with current values.
00200 
00201   int viewportWidth, viewportHeight;
00202   virtualCamera.getViewport(&viewportWidth, &viewportHeight);
00203   response.config.viewportWidth = viewportWidth;
00204   response.config.viewportHeight = viewportHeight;
00205   response.config.pan = virtualCamera.getPan();
00206   response.config.tilt = virtualCamera.getTilt();
00207   response.config.horizontalFov = virtualCamera.getHorizontalFov();
00208   response.config.verticalFov = virtualCamera.getVerticalFov();
00209 
00210   response.config.imageUpdateInterval = imageUpdateInterval;
00211 
00212   return true;
00213 }
00214 
00215 void virtualCameraConfigCallback(const VirtualCameraConfig::ConstPtr& msg) {
00216   ROS_DEBUG("virtualCameraConfigCallback called");
00217 
00218   virtualCamera.setViewport(msg->viewportWidth, msg->viewportHeight);
00219   virtualCamera.setPan(msg->pan);
00220   virtualCamera.setTilt(msg->tilt);
00221   virtualCamera.setHorizontalFov(msg->horizontalFov);
00222   virtualCamera.setVerticalFov(msg->verticalFov);
00223 
00224   imageUpdateInterval = msg->imageUpdateInterval;
00225 
00226   viewChanged = true;
00227 }
00228 
00229 void startDuration() {
00230   r1 = times(&t1);
00231 }
00232 
00233 void logDuration(char* message) {
00234   r2 = times(&t2);
00235 
00236   float userTime = ((float) (t2.tms_utime - t1.tms_utime)) / HZ;
00237   float systemTime = ((float) (t2.tms_stime - t1.tms_stime)) / HZ;
00238   float realTime = ((float) (r2 - r1)) / HZ;
00239 
00240   std::string format = "%s: real time: %1.2f, user time: %1.2f, system time: %1.2f";
00241   ROS_DEBUG(format.data(), message, realTime, userTime, systemTime);
00242 }
00243 
00244 }
 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