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
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
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
00068
00069
00070
00071 image_msg.width=resol[0];
00072 image_msg.height=resol[1];
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;
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;
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
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];
00170 depth_msg.height=resol[1];
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
00235
00236 const int width = req.camera_info.width;
00237 const int height = req.camera_info.height;
00238
00239
00240
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
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
00283 std::vector<unsigned char> developerCustomData;
00284 getDeveloperCustomData(developerCustomData);
00285
00286
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
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
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)