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 #include <Eigen/Geometry>
00011 
00012 #include <vrep_ros_plugin/ConsoleHandler.h>
00013 
00014 
00015 
00016 CameraHandler::CameraHandler() : GenericObjectHandler(),
00017     _acquisitionFrequency(30.0),
00018     _lastPublishedImageTime(0.0),
00019     _cameraIsRGB(true),
00020     _it(_nh){
00021 }
00022 
00023 CameraHandler::~CameraHandler(){
00024 }
00025 
00026 unsigned int CameraHandler::getObjectType() const {
00027     return CustomDataHeaders::CAMERA_DATA_MAIN;
00028 }
00029 
00030 void CameraHandler::synchronize(){
00031 
00032     _associatedObjectName = simGetObjectName(_associatedObjectID);
00033 
00034     // Remove # chars for compatibility with ROS
00035     std::string objectName(_associatedObjectName);
00036     std::replace( objectName.begin(), objectName.end(), '#', '_');
00037     _pubIT = _it.advertiseCamera(objectName, 1);
00038     _service = _nh.advertiseService(objectName + "/set_camera_info", &CameraHandler::setCameraInfo, this);
00039 }
00040 
00041 void CameraHandler::handleSimulation(){
00042     // called when the main script calls: simHandleModule
00043     if(!_initialized){
00044         _initialize();
00045     }
00046 
00047     ros::Time now = ros::Time::now();
00048 
00049 
00050     const simFloat currentSimulationTime = simGetSimulationTime();
00051 
00052     if ((currentSimulationTime-_lastPublishedImageTime) >= 1.0/_acquisitionFrequency){
00053 
00054         int resol[2];
00055 
00056         if(simHandleVisionSensor(_associatedObjectID,NULL,NULL)!=-1 &&
00057             simGetVisionSensorResolution(_associatedObjectID,resol)!=-1){
00058 
00059             // Populate the sensor_msgs::Image message
00060             sensor_msgs::Image image_msg;
00061             image_msg.header.stamp = now;
00062 
00063             std::string frame_id=_associatedObjectName;
00064             if (frame_id[0] != '/'){
00065                 frame_id = "/" + frame_id;
00066             }
00067 
00068             image_msg.header.frame_id = frame_id;
00069 
00070 
00071 //            char* cameraName = new(char[_associatedObjectName.size()]);
00072 //            memcpy(cameraName,_associatedObjectName.c_str(),_associatedObjectName.size()*sizeof(char));
00073 //            simReleaseBuffer(cameraName);
00074 
00075             image_msg.width=resol[0]; //Set the width of the image
00076             image_msg.height=resol[1]; //Set the height of the image
00077             image_msg.is_bigendian=0;
00078 
00079             const float* image_buf = simGetVisionSensorImage(_associatedObjectID);
00080             Eigen::Map< const Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00081                 imageR(image_buf,image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00082             Eigen::Map< const Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00083                 imageG(image_buf+1,image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00084             Eigen::Map< const Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00085                 imageB(image_buf+2,image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00086 
00087             if (_cameraIsRGB){
00088                 image_msg.encoding=sensor_msgs::image_encodings::RGB8; //Set the format to be RGB with 8bits per channel
00089                 image_msg.step=image_msg.width*3; //Set the image stride in bytes
00090 
00091                 const int data_len=image_msg.step*image_msg.height;
00092                 image_msg.data.resize(data_len);
00093 
00094                 Eigen::Map< Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00095                     imageMsgR(image_msg.data.data(),image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00096                 Eigen::Map< Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00097                                         imageMsgG(image_msg.data.data()+1,image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00098                 Eigen::Map< Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>, 0, Eigen::Stride< Eigen::Dynamic, 3> >
00099                                         imageMsgB(image_msg.data.data()+2,image_msg.height,image_msg.width, Eigen::Stride<Eigen::Dynamic, 3>(3*(int)(resol[0]), 3) );
00100 
00101                 imageMsgR = (255.1f*imageR).rowwise().reverse().cast<unsigned char>();
00102                 imageMsgG = (255.1f*imageG).rowwise().reverse().cast<unsigned char>();
00103                 imageMsgB = (255.1f*imageB).rowwise().reverse().cast<unsigned char>();
00104 
00105             } else {
00106                 image_msg.encoding=sensor_msgs::image_encodings::MONO8;
00107                 image_msg.step=image_msg.width; //Set the image stride in bytes
00108 
00109                 const int data_len=image_msg.step*image_msg.height;
00110                 image_msg.data.resize(data_len);
00111 
00112                 Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> >
00113                    imageMsg(image_msg.data.data(),image_msg.height,image_msg.step);
00114 
00115 //                const Eigen::Vector3f coeffs(255.1f/3.0,255.1f/3.0,255.1f/3.0); //RGB to grayscale averaging
00116                 const Eigen::Vector3f coeffs(255.1*Eigen::Vector3f(0.2126,0.7152,0.0722)); //RGB to grayscale luminance
00117 
00118                 imageMsg = ((coeffs[0]*imageR+coeffs[1]*imageG+coeffs[2]*imageB).rowwise().reverse()).cast<unsigned char>();
00119 
00120             }
00121 
00122             simReleaseBuffer((char*)image_buf);
00123             _camera_info.header.stamp = now;
00124             _pubIT.publish(image_msg, _camera_info, now);
00125             _lastPublishedImageTime = currentSimulationTime;
00126         }
00127     }
00128 
00129 }
00130 
00131 
00132 void CameraHandler::computeCameraInfo(){
00133     int resol[2];
00134     if (simGetVisionSensorResolution(_associatedObjectID,resol)!=-1)
00135     {
00136         _camera_info.header.frame_id = "/" + _associatedObjectName;
00137         _camera_info.width = resol[0];
00138         _camera_info.height = resol[1];
00139         simFloat view_angle = M_PI/4;
00140         const unsigned int viewing_angle_id = 1004;
00141         simGetObjectFloatParameter(_associatedObjectID, viewing_angle_id, &view_angle);
00142         double f_x = (_camera_info.width/2.) / tan(view_angle/2.);
00143         double f_y = f_x;
00144 
00145         _camera_info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00146         _camera_info.D.resize(5);
00147         _camera_info.D[0] = 0;
00148         _camera_info.D[1] = 0;
00149         _camera_info.D[2] = 0;
00150         _camera_info.D[3] = 0;
00151         _camera_info.D[4] = 0;
00152 
00153         _camera_info.K[0] = f_x; _camera_info.K[1] =   0; _camera_info.K[2] = _camera_info.width/2.0;
00154         _camera_info.K[3] =   0; _camera_info.K[4] = f_y; _camera_info.K[5] = _camera_info.height/2.0;
00155         _camera_info.K[6] =   0; _camera_info.K[7] =   0; _camera_info.K[8] = 1;
00156 
00157         _camera_info.R[0] = 1; _camera_info.R[1] = 0; _camera_info.R[2] = 0;
00158         _camera_info.R[3] = 0; _camera_info.R[4] = 1; _camera_info.R[5] = 0;
00159         _camera_info.R[6] = 0; _camera_info.R[7] = 0; _camera_info.R[8] = 1;
00160 
00161         _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;
00162         _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;
00163         _camera_info.P[8] = 0;         _camera_info.P[9] = 0;         _camera_info.P[10] = 1;        _camera_info.P[11] = 0;
00164 
00165     }
00166 }
00167 
00168 
00169 bool CameraHandler::setCameraInfo(sensor_msgs::SetCameraInfo::Request &req, sensor_msgs::SetCameraInfo::Response &res) {
00170 //    ROS_INFO("Setting camera parameters for %s.", _associatedObjectName.c_str());
00171 
00172     const int width = req.camera_info.width;
00173     const int height = req.camera_info.height;
00174 
00175     // check input compatibility
00176     // TODO: do it better
00177     if (fabs(req.camera_info.K[0] - req.camera_info.K[4]) > 1e-5 ||
00178             fabs(req.camera_info.K[2] - width/2.0) > 1e-5 ||
00179             fabs(req.camera_info.K[5] - height/2.0) > 1e-5) {
00180         res.success = false;
00181         res.status_message = std::string("Specified input parameters are not compatible with v-rep.");
00182         return res.success;
00183     }
00184 
00185 
00186     const simFloat view_angle = 2.0*atan(width/(2.*req.camera_info.K[0]));
00187 
00188     const unsigned int resolution_x_id = 1002;
00189     const unsigned int resolution_y_id = 1003;
00190     const unsigned int viewing_angle_id = 1004;
00191 
00192     if (simSetObjectIntParameter(_associatedObjectID, resolution_x_id, width) == 1 &&
00193             simSetObjectIntParameter(_associatedObjectID, resolution_y_id, height) == 1 &&
00194             simSetObjectFloatParameter(_associatedObjectID, viewing_angle_id, view_angle) == 1){
00195 
00196         res.success = true;
00197         res.status_message = std::string("Correctly set camera parameters.");
00198     } else {
00199         res.success = false;
00200         res.status_message = std::string("Error setting camera parameters.");
00201     }
00202     computeCameraInfo();
00203     return res.success;
00204 
00205 }
00206 
00207 
00208 void CameraHandler::_initialize(){
00209     if (_initialized)
00210         return;
00211 
00212     // get some data from the main object
00213     std::vector<unsigned char> developerCustomData;
00214     getDeveloperCustomData(developerCustomData);
00215 
00216     // 2. From that retrieved data, try to extract sub-data of interest
00217     std::vector<unsigned char> tempMainData;
00218 
00219     std::stringstream ss;
00220     if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_RGB,tempMainData)){
00221         _cameraIsRGB=CAccess::pop_int(tempMainData);
00222         if (_cameraIsRGB){
00223             ss << "- [" << _associatedObjectName << "] Camera is RGB." << std::endl;
00224         } else {
00225             ss << "- [" << _associatedObjectName << "] Camera is grayscale." << std::endl;
00226         }
00227     } else {
00228         _cameraIsRGB = true;
00229         ss << "- [" << _associatedObjectName << "] Camera color type not specified. Using rgb as default" << std::endl;
00230     }
00231 
00232     if (CAccess::extractSerializationData(developerCustomData,CustomDataHeaders::CAMERA_DATA_FREQ,tempMainData)){
00233         _acquisitionFrequency=CAccess::pop_float(tempMainData);
00234         ss << "- [" << _associatedObjectName << "] Camera acquisition frequency: " << _acquisitionFrequency << "." << std::endl;
00235     } else {
00236         _acquisitionFrequency = 30.0;
00237         ss << "- [" << _associatedObjectName << "] Camera acquisition frequency not specified. Using 30Hz as default." << std::endl;
00238     }
00239 
00240     // Compute the intrinsic parameters of the camera
00241     computeCameraInfo();
00242 
00243     Eigen::Map<Eigen::Matrix3d> K(&_camera_info.K[0]);
00244     ss << "- [" << _associatedObjectName << "] Camera intrinsic matrix K = " << std::endl << K <<  std::endl;
00245 
00246     // Print in the external console
00247     ConsoleHandler::printInConsole(ss);
00248 
00249     _lastPublishedImageTime = -1e5;
00250     _initialized=true;
00251 }
00252 
00253 
00254 PLUGINLIB_EXPORT_CLASS(CameraHandler, GenericObjectHandler)


camera_handler
Author(s): Riccardo Spica , Giovanni Claudio
autogenerated on Wed Sep 9 2015 18:55:01