CameraHandler.cpp
Go to the documentation of this file.
00001 
00002 #include <pluginlib/class_list_macros.h>
00003 #include <camera_handler/CameraHandler.h>
00004 #include <v_repLib.h>
00005 #include <vrep_ros_plugin/access.h>
00006 
00007 #include <sensor_msgs/Image.h>
00008 #include <sensor_msgs/image_encodings.h>
00009 #include <sensor_msgs/distortion_models.h>
00010 
00011 #include <vrep_ros_plugin/ConsoleHandler.h>
00012 
00013 
00014 
00015 CameraHandler::CameraHandler() : GenericObjectHandler(),
00016 _acquisitionFrequency(30.0),
00017 _lastPublishedImageTime(0.0),
00018 _cameraIsRGB(true),
00019 _cameraHasDepth(false),
00020 _cameraIsFloat(false),
00021 _it(_nh){
00022 }
00023 
00024 CameraHandler::~CameraHandler(){
00025 }
00026 
00027 unsigned int CameraHandler::getObjectType() const {
00028         return CustomDataHeaders::CAMERA_DATA_MAIN;
00029 }
00030 
00031 void CameraHandler::synchronize(){
00032 
00033         _associatedObjectName = simGetObjectName(_associatedObjectID);
00034 
00035 }
00036 
00037 void CameraHandler::handleSimulation(){
00038         // called when the main script calls: simHandleModule
00039         if(!_initialized){
00040                 _initialize();
00041         }
00042 
00043         ros::Time now = ros::Time::now();
00044 
00045 
00046         const simFloat currentSimulationTime = simGetSimulationTime();
00047 
00048         if ((currentSimulationTime-_lastPublishedImageTime) >= 1.0/_acquisitionFrequency){
00049 
00050                 int resol[2];
00051 
00052                 if(simHandleVisionSensor(_associatedObjectID,NULL,NULL)!=-1 &&
00053                                 simGetVisionSensorResolution(_associatedObjectID,resol)!=-1){
00054 
00055                         // Populate the sensor_msgs::Image message
00056                         sensor_msgs::Image image_msg;
00057                         image_msg.header.stamp = now;
00058 
00059                         std::string frame_id=_associatedObjectName;
00060                         if (frame_id[0] != '/'){
00061                                 frame_id = "/" + frame_id;
00062                         }
00063 
00064                         image_msg.header.frame_id = frame_id;
00065 
00066 
00067                         //            char* cameraName = new(char[_associatedObjectName.size()]);
00068                         //            memcpy(cameraName,_associatedObjectName.c_str(),_associatedObjectName.size()*sizeof(char));
00069                         //            simReleaseBuffer(cameraName);
00070 
00071                         image_msg.width=resol[0]; //Set the width of the image
00072                         image_msg.height=resol[1]; //Set the height of the image
00073                         image_msg.is_bigendian=0;
00074 
00075                         if (_cameraIsFloat){
00076                                 if(_cameraIsRGB){
00077                                         image_msg.encoding=sensor_msgs::image_encodings::TYPE_32FC3;
00078                                 } else {
00079                                         image_msg.encoding=sensor_msgs::image_encodings::TYPE_32FC1;
00080                                 }
00081                         } else {
00082                                 if(_cameraIsRGB){
00083                                         image_msg.encoding=sensor_msgs::image_encodings::RGB8; //Set the format to be RGB with 8bits per channel
00084                                 } else {
00085                                         image_msg.encoding=sensor_msgs::image_encodings::MONO8;
00086                                 }
00087                         }
00088 
00089                         const unsigned int pixPerLine = image_msg.width*sensor_msgs::image_encodings::numChannels(image_msg.encoding);
00090                         image_msg.step=pixPerLine*sensor_msgs::image_encodings::bitDepth(image_msg.encoding)/8; //Set the image stride in bytes
00091                         image_msg.data.resize(image_msg.step*image_msg.height);
00092 
00093                         if (_cameraIsRGB){
00094                                 if(_cameraIsFloat){
00095                                         const simFloat* image_buf = simGetVisionSensorImage(_associatedObjectID);
00096                                         simFloat* image_msg_pt = (simFloat*)(image_msg.data.data());
00097                                         for(unsigned int i=0; i<image_msg.height; ++i){
00098                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00099                                                         image_msg_pt[i*pixPerLine+j] = image_buf[(image_msg.height-i-1)*pixPerLine+j];
00100                                                 }
00101                                         }
00102                                         simReleaseBuffer((simChar*)image_buf);
00103                                 } else {
00104                                         const simUChar* image_buf = simGetVisionSensorCharImage(_associatedObjectID, resol, resol+1);
00105                                         simUChar* image_msg_pt = static_cast<simUChar*>(image_msg.data.data());
00106                                         for(unsigned int i=0; i<image_msg.height; ++i){
00107                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00108                                                         image_msg_pt[i*pixPerLine+j] = image_buf[(image_msg.height-i-1)*pixPerLine+j];
00109                                                 }
00110                                         }
00111                                         simReleaseBuffer((simChar*)image_buf);
00112                                 }
00113                         } else {
00114                                 if (_cameraIsFloat){                                    
00115                                         simFloat* image_msg_pt = (simFloat*)(image_msg.data.data());
00116 #if VREP_VERSION_MAJOR*10000 + VREP_VERSION_MINOR*100 + VREP_VERSION_PATCH < 3*10000 + 3*100 + 1
00117                                         const simFloat* image_buf = simGetVisionSensorImage(_associatedObjectID);
00118                                         for(unsigned int i=0; i<image_msg.height; ++i){
00119                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00120                                                         image_msg_pt[i*pixPerLine+j] = image_buf[3*((image_msg.height-i-1)*pixPerLine+j)]*0.2126f + 
00121                                                                 image_buf[3*((image_msg.height-i-1)*pixPerLine+j)+1]*0.7152f +
00122                                                                 image_buf[3*((image_msg.height-i-1)*pixPerLine+j)+2]*0.0722f;
00123                                                 }
00124                                         }
00125 #else
00126                                         const simFloat* image_buf = simGetVisionSensorImage(_associatedObjectID+sim_handleflag_greyscale);
00127                                         for(unsigned int i=0; i<image_msg.height; ++i){
00128                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00129                                                         image_msg_pt[i*pixPerLine+j] = image_buf[(image_msg.height-i-1)*pixPerLine+j];
00130                                                 }
00131                                         }
00132 #endif
00133                                         simReleaseBuffer((simChar*)image_buf);
00134                                 } else {
00135                                         simUChar* image_msg_pt = static_cast<simUChar*>(image_msg.data.data());
00136 #if VREP_VERSION_MAJOR*10000 + VREP_VERSION_MINOR*100 + VREP_VERSION_PATCH < 3*10000 + 3*100 + 1
00137                                         const simUChar* image_buf = simGetVisionSensorCharImage(_associatedObjectID, resol, resol+1);
00138                                         for(unsigned int i=0; i<image_msg.height; ++i){
00139                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00140                                                         image_msg_pt[i*pixPerLine+j] = (simUChar)((float)image_buf[3*((image_msg.height-i-1)*pixPerLine+j)]*0.2126f + 
00141                                                                 (float)image_buf[3*((image_msg.height-i-1)*pixPerLine+j)+1]*0.7152f +
00142                                                                 (float)image_buf[3*((image_msg.height-i-1)*pixPerLine+j)+2]*0.0722f);
00143                                                 }
00144                                         }
00145 #else
00146                                         const simUChar* image_buf = simGetVisionSensorCharImage(_associatedObjectID+sim_handleflag_greyscale, resol, resol+1);
00147                                         for(unsigned int i=0; i<image_msg.height; ++i){
00148                                                 for(unsigned int j=0; j<pixPerLine; ++j){
00149                                                         image_msg_pt[i*pixPerLine+j] = image_buf[(image_msg.height-i-1)*pixPerLine+j];
00150                                                 }
00151                                         }
00152 #endif
00153                                         simReleaseBuffer((simChar*)image_buf);
00154                                 }
00155                         }
00156 
00157 
00158                         _camera_info.header.stamp = now;
00159                         _pubIT.publish(image_msg, _camera_info, now);
00160 
00161                         // Publish depth map. Mind that it reuses the same image message
00162                         if(_cameraHasDepth){
00163                                 simFloat clipping[2];
00164                                 simGetObjectFloatParameter(_associatedObjectID, sim_visionfloatparam_near_clipping, clipping);
00165                                 simGetObjectFloatParameter(_associatedObjectID, sim_visionfloatparam_far_clipping, clipping+1);
00166                                 sensor_msgs::Image depth_msg;
00167                                 depth_msg.header.stamp = now;
00168                                 depth_msg.header.frame_id = frame_id;
00169                                 depth_msg.width=resol[0]; //Set the width of the image
00170                                 depth_msg.height=resol[1]; //Set the height of the image
00171                                 depth_msg.is_bigendian=0;
00172                                 depth_msg.encoding=sensor_msgs::image_encodings::TYPE_32FC1;
00173                                 depth_msg.step=depth_msg.width*sensor_msgs::image_encodings::bitDepth(depth_msg.encoding)/8;
00174                                 depth_msg.data.resize(depth_msg.height*depth_msg.step);
00175                                 const simFloat* depth_buf = simGetVisionSensorDepthBuffer(_associatedObjectID);
00176                                 simFloat* depth_img = reinterpret_cast<simFloat*>(depth_msg.data.data());
00177 
00178                                 for (unsigned int i = 0; i < depth_msg.height; ++i){
00179                                         for (unsigned int j = 0; j < depth_msg.width; ++j){
00180                                                 depth_img[i*depth_msg.width+j] = clipping[0] + (clipping[1] - clipping[0])*depth_buf[(depth_msg.height-i-1)*depth_msg.width+j];
00181                                         }
00182                                 }
00183 
00184                                 simReleaseBuffer((char*)depth_buf);
00185                                 _pubDepth.publish(depth_msg);
00186 
00187                         }
00188 
00189                         _lastPublishedImageTime = currentSimulationTime;
00190                 }
00191         }
00192 
00193 }
00194 
00195 
00196 void CameraHandler::computeCameraInfo(){
00197         int resol[2];
00198         if (simGetVisionSensorResolution(_associatedObjectID,resol)!=-1)
00199         {
00200                 _camera_info.header.frame_id = "/" + _associatedObjectName;
00201                 _camera_info.width = resol[0];
00202                 _camera_info.height = resol[1];
00203                 simFloat view_angle = M_PI/4;
00204                 const unsigned int viewing_angle_id = 1004;
00205                 simGetObjectFloatParameter(_associatedObjectID, viewing_angle_id, &view_angle);
00206                 double f_x = (_camera_info.width/2.) / tan(view_angle/2.);
00207                 double f_y = f_x;
00208 
00209                 _camera_info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00210                 _camera_info.D.resize(5);
00211                 _camera_info.D[0] = 0;
00212                 _camera_info.D[1] = 0;
00213                 _camera_info.D[2] = 0;
00214                 _camera_info.D[3] = 0;
00215                 _camera_info.D[4] = 0;
00216 
00217                 _camera_info.K[0] = f_x; _camera_info.K[1] =   0; _camera_info.K[2] = _camera_info.width/2.0;
00218                 _camera_info.K[3] =   0; _camera_info.K[4] = f_y; _camera_info.K[5] = _camera_info.height/2.0;
00219                 _camera_info.K[6] =   0; _camera_info.K[7] =   0; _camera_info.K[8] = 1;
00220 
00221                 _camera_info.R[0] = 1; _camera_info.R[1] = 0; _camera_info.R[2] = 0;
00222                 _camera_info.R[3] = 0; _camera_info.R[4] = 1; _camera_info.R[5] = 0;
00223                 _camera_info.R[6] = 0; _camera_info.R[7] = 0; _camera_info.R[8] = 1;
00224 
00225                 _camera_info.P[0] = _camera_info.K[0]; _camera_info.P[1] = 0;         _camera_info.P[2] = _camera_info.K[2]; _camera_info.P[3] = 0;
00226                 _camera_info.P[4] = 0;         _camera_info.P[5] = _camera_info.K[4]; _camera_info.P[6] = _camera_info.K[5]; _camera_info.P[7] = 0;
00227                 _camera_info.P[8] = 0;         _camera_info.P[9] = 0;         _camera_info.P[10] = 1;        _camera_info.P[11] = 0;
00228 
00229         }
00230 }
00231 
00232 
00233 bool CameraHandler::setCameraInfo(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &res) {
00234         //    ROS_INFO("Setting camera parameters for %s.", _associatedObjectName.c_str());
00235 
00236         const int width = req.camera_info.width;
00237         const int height = req.camera_info.height;
00238 
00239         // check input compatibility
00240         // TODO: do it better
00241         if (fabs(req.camera_info.K[0] - req.camera_info.K[4]) > 1e-5 ||
00242                         fabs(req.camera_info.K[2] - width/2.0) > 1e-5 ||
00243                         fabs(req.camera_info.K[5] - height/2.0) > 1e-5) {
00244                 res.success = false;
00245                 res.status_message = std::string("Specified input parameters are not compatible with v-rep.");
00246                 return res.success;
00247         }
00248 
00249 
00250         const simFloat view_angle = 2.0*atan(width/(2.*req.camera_info.K[0]));
00251 
00252         const unsigned int resolution_x_id = 1002;
00253         const unsigned int resolution_y_id = 1003;
00254         const unsigned int viewing_angle_id = 1004;
00255 
00256         if (simSetObjectIntParameter(_associatedObjectID, resolution_x_id, width) == 1 &&
00257                         simSetObjectIntParameter(_associatedObjectID, resolution_y_id, height) == 1 &&
00258                         simSetObjectFloatParameter(_associatedObjectID, viewing_angle_id, view_angle) == 1){
00259 
00260                 res.success = true;
00261                 res.status_message = std::string("Correctly set camera parameters.");
00262         } else {
00263                 res.success = false;
00264                 res.status_message = std::string("Error setting camera parameters.");
00265         }
00266         computeCameraInfo();
00267         return res.success;
00268 
00269 }
00270 
00271 
00272 void CameraHandler::_initialize(){
00273         if (_initialized)
00274                 return;
00275 
00276         // Remove # chars for compatibility with ROS
00277         std::string objectName(_associatedObjectName);
00278         std::replace( objectName.begin(), objectName.end(), '#', '_');
00279         _pubIT = _it.advertiseCamera(objectName, 1);
00280         _service = _nh.advertiseService(objectName + "/set_camera_info", &CameraHandler::setCameraInfo, this);
00281 
00282         // get some data from the main object
00283         std::vector<unsigned char> developerCustomData;
00284         getDeveloperCustomData(developerCustomData);
00285 
00286         // 2. From that retrieved data, try to extract sub-data of interest
00287         std::vector<unsigned char> tempMainData;
00288 
00289         std::stringstream ss;
00290         if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_RGB,tempMainData)){
00291                 _cameraIsRGB=CAccess::pop_int(tempMainData);
00292                 if (_cameraIsRGB){
00293                         ss << "- [" << _associatedObjectName << "] Camera is RGB." << std::endl;
00294                 } else {
00295                         ss << "- [" << _associatedObjectName << "] Camera is grayscale." << std::endl;
00296                 }
00297         } else {
00298                 _cameraIsRGB = true;
00299                 ss << "- [" << _associatedObjectName << "] Camera color type not specified. Using rgb as default" << std::endl;
00300         }
00301 
00302         if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_HAS_DEPTH,tempMainData)){
00303                 _cameraHasDepth=CAccess::pop_int(tempMainData);
00304                 if (_cameraHasDepth){
00305                         ss << "- [" << _associatedObjectName << "] Camera has a depth sensor." << std::endl;
00306                         std::string objectName(_associatedObjectName);
00307                         std::replace( objectName.begin(), objectName.end(), '#', '_');
00308                         _pubDepth = _it.advertise(objectName + "/depthMap", 1);
00309                 } else {
00310                         ss << "- [" << _associatedObjectName << "] Camera does not have a depth sensor." << std::endl;
00311                 }
00312         } else {
00313                 _cameraHasDepth = false;
00314                 ss << "- [" << _associatedObjectName << "] Presence of depth sensor not specified. Assuming no depth sensor by default." << std::endl;
00315         }
00316 
00317         if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_USE_FLOAT,tempMainData)){
00318                 _cameraIsFloat=CAccess::pop_int(tempMainData);
00319                 if (_cameraIsFloat){
00320                         ss << "- [" << _associatedObjectName << "] Camera uses float encoding." << std::endl;
00321                 } else {
00322                         ss << "- [" << _associatedObjectName << "] Camera uses char encoding." << std::endl;
00323                 }
00324         } else {
00325                 _cameraIsFloat = false;
00326                 ss << "- [" << _associatedObjectName << "] Camera encoding not specified. Using char by default." << std::endl;
00327         }
00328 
00329         if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_FREQ,tempMainData)){
00330                 _acquisitionFrequency=CAccess::pop_float(tempMainData);
00331                 ss << "- [" << _associatedObjectName << "] Camera acquisition frequency: " << _acquisitionFrequency << "." << std::endl;
00332         } else {
00333                 _acquisitionFrequency = 30.0;
00334                 ss << "- [" << _associatedObjectName << "] Camera acquisition frequency not specified. Using 30Hz as default." << std::endl;
00335         }
00336 
00337         // Compute the intrinsic parameters of the camera
00338         computeCameraInfo();
00339 
00340         ss << "- [" << _associatedObjectName << "] Camera intrinsic matrix K = [";
00341         for (unsigned i=0; i<3;++i){
00342                 for (unsigned j=0; j<3;++j){
00343                         ss << _camera_info.K[3*i+j] << (j<2 ? ", " : (i<2 ? "; " : "]\n"));
00344                 }
00345         }
00346 
00347         // Print in the external console
00348         ConsoleHandler::printInConsole(ss);
00349 
00350         _lastPublishedImageTime = -1e5;
00351         _initialized=true;
00352 }
00353 
00354 
00355 bool CameraHandler::endOfSimulation(){
00356         _pubIT.shutdown();
00357         _pubDepth.shutdown();
00358         return GenericObjectHandler::endOfSimulation();
00359 }
00360 
00361 
00362 PLUGINLIB_EXPORT_CLASS(CameraHandler, GenericObjectHandler)


camera_handler
Author(s): Riccardo Spica , Giovanni Claudio
autogenerated on Mon Apr 3 2017 04:03:44