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
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
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
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
00072
00073
00074
00075 image_msg.width=resol[0];
00076 image_msg.height=resol[1];
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;
00089 image_msg.step=image_msg.width*3;
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;
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
00116 const Eigen::Vector3f coeffs(255.1*Eigen::Vector3f(0.2126,0.7152,0.0722));
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
00171
00172 const int width = req.camera_info.width;
00173 const int height = req.camera_info.height;
00174
00175
00176
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
00213 std::vector<unsigned char> developerCustomData;
00214 getDeveloperCustomData(developerCustomData);
00215
00216
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
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
00247 ConsoleHandler::printInConsole(ss);
00248
00249 _lastPublishedImageTime = -1e5;
00250 _initialized=true;
00251 }
00252
00253
00254 PLUGINLIB_EXPORT_CLASS(CameraHandler, GenericObjectHandler)