00001 #include "pmdcamera_driver_node.h"
00002 #include <boost/make_shared.hpp>
00003 #include "exceptions.h"
00004
00005 PmdcameraDriverNode::PmdcameraDriverNode(ros::NodeHandle &nh) : iri_base_driver::IriBaseNodeDriver<PmdcameraDriver>(nh) {
00006
00007 max_intensity_ = 50000.0;
00008 max_amplitude_ = 50000.0;
00009
00010 max_depth_ = 7.5;
00011
00012 int camera_type=0;
00013 private_node_handle_.param<int>("camera_type", camera_type, pmd_camera::camboard);
00014 std::string frame_id="/camboard_frame";
00015 private_node_handle_.param<std::string>("frame_id", frame_id, "/camboard_frame");
00016
00017 int int_time=700;
00018 private_node_handle_.param<int>("integration_time", int_time, 700);
00019 int mod_freq=20000000;
00020 private_node_handle_.param<int>("modulation_freq", mod_freq, 20000000);
00021
00022 if (camera_type==pmd_camera::camboard) {
00023 driver_.setCameraType(pmd_camera::camboard);
00024 ROS_INFO("Camera type CAMBOARD");
00025 } else if (camera_type==pmd_camera::camcube) {
00026 driver_.setCameraType(pmd_camera::camcube);
00027 ROS_INFO("Camera type CAMCUBE");
00028 } else {
00029 ROS_WARN("Camera type not recognized. Trying camboard...");
00030 }
00031
00032 driver_.setIntegrationTime(int_time);
00033 driver_.setModulationFrequency(mod_freq);
00034
00035
00036 real_width_ = driver_.getWidth();
00037 real_height_ = driver_.getHeight();
00038
00039
00040 ROS_INFO("Raw Image size %d %d", real_width_, real_height_);
00041
00042
00043 width_ = 200;
00044 height_ = 200;
00045
00046
00047 loop_rate_ = 50;
00048
00049
00050 if(camera_type==pmd_camera::camboard){
00051 pcl2_int_msg_.header.frame_id = std::string (frame_id);
00052 pcl2_amp_msg_.header.frame_id = std::string (frame_id);
00053 pcl2_range_msg_.header.frame_id = std::string (frame_id);
00054 } else if (camera_type==pmd_camera::camcube) {
00055 pcl2_int_msg_.header.frame_id = std::string (frame_id);
00056 pcl2_amp_msg_.header.frame_id = std::string (frame_id);
00057 pcl2_range_msg_.header.frame_id = std::string (frame_id);
00058 } else {
00059 ROS_WARN("Camera type not recognized. Trying again...");
00060 }
00061
00062
00063 pcl2_int_msg_.height = height_;
00064 pcl2_int_msg_.width = width_;
00065 pcl2_int_msg_.fields.resize (4);
00066 pcl2_int_msg_.fields[0].name = "x";
00067 pcl2_int_msg_.fields[1].name = "y";
00068 pcl2_int_msg_.fields[2].name = "z";
00069 pcl2_int_msg_.fields[3].name = "intensity";
00070
00071 pcl2_amp_msg_.height = height_;
00072 pcl2_amp_msg_.width = width_;
00073 pcl2_amp_msg_.fields.resize (4);
00074 pcl2_amp_msg_.fields[0].name = "x";
00075 pcl2_amp_msg_.fields[1].name = "y";
00076 pcl2_amp_msg_.fields[2].name = "z";
00077 pcl2_amp_msg_.fields[3].name = "intensity";
00078
00079 pcl2_range_msg_.height = height_;
00080 pcl2_range_msg_.width = width_;
00081 pcl2_range_msg_.fields.resize (5);
00082 pcl2_range_msg_.fields[0].name = "x";
00083 pcl2_range_msg_.fields[1].name = "y";
00084 pcl2_range_msg_.fields[2].name = "z";
00085 pcl2_range_msg_.fields[3].name = "range";
00086 pcl2_range_msg_.fields[4].name = "intensity";
00087
00088
00089 int offset = 0;
00090
00091 for (size_t s = 0; s < pcl2_int_msg_.fields.size (); ++s, offset += 4)
00092 {
00093 pcl2_int_msg_.fields[s].offset = offset;
00094 pcl2_int_msg_.fields[s].count = 1;
00095 pcl2_int_msg_.fields[s].datatype = sensor_msgs::PointField::FLOAT32;
00096 pcl2_amp_msg_.fields[s].offset = offset;
00097 pcl2_amp_msg_.fields[s].count = 1;
00098 pcl2_amp_msg_.fields[s].datatype = sensor_msgs::PointField::FLOAT32;
00099 }
00100 pcl2_int_msg_.point_step = offset;
00101 pcl2_int_msg_.row_step = pcl2_int_msg_.point_step * pcl2_int_msg_.width;
00102 pcl2_int_msg_.data.resize (pcl2_int_msg_.row_step * pcl2_int_msg_.height);
00103 pcl2_int_msg_.is_dense = true;
00104 pcl2_amp_msg_.point_step = offset;
00105 pcl2_amp_msg_.row_step = pcl2_amp_msg_.point_step * pcl2_amp_msg_.width;
00106 pcl2_amp_msg_.data.resize (pcl2_amp_msg_.row_step * pcl2_amp_msg_.height);
00107 pcl2_amp_msg_.is_dense = true;
00108
00109 offset = 0;
00110
00111 for (size_t s = 0; s < pcl2_range_msg_.fields.size (); ++s, offset += 4)
00112 {
00113 pcl2_range_msg_.fields[s].offset = offset;
00114 pcl2_range_msg_.fields[s].count = 1;
00115 pcl2_range_msg_.fields[s].datatype = sensor_msgs::PointField::FLOAT32;
00116 }
00117 pcl2_range_msg_.point_step = offset;
00118 pcl2_range_msg_.row_step = pcl2_range_msg_.point_step * pcl2_range_msg_.width;
00119 pcl2_range_msg_.data.resize (pcl2_range_msg_.row_step * pcl2_range_msg_.height);
00120 pcl2_range_msg_.is_dense = true;
00121
00122
00123 Image_flags_msg_.header.frame_id = pcl2_int_msg_.header.frame_id;
00124 Image_flags_msg_.height = height_;
00125 Image_flags_msg_.width = width_;
00126 Image_flags_msg_.encoding = sensor_msgs::image_encodings::MONO8;
00127 Image_flags_msg_.step = width_;
00128 Image_flags_msg_.data.resize(width_ * height_);
00129
00130
00131 Image_int_msg_.header.frame_id = pcl2_int_msg_.header.frame_id;
00132 Image_int_msg_.height = height_;
00133 Image_int_msg_.width = width_;
00134 Image_int_msg_.encoding = sensor_msgs::image_encodings::MONO8;
00135 Image_int_msg_.step = width_ * sizeof(uint8_t);
00136 Image_int_msg_.data.resize(Image_int_msg_.step * height_);
00137
00138
00139 Image_amp_msg_.header.frame_id = pcl2_int_msg_.header.frame_id;
00140 Image_amp_msg_.height = height_;
00141 Image_amp_msg_.width = width_;
00142 Image_amp_msg_.encoding = sensor_msgs::image_encodings::MONO8;
00143 Image_amp_msg_.step = width_ * sizeof(uint8_t);
00144 Image_amp_msg_.data.resize(Image_amp_msg_.step * height_);
00145
00146
00147 Image_depth_msg_.header.frame_id = pcl2_int_msg_.header.frame_id;
00148 Image_depth_msg_.height = height_;
00149 Image_depth_msg_.width = width_;
00150 Image_depth_msg_.encoding = sensor_msgs::image_encodings::TYPE_32FC1;
00151 Image_depth_msg_.step = width_ * sizeof(float);
00152 Image_depth_msg_.data.resize(Image_depth_msg_.step * height_);
00153
00154
00155
00156
00157 switch (camera_type) {
00158 case pmd_camera::camboard:
00159 public_node_handle_.param ("camera_name", camera_name_, std::string("camboard"));
00160 public_node_handle_.param ("camera_info_url", camera_info_url_, std::string("file://")+ros::package::getPath(ROS_PACKAGE_NAME)+std::string("/info/camboard_calibration.yaml"));
00161 break;
00162 case pmd_camera::camcube:
00163 public_node_handle_.param ("camera_name", camera_name_, std::string("camcube"));
00164 public_node_handle_.param ("camera_info_url", camera_info_url_, std::string("file://")+ros::package::getPath(ROS_PACKAGE_NAME)+std::string("/info/camcube_calibration.yaml"));
00165 break;
00166 default:
00167 public_node_handle_.param ("camera_name", camera_name_, std::string("camera"));
00168 public_node_handle_.param ("camera_info_url", camera_info_url_, std::string("auto"));
00169 break;
00170 }
00171
00172 camera_info_manager_ = new camera_info_manager::CameraInfoManager(public_node_handle_, camera_name_, camera_info_url_);
00173
00174 image_transport::ImageTransport imt(public_node_handle_);
00175
00176
00177 image_raw_publisher_ = imt.advertiseCamera ("intensity/image_raw", 1);
00178 image_amp_publisher_ = imt.advertiseCamera ("amplitude/image_raw", 1);
00179 image_depth_publisher_ = imt.advertiseCamera ("distance/image_raw", 1);
00180 image_flags_publisher_ = imt.advertiseCamera ("flags/image_raw", 1);
00181 pcl_int_raw_publisher_ = public_node_handle_.advertise<sensor_msgs::PointCloud2>("pointcloud/pcl_int_raw", 1);
00182 pcl_amp_raw_publisher_ = public_node_handle_.advertise<sensor_msgs::PointCloud2>("pointcloud/pcl_amp_raw", 1);
00183 pcl_range_raw_publisher_ = public_node_handle_.advertise<sensor_msgs::PointCloud2>("pointcloud/pcl_range_raw", 1);
00184
00185 ROS_INFO ("publishers initialized");
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 }
00197
00198
00199 void
00200 PmdcameraDriverNode::findMaxIntensity(const float* intensity)
00201 {
00202 if (max_intensity_ == 0)
00203 for (int v = 0; v < height_; ++v)
00204 for (int u = 0; u < width_; ++u)
00205 if (max_intensity_ < intensity[v*(width_)+u])
00206 max_intensity_ = intensity[v*(width_)+u];
00207
00208 }
00209
00210 void PmdcameraDriverNode::findMaxAmplitude(const float* amplitude)
00211 {
00212 if (max_amplitude_ == 0)
00213 for (int v = 0; v < height_; ++v)
00214 for (int u = 0; u < width_; ++u)
00215 if (max_amplitude_ < amplitude[v*(width_)+u])
00216 max_amplitude_ = amplitude[v*(width_)+u];
00217
00218 }
00219
00220 void PmdcameraDriverNode::findMaxDepth(const float* distance)
00221 {
00222 if (max_depth_ == 0)
00223 for (int v = 0; v < height_; ++v)
00224 for (int u = 0; u < width_; ++u)
00225 if (max_depth_ < distance[v*(width_)+u])
00226 max_depth_ = distance[v*(width_)+u];
00227
00228 }
00229
00230 void PmdcameraDriverNode::assembleFlagsImage(float* flags)
00231 {
00232 for (int v = 0; v < height_; ++v)
00233 {
00234 for (int u = 0; u < width_; ++u)
00235 {
00236 int index = v * width_ + u;
00237 Image_flags_msg_.data[index] = flags[index];
00238 }
00239 }
00240 }
00241
00242 void PmdcameraDriverNode::assembleIntensityImage(float* intensity)
00243 {
00244
00245 findMaxIntensity(intensity);
00246 if (max_intensity_ != 0)
00247 {
00248 for (unsigned index = 0; index < Image_int_msg_.height * Image_int_msg_.width; ++index){
00249 Image_int_msg_.data[index]=intensity[index]*255/max_intensity_;
00250 }
00251 }
00252 }
00253
00254 void PmdcameraDriverNode::assembleAmplitudeImage(float* amplitude)
00255 {
00256
00257
00258 if (max_amplitude_ != 0)
00259 {
00260 for (unsigned index = 0; index < Image_amp_msg_.height * Image_amp_msg_.width; ++index){
00261 Image_amp_msg_.data[index] = amplitude[index]*255/max_amplitude_;
00262 }
00263 }
00264 }
00265
00266 void PmdcameraDriverNode::assembleDepthImage(float* distance)
00267 {
00268
00269
00270
00271
00272 float* raw_data = reinterpret_cast<float*>(&distance[0]);
00273 float* depth_data = reinterpret_cast<float*>(&Image_depth_msg_.data[0]);
00274 for (unsigned index = 0; index < Image_depth_msg_.height * Image_depth_msg_.width; ++index){
00275 depth_data[index] = raw_data[index];
00276 }
00277
00278 }
00279
00280 void PmdcameraDriverNode::assemblePcl2Int(const float* const coord_3D, const float* const intensity)
00281 {
00282
00283 findMaxIntensity(intensity);
00284 if (max_intensity_ == 0 ) max_intensity_=1;
00285
00286
00287 for (int v = 0; v < height_; v++)
00288 {
00289 for (int u = 0; u < width_; u++)
00290 {
00291 int index = v * width_ + u;
00292 int index1 = v * real_width_ + u;
00293 int index3 = (v * real_width_ + u)*3;
00294
00295 float *pstep = (float*)&pcl2_int_msg_.data[(index) * pcl2_int_msg_.point_step];
00296
00297 pstep[0] = coord_3D[index3];
00298 pstep[1] = coord_3D[index3+1];
00299 pstep[2] = coord_3D[index3+2];
00300 pstep[3] = intensity[index1]*255/max_intensity_;
00301
00302
00303
00304
00305
00306 }
00307 }
00308 }
00309
00310 void PmdcameraDriverNode::assemblePcl2Amp(const float* const coord_3D, const float* const amplitude)
00311 {
00312
00313
00314 for (int v = 0; v < height_; v++){
00315 for (int u = 0; u < width_; u++){
00316 int index = v * width_ + u;
00317 int index1 = v * real_width_ + u;
00318 int index3 = (v * real_width_ + u)*3;
00319
00320 float *pstep = (float*)&pcl2_amp_msg_.data[(index) * pcl2_amp_msg_.point_step];
00321
00322 pstep[0] = coord_3D[index3];
00323 pstep[1] = coord_3D[index3+1];
00324 pstep[2] = coord_3D[index3+2];
00325 pstep[3] = amplitude[index1];
00326
00327
00328
00329
00330 }
00331 }
00332 }
00333
00334 void PmdcameraDriverNode::assemblePcl2RangeImage(const float* const coord_3D, const float* const range, const float* const amp)
00335 {
00336
00337
00338 for (int v = 0; v < height_; v++){
00339 for (int u = 0; u < width_; u++){
00340 int index = v * width_ + u;
00341 int index1 = v * real_width_ + u;
00342 int index3 = (v * real_width_ + u)*3;
00343
00344 float *pstep = (float*)&pcl2_range_msg_.data[(index) * pcl2_range_msg_.point_step];
00345
00346 pstep[0] = coord_3D[index3];
00347 pstep[1] = coord_3D[index3+1];
00348 pstep[2] = coord_3D[index3+2];
00349 pstep[3] = range[index1];
00350 pstep[4] = amp[index1];
00351 }
00352 }
00353 }
00354
00355 void PmdcameraDriverNode::mainNodeThread(void)
00356 {
00357 camera_info_ = camera_info_manager_->getCameraInfo ();
00358
00359
00360 max_intensity_ = 0;
00361
00362
00363
00364
00365
00366
00367
00368 PointCloud_msg_.header.frame_id = camera_info_.header.frame_id = pcl2_range_msg_.header.frame_id = pcl2_amp_msg_.header.frame_id = pcl2_int_msg_.header.frame_id;
00369 PointCloud_msg_.header.stamp = pcl2_range_msg_.header.stamp = pcl2_amp_msg_.header.stamp = pcl2_int_msg_.header.stamp = Image_int_msg_.header.stamp = Image_amp_msg_.header.stamp
00370 = Image_depth_msg_.header.stamp = camera_info_.header.stamp = ros::Time::now ();
00371
00372
00373 if ((pcl_range_raw_publisher_.getNumSubscribers () > 0) ||
00374 (pcl_amp_raw_publisher_.getNumSubscribers () > 0) ||
00375 (pcl_int_raw_publisher_.getNumSubscribers () > 0) ||
00376 (image_raw_publisher_.getNumSubscribers () > 0) ||
00377 (image_amp_publisher_.getNumSubscribers () > 0) ||
00378 (image_flags_publisher_.getNumSubscribers () > 0) ||
00379 (image_depth_publisher_.getNumSubscribers () > 0)) {
00380 try {
00381 driver_.lock();
00382 driver_.readData();
00383
00384 driver_.unlock();
00385
00386
00387
00388
00389
00390
00391
00392
00393 if (pcl_range_raw_publisher_.getNumSubscribers () > 0) {
00394 bool is_dense = true;
00395 assemblePcl2RangeImage(driver_.get3DImage(is_dense), driver_.getRangeImage(), driver_.getAmplitudeImage());
00396 pcl2_range_msg_.is_dense = is_dense;
00397 pcl_range_raw_publisher_.publish(pcl2_range_msg_);
00398 }
00399
00400 if (pcl_amp_raw_publisher_.getNumSubscribers () > 0) {
00401 bool is_dense = true;
00402 assemblePcl2Amp(driver_.get3DImage(is_dense), driver_.getAmplitudeImage());
00403 pcl2_amp_msg_.is_dense = is_dense;
00404 pcl_amp_raw_publisher_.publish(pcl2_amp_msg_);
00405 }
00406
00407 if (pcl_int_raw_publisher_.getNumSubscribers () > 0) {
00408 bool is_dense = true;
00409 assemblePcl2Int(driver_.get3DImage(is_dense), driver_.getIntensityImage());
00410 pcl2_int_msg_.is_dense = is_dense;
00411 pcl_int_raw_publisher_.publish(pcl2_int_msg_);
00412 }
00413
00414 if (image_flags_publisher_.getNumSubscribers () > 0) {
00415 assembleFlagsImage(driver_.getFlagsImage());
00416
00417 image_flags_publisher_.publish(boost::make_shared<const sensor_msgs::Image> (Image_int_msg_),boost::make_shared<const sensor_msgs::CameraInfo> (camera_info_));
00418 }
00419
00420 if (image_raw_publisher_.getNumSubscribers () > 0) {
00421 assembleIntensityImage(driver_.getIntensityImage());
00422
00423 image_raw_publisher_.publish(boost::make_shared<const sensor_msgs::Image> (Image_int_msg_),boost::make_shared<const sensor_msgs::CameraInfo> (camera_info_));
00424 }
00425
00426 if (image_amp_publisher_.getNumSubscribers () > 0)
00427 {
00428 assembleAmplitudeImage(driver_.getAmplitudeImage());
00429
00430 image_amp_publisher_.publish(boost::make_shared<const sensor_msgs::Image> (Image_amp_msg_),boost::make_shared<const sensor_msgs::CameraInfo> (camera_info_));
00431 }
00432
00433 if (image_depth_publisher_.getNumSubscribers () > 0)
00434 {
00435 assembleDepthImage(driver_.getDepthImage());
00436
00437 image_depth_publisher_.publish(boost::make_shared<const sensor_msgs::Image> (Image_depth_msg_),boost::make_shared<const sensor_msgs::CameraInfo> (camera_info_));
00438 }
00439
00440 } catch(CException &e){
00441 driver_.unlock();
00442 ROS_INFO("Impossible to capture frame");
00443 }
00444
00445
00446 }
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 void PmdcameraDriverNode::postNodeOpenHook(void)
00458 {
00459 }
00460
00461 void PmdcameraDriverNode::addNodeDiagnostics(void)
00462 {
00463 }
00464
00465 void PmdcameraDriverNode::addNodeOpenedTests(void)
00466 {
00467 }
00468
00469 void PmdcameraDriverNode::addNodeStoppedTests(void)
00470 {
00471 }
00472
00473 void PmdcameraDriverNode::addNodeRunningTests(void)
00474 {
00475 }
00476
00477 void PmdcameraDriverNode::reconfigureNodeHook(int level)
00478 {
00479 }
00480
00481 PmdcameraDriverNode::~PmdcameraDriverNode()
00482 {
00483
00484 delete camera_info_manager_;
00485 }
00486
00487
00488 int main(int argc,char *argv[])
00489 {
00490 return driver_base::main<PmdcameraDriverNode>(argc,argv,"pmdcamera_driver_node");
00491 }