00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "astra_camera/astra_driver.h"
00034 #include "astra_camera/astra_exception.h"
00035 #include "astra_camera/astra_device_type.h"
00036
00037 #include <unistd.h>
00038 #include <stdlib.h>
00039 #include <stdio.h>
00040 #include <sys/shm.h>
00041 #include <sensor_msgs/image_encodings.h>
00042 #include <sensor_msgs/distortion_models.h>
00043
00044 #include <boost/date_time/posix_time/posix_time.hpp>
00045 #include <boost/thread/thread.hpp>
00046
00047 #define MULTI_ASTRA 1
00048 namespace astra_wrapper
00049 {
00050
00051 AstraDriver::AstraDriver(ros::NodeHandle& n, ros::NodeHandle& pnh) :
00052 nh_(n),
00053 pnh_(pnh),
00054 device_manager_(AstraDeviceManager::getSingelton()),
00055 config_init_(false),
00056 data_skip_ir_counter_(0),
00057 data_skip_color_counter_(0),
00058 data_skip_depth_counter_ (0),
00059 ir_subscribers_(false),
00060 color_subscribers_(false),
00061 depth_subscribers_(false),
00062 depth_raw_subscribers_(false),
00063 uvc_flip_(0)
00064 {
00065
00066 genVideoModeTableMap();
00067
00068 readConfigFromParameterServer();
00069
00070 #if MULTI_ASTRA
00071 int bootOrder, devnums;
00072 if (!pnh.getParam("bootorder", bootOrder))
00073 {
00074 bootOrder = 0;
00075 }
00076
00077 if (!pnh.getParam("devnums", devnums))
00078 {
00079 devnums = 1;
00080 }
00081
00082 if( devnums>1 )
00083 {
00084 int shmid;
00085 char *shm = NULL;
00086 char *tmp;
00087
00088 if( bootOrder==1 )
00089 {
00090 if( (shmid = shmget((key_t)0401, 1, 0666|IPC_CREAT)) == -1 )
00091 {
00092 ROS_ERROR("Create Share Memory Error:%s", strerror(errno));
00093 }
00094 shm = (char *)shmat(shmid, 0, 0);
00095 *shm = 1;
00096 initDevice();
00097 ROS_INFO("*********** device_id %s already open device************************ ", device_id_.c_str());
00098 *shm = 2;
00099 }
00100 else
00101 {
00102 if( (shmid = shmget((key_t)0401, 1, 0666|IPC_CREAT)) == -1 )
00103 {
00104 ROS_ERROR("Create Share Memory Error:%s", strerror(errno));
00105 }
00106 shm = (char *)shmat(shmid, 0, 0);
00107 while( *shm!=bootOrder)
00108 {
00109 boost::this_thread::sleep(boost::posix_time::milliseconds(10));
00110 }
00111
00112 initDevice();
00113 ROS_INFO("*********** device_id %s already open device************************ ", device_id_.c_str());
00114 *shm = (bootOrder+1);
00115 }
00116 if( bootOrder==devnums )
00117 {
00118 if(shmdt(shm) == -1)
00119 {
00120 ROS_ERROR("shmdt failed\n");
00121 }
00122 if(shmctl(shmid, IPC_RMID, 0) == -1)
00123 {
00124 ROS_ERROR("shmctl(IPC_RMID) failed\n");
00125 }
00126 }
00127 else
00128 {
00129 if(shmdt(shm) == -1)
00130 {
00131 ROS_ERROR("shmdt failed\n");
00132 }
00133 }
00134 }
00135 else
00136 {
00137 initDevice();
00138 }
00139 #else
00140 initDevice();
00141
00142 #endif
00143
00144 reconfigure_server_.reset(new ReconfigureServer(pnh_));
00145 reconfigure_server_->setCallback(boost::bind(&AstraDriver::configCb, this, _1, _2));
00146
00147 while (!config_init_)
00148 {
00149 ROS_DEBUG("Waiting for dynamic reconfigure configuration.");
00150 boost::this_thread::sleep(boost::posix_time::milliseconds(100));
00151 }
00152 ROS_DEBUG("Dynamic reconfigure configuration received.");
00153
00154 advertiseROSTopics();
00155 }
00156
00157 void AstraDriver::advertiseROSTopics()
00158 {
00159
00160
00161 ros::NodeHandle color_nh(nh_, "rgb");
00162 image_transport::ImageTransport color_it(color_nh);
00163 ros::NodeHandle ir_nh(nh_, "ir");
00164 image_transport::ImageTransport ir_it(ir_nh);
00165 ros::NodeHandle depth_nh(nh_, "depth");
00166 image_transport::ImageTransport depth_it(depth_nh);
00167 ros::NodeHandle depth_raw_nh(nh_, "depth");
00168 image_transport::ImageTransport depth_raw_it(depth_raw_nh);
00169 ros::NodeHandle projector_nh(nh_, "projector");
00170
00171
00172
00173
00174
00175
00176 boost::lock_guard<boost::mutex> lock(connect_mutex_);
00177
00178
00179
00180 if (device_->hasColorSensor())
00181 {
00182 image_transport::SubscriberStatusCallback itssc = boost::bind(&AstraDriver::imageConnectCb, this);
00183 ros::SubscriberStatusCallback rssc = boost::bind(&AstraDriver::imageConnectCb, this);
00184 pub_color_ = color_it.advertiseCamera("image", 1, itssc, itssc, rssc, rssc);
00185 }
00186
00187 if (device_->hasIRSensor())
00188 {
00189 image_transport::SubscriberStatusCallback itssc = boost::bind(&AstraDriver::imageConnectCb, this);
00190 ros::SubscriberStatusCallback rssc = boost::bind(&AstraDriver::imageConnectCb, this);
00191 pub_ir_ = ir_it.advertiseCamera("image", 1, itssc, itssc, rssc, rssc);
00192 }
00193
00194 if (device_->hasDepthSensor())
00195 {
00196 image_transport::SubscriberStatusCallback itssc = boost::bind(&AstraDriver::depthConnectCb, this);
00197 ros::SubscriberStatusCallback rssc = boost::bind(&AstraDriver::depthConnectCb, this);
00198 pub_depth_raw_ = depth_it.advertiseCamera("image_raw", 1, itssc, itssc, rssc, rssc);
00199 pub_depth_ = depth_raw_it.advertiseCamera("image", 1, itssc, itssc, rssc, rssc);
00200 pub_projector_info_ = projector_nh.advertise<sensor_msgs::CameraInfo>("camera_info", 1, rssc, rssc);
00201 }
00202
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 std::string serial_number = device_->getStringID();
00214 std::string color_name, ir_name;
00215
00216 color_name = "rgb_" + serial_number;
00217 ir_name = "depth_" + serial_number;
00218
00219
00220 color_info_manager_ = boost::make_shared<camera_info_manager::CameraInfoManager>(color_nh, color_name, color_info_url_);
00221 ir_info_manager_ = boost::make_shared<camera_info_manager::CameraInfoManager>(ir_nh, ir_name, ir_info_url_);
00222
00223 get_serial_server = nh_.advertiseService("get_serial", &AstraDriver::getSerialCb, this);
00224 get_device_type_server = nh_.advertiseService("get_device_type", &AstraDriver::getDeviceTypeCb, this);
00225 get_ir_gain_server = nh_.advertiseService("get_ir_gain", &AstraDriver::getIRGainCb, this);
00226 set_ir_gain_server = nh_.advertiseService("set_ir_gain", &AstraDriver::setIRGainCb, this);
00227 get_ir_exposure_server = nh_.advertiseService("get_ir_exposure", &AstraDriver::getIRExposureCb, this);
00228 set_ir_exposure_server = nh_.advertiseService("set_ir_exposure", &AstraDriver::setIRExposureCb, this);
00229 set_ir_flood_server = nh_.advertiseService("set_ir_flood", &AstraDriver::setIRFloodCb, this);
00230 set_laser_server = nh_.advertiseService("set_laser", &AstraDriver::setLaserCb, this);
00231 reset_ir_gain_server = nh_.advertiseService("reset_ir_gain", &AstraDriver::resetIRGainCb, this);
00232 reset_ir_exposure_server = nh_.advertiseService("reset_ir_exposure", &AstraDriver::resetIRExposureCb, this);
00233 get_camera_info = nh_.advertiseService("get_camera_info", &AstraDriver::getCameraInfoCb, this);
00234 }
00235
00236 bool AstraDriver::getSerialCb(astra_camera::GetSerialRequest& req, astra_camera::GetSerialResponse& res)
00237 {
00238 res.serial = device_manager_->getSerial(device_->getUri());
00239 return true;
00240 }
00241
00242 bool AstraDriver::getDeviceTypeCb(astra_camera::GetDeviceTypeRequest& req, astra_camera::GetDeviceTypeResponse& res)
00243 {
00244 res.device_type = std::string(device_->getDeviceType());
00245 return true;
00246 }
00247
00248 bool AstraDriver::getIRGainCb(astra_camera::GetIRGainRequest& req, astra_camera::GetIRGainResponse& res)
00249 {
00250 res.gain = device_->getIRGain();
00251 return true;
00252 }
00253
00254 bool AstraDriver::setIRGainCb(astra_camera::SetIRGainRequest& req, astra_camera::SetIRGainResponse& res)
00255 {
00256 device_->setIRGain(req.gain);
00257 return true;
00258 }
00259
00260 bool AstraDriver::getIRExposureCb(astra_camera::GetIRExposureRequest& req, astra_camera::GetIRExposureResponse& res)
00261 {
00262 res.exposure = device_->getIRExposure();
00263 return true;
00264 }
00265
00266 bool AstraDriver::setIRExposureCb(astra_camera::SetIRExposureRequest& req, astra_camera::SetIRExposureResponse& res)
00267 {
00268 device_->setIRExposure(req.exposure);
00269 return true;
00270 }
00271
00272 bool AstraDriver::setLaserCb(astra_camera::SetLaserRequest& req, astra_camera::SetLaserResponse& res)
00273 {
00274 device_->setLaser(req.enable);
00275 return true;
00276 }
00277
00278 bool AstraDriver::resetIRGainCb(astra_camera::ResetIRGainRequest& req, astra_camera::ResetIRGainResponse& res)
00279 {
00280 device_->setIRGain(0x8);
00281 return true;
00282 }
00283
00284 bool AstraDriver::resetIRExposureCb(astra_camera::ResetIRExposureRequest& req, astra_camera::ResetIRExposureResponse& res)
00285 {
00286 device_->setIRExposure(0x419);
00287 return true;
00288 }
00289
00290 bool AstraDriver::getCameraInfoCb(astra_camera::GetCameraInfoRequest& req, astra_camera::GetCameraInfoResponse& res)
00291 {
00292 res.info = convertAstraCameraInfo(device_->getCameraParams(), ros::Time::now());
00293 return true;
00294 }
00295
00296 bool AstraDriver::setIRFloodCb(astra_camera::SetIRFloodRequest& req, astra_camera::SetIRFloodResponse& res)
00297 {
00298 device_->setIRFlood(req.enable);
00299 return true;
00300 }
00301
00302 void AstraDriver::configCb(Config &config, uint32_t level)
00303 {
00304 if (device_->getDeviceTypeNo() == OB_STEREO_S_NO)
00305 {
00306 config.depth_mode = 13;
00307 config.ir_mode = 13;
00308 }
00309 else if (device_->getDeviceTypeNo() == OB_EMBEDDED_S_NO)
00310 {
00311 config.depth_mode = 13;
00312 config.ir_mode = 13;
00313 uvc_flip_ = 1;
00314 }
00315 bool stream_reset = false;
00316
00317 rgb_preferred_ = config.rgb_preferred;
00318
00319 if (config_init_ && old_config_.rgb_preferred != config.rgb_preferred)
00320 imageConnectCb();
00321
00322 depth_ir_offset_x_ = config.depth_ir_offset_x;
00323 depth_ir_offset_y_ = config.depth_ir_offset_y;
00324 z_offset_mm_ = config.z_offset_mm;
00325 z_scaling_ = config.z_scaling;
00326
00327 ir_time_offset_ = ros::Duration(config.ir_time_offset);
00328 color_time_offset_ = ros::Duration(config.color_time_offset);
00329 depth_time_offset_ = ros::Duration(config.depth_time_offset);
00330
00331 if (lookupVideoModeFromDynConfig(config.ir_mode, ir_video_mode_)<0)
00332 {
00333 ROS_ERROR("Undefined IR video mode received from dynamic reconfigure");
00334 exit(-1);
00335 }
00336
00337 if (lookupVideoModeFromDynConfig(config.color_mode, color_video_mode_)<0)
00338 {
00339 ROS_ERROR("Undefined color video mode received from dynamic reconfigure");
00340 exit(-1);
00341 }
00342
00343 if (lookupVideoModeFromDynConfig(config.depth_mode, depth_video_mode_)<0)
00344 {
00345 ROS_ERROR("Undefined depth video mode received from dynamic reconfigure");
00346 exit(-1);
00347 }
00348
00349
00350
00351 ir_video_mode_.pixel_format_ = PIXEL_FORMAT_GRAY16;
00352 color_video_mode_.pixel_format_ = PIXEL_FORMAT_RGB888;
00353 depth_video_mode_.pixel_format_ = PIXEL_FORMAT_DEPTH_1_MM;
00354
00355 color_depth_synchronization_ = config.color_depth_synchronization;
00356 depth_registration_ = config.depth_registration;
00357
00358 auto_exposure_ = config.auto_exposure;
00359 auto_white_balance_ = config.auto_white_balance;
00360
00361 use_device_time_ = config.use_device_time;
00362
00363 data_skip_ = config.data_skip+1;
00364
00365 applyConfigToOpenNIDevice();
00366
00367 config_init_ = true;
00368
00369 old_config_ = config;
00370 }
00371
00372 void AstraDriver::setIRVideoMode(const AstraVideoMode& ir_video_mode)
00373 {
00374 if (device_->isIRVideoModeSupported(ir_video_mode))
00375 {
00376 if (ir_video_mode != device_->getIRVideoMode())
00377 {
00378 device_->setIRVideoMode(ir_video_mode);
00379 }
00380
00381 }
00382 else
00383 {
00384 ROS_ERROR_STREAM("Unsupported IR video mode - " << ir_video_mode);
00385 }
00386 }
00387 void AstraDriver::setColorVideoMode(const AstraVideoMode& color_video_mode)
00388 {
00389 if (device_->isColorVideoModeSupported(color_video_mode))
00390 {
00391 if (color_video_mode != device_->getColorVideoMode())
00392 {
00393 device_->setColorVideoMode(color_video_mode);
00394 }
00395 }
00396 else
00397 {
00398 ROS_ERROR_STREAM("Unsupported color video mode - " << color_video_mode);
00399 }
00400 }
00401 void AstraDriver::setDepthVideoMode(const AstraVideoMode& depth_video_mode)
00402 {
00403 if (device_->isDepthVideoModeSupported(depth_video_mode))
00404 {
00405 if (depth_video_mode != device_->getDepthVideoMode())
00406 {
00407 device_->setDepthVideoMode(depth_video_mode);
00408 }
00409 }
00410 else
00411 {
00412 ROS_ERROR_STREAM("Unsupported depth video mode - " << depth_video_mode);
00413 }
00414 }
00415
00416 void AstraDriver::applyConfigToOpenNIDevice()
00417 {
00418
00419 data_skip_ir_counter_ = 0;
00420 data_skip_color_counter_= 0;
00421 data_skip_depth_counter_ = 0;
00422
00423 setIRVideoMode(ir_video_mode_);
00424 if (device_->hasColorSensor())
00425 {
00426 setColorVideoMode(color_video_mode_);
00427 }
00428 setDepthVideoMode(depth_video_mode_);
00429
00430 if (device_->isImageRegistrationModeSupported())
00431 {
00432 try
00433 {
00434 if (!config_init_ || (old_config_.depth_registration != depth_registration_))
00435 device_->setImageRegistrationMode(depth_registration_);
00436 }
00437 catch (const AstraException& exception)
00438 {
00439 ROS_ERROR("Could not set image registration. Reason: %s", exception.what());
00440 }
00441 }
00442
00443 try
00444 {
00445 if (!config_init_ || (old_config_.color_depth_synchronization != color_depth_synchronization_))
00446 device_->setDepthColorSync(color_depth_synchronization_);
00447 }
00448 catch (const AstraException& exception)
00449 {
00450 ROS_ERROR("Could not set color depth synchronization. Reason: %s", exception.what());
00451 }
00452
00453 try
00454 {
00455 if (!config_init_ || (old_config_.auto_exposure != auto_exposure_))
00456 device_->setAutoExposure(auto_exposure_);
00457 }
00458 catch (const AstraException& exception)
00459 {
00460 ROS_ERROR("Could not set auto exposure. Reason: %s", exception.what());
00461 }
00462
00463 try
00464 {
00465 if (!config_init_ || (old_config_.auto_white_balance != auto_white_balance_))
00466 device_->setAutoWhiteBalance(auto_white_balance_);
00467 }
00468 catch (const AstraException& exception)
00469 {
00470 ROS_ERROR("Could not set auto white balance. Reason: %s", exception.what());
00471 }
00472
00473 device_->setUseDeviceTimer(use_device_time_);
00474
00475 }
00476
00477 void AstraDriver::imageConnectCb()
00478 {
00479 boost::lock_guard<boost::mutex> lock(connect_mutex_);
00480
00481 bool ir_started = device_->isIRStreamStarted();
00482 bool color_started = device_->isColorStreamStarted();
00483
00484 ir_subscribers_ = pub_ir_.getNumSubscribers() > 0;
00485 color_subscribers_ = pub_color_.getNumSubscribers() > 0;
00486
00487 if (color_subscribers_ && (!ir_subscribers_ || rgb_preferred_))
00488 {
00489 if (ir_subscribers_)
00490 ROS_ERROR("Cannot stream RGB and IR at the same time. Streaming RGB only.");
00491
00492 if (ir_started)
00493 {
00494 ROS_INFO("Stopping IR stream.");
00495 device_->stopIRStream();
00496 }
00497
00498 if (!color_started)
00499 {
00500 device_->setColorFrameCallback(boost::bind(&AstraDriver::newColorFrameCallback, this, _1));
00501
00502 ROS_INFO("Starting color stream.");
00503 device_->startColorStream();
00504 }
00505 }
00506 else if (ir_subscribers_ && (!color_subscribers_ || !rgb_preferred_))
00507 {
00508
00509 if (color_subscribers_)
00510 ROS_ERROR("Cannot stream RGB and IR at the same time. Streaming IR only.");
00511
00512 if (color_started)
00513 {
00514 ROS_INFO("Stopping color stream.");
00515 device_->stopColorStream();
00516 }
00517
00518 if (!ir_started)
00519 {
00520 device_->setIRFrameCallback(boost::bind(&AstraDriver::newIRFrameCallback, this, _1));
00521
00522 ROS_INFO("Starting IR stream.");
00523 device_->startIRStream();
00524 }
00525 }
00526 else
00527 {
00528 if (color_started)
00529 {
00530 ROS_INFO("Stopping color stream.");
00531 device_->stopColorStream();
00532 }
00533 if (ir_started)
00534 {
00535 ROS_INFO("Stopping IR stream.");
00536 device_->stopIRStream();
00537 }
00538 }
00539 }
00540
00541 void AstraDriver::depthConnectCb()
00542 {
00543 boost::lock_guard<boost::mutex> lock(connect_mutex_);
00544
00545 depth_subscribers_ = pub_depth_.getNumSubscribers() > 0;
00546 depth_raw_subscribers_ = pub_depth_raw_.getNumSubscribers() > 0;
00547 projector_info_subscribers_ = pub_projector_info_.getNumSubscribers() > 0;
00548
00549 bool need_depth = depth_subscribers_ || depth_raw_subscribers_;
00550
00551 if (need_depth && !device_->isDepthStreamStarted())
00552 {
00553 device_->setDepthFrameCallback(boost::bind(&AstraDriver::newDepthFrameCallback, this, _1));
00554
00555 ROS_INFO("Starting depth stream.");
00556 device_->startDepthStream();
00557 }
00558 else if (!need_depth && device_->isDepthStreamStarted())
00559 {
00560 ROS_INFO("Stopping depth stream.");
00561 device_->stopDepthStream();
00562 }
00563 }
00564
00565 void AstraDriver::newIRFrameCallback(sensor_msgs::ImagePtr image)
00566 {
00567 if ((++data_skip_ir_counter_)%data_skip_==0)
00568 {
00569 data_skip_ir_counter_ = 0;
00570
00571 if (ir_subscribers_)
00572 {
00573 image->header.frame_id = ir_frame_id_;
00574 image->header.stamp = image->header.stamp + ir_time_offset_;
00575
00576 pub_ir_.publish(image, getIRCameraInfo(image->width, image->height, image->header.stamp));
00577 }
00578 }
00579 }
00580
00581 void AstraDriver::newColorFrameCallback(sensor_msgs::ImagePtr image)
00582 {
00583 if ((++data_skip_color_counter_)%data_skip_==0)
00584 {
00585 data_skip_color_counter_ = 0;
00586
00587 if (color_subscribers_)
00588 {
00589 image->header.frame_id = color_frame_id_;
00590 image->header.stamp = image->header.stamp + color_time_offset_;
00591
00592 pub_color_.publish(image, getColorCameraInfo(image->width, image->height, image->header.stamp));
00593 }
00594 }
00595 }
00596
00597 void AstraDriver::newDepthFrameCallback(sensor_msgs::ImagePtr image)
00598 {
00599 if ((++data_skip_depth_counter_)%data_skip_==0)
00600 {
00601
00602 data_skip_depth_counter_ = 0;
00603
00604 if (depth_raw_subscribers_||depth_subscribers_||projector_info_subscribers_)
00605 {
00606 image->header.stamp = image->header.stamp + depth_time_offset_;
00607
00608 if (z_offset_mm_ != 0)
00609 {
00610 uint16_t* data = reinterpret_cast<uint16_t*>(&image->data[0]);
00611 for (unsigned int i = 0; i < image->width * image->height; ++i)
00612 if (data[i] != 0)
00613 data[i] += z_offset_mm_;
00614 }
00615
00616 if (fabs(z_scaling_ - 1.0) > 1e-6)
00617 {
00618 uint16_t* data = reinterpret_cast<uint16_t*>(&image->data[0]);
00619 for (unsigned int i = 0; i < image->width * image->height; ++i)
00620 if (data[i] != 0)
00621 data[i] = static_cast<uint16_t>(data[i] * z_scaling_);
00622 }
00623
00624 sensor_msgs::CameraInfoPtr cam_info;
00625
00626 if (depth_registration_)
00627 {
00628 image->header.frame_id = color_frame_id_;
00629 cam_info = getColorCameraInfo(image->width, image->height, image->header.stamp);
00630 } else
00631 {
00632 image->header.frame_id = depth_frame_id_;
00633 cam_info = getDepthCameraInfo(image->width, image->height, image->header.stamp);
00634 }
00635
00636 if (depth_raw_subscribers_)
00637 {
00638 pub_depth_raw_.publish(image, cam_info);
00639 }
00640
00641 if (depth_subscribers_ )
00642 {
00643 sensor_msgs::ImageConstPtr floating_point_image = rawToFloatingPointConversion(image);
00644 pub_depth_.publish(floating_point_image, cam_info);
00645 }
00646
00647
00648 if (projector_info_subscribers_)
00649 {
00650 pub_projector_info_.publish(getProjectorCameraInfo(image->width, image->height, image->header.stamp));
00651 }
00652 }
00653 }
00654 }
00655
00656 sensor_msgs::CameraInfo AstraDriver::convertAstraCameraInfo(OBCameraParams p, ros::Time time) const
00657 {
00658 sensor_msgs::CameraInfo info;
00659
00660
00661 info.distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00662 info.D.resize(5, 0.0);
00663 info.D[0] = p.r_k[0];
00664 info.D[1] = p.r_k[1];
00665 info.D[2] = p.r_k[3];
00666 info.D[3] = p.r_k[4];
00667 info.D[4] = p.r_k[2];
00668
00669 info.K.assign(0.0);
00670 info.K[0] = p.r_intr_p[0];
00671 info.K[2] = p.r_intr_p[2];
00672 info.K[4] = p.r_intr_p[1];
00673 info.K[5] = p.r_intr_p[3];
00674 info.K[8] = 1.0;
00675
00676 info.R.assign(0.0);
00677 for (int i = 0; i < 9; i++)
00678 {
00679 info.R[i] = p.r2l_r[i];
00680 }
00681
00682 info.P.assign(0.0);
00683 info.P[0] = info.K[0];
00684 info.P[2] = info.K[2];
00685 info.P[3] = p.r2l_t[0];
00686 info.P[5] = info.K[4];
00687 info.P[6] = info.K[5];
00688 info.P[7] = p.r2l_t[1];
00689 info.P[10] = 1.0;
00690 info.P[11] = p.r2l_t[2];
00691
00692 info.header.stamp = time;
00693 info.header.frame_id = color_frame_id_;
00694 return info;
00695 }
00696
00697
00698 sensor_msgs::CameraInfoPtr AstraDriver::getDefaultCameraInfo(int width, int height, double f) const
00699 {
00700 sensor_msgs::CameraInfoPtr info = boost::make_shared<sensor_msgs::CameraInfo>();
00701
00702 info->width = width;
00703 info->height = height;
00704
00705
00706 info->D.resize(5, 0.0);
00707 info->distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00708
00709
00710 info->K.assign(0.0);
00711 info->K[0] = info->K[4] = f;
00712 info->K[2] = (width / 2) - 0.5;
00713
00714
00715 info->K[5] = (width * (3./8.)) - 0.5;
00716 info->K[8] = 1.0;
00717
00718
00719 info->R.assign(0.0);
00720 info->R[0] = info->R[4] = info->R[8] = 1.0;
00721
00722
00723 info->P.assign(0.0);
00724 info->P[0] = info->P[5] = f;
00725 info->P[2] = info->K[2];
00726 info->P[6] = info->K[5];
00727 info->P[10] = 1.0;
00728
00729 return info;
00730 }
00731
00733 sensor_msgs::CameraInfoPtr AstraDriver::getColorCameraInfo(int width, int height, ros::Time time) const
00734 {
00735 sensor_msgs::CameraInfoPtr info;
00736
00737 if (color_info_manager_->isCalibrated())
00738 {
00739 info = boost::make_shared<sensor_msgs::CameraInfo>(color_info_manager_->getCameraInfo());
00740 if ( info->width != width )
00741 {
00742
00743 ROS_WARN_ONCE("Image resolution doesn't match calibration of the RGB camera. Using default parameters.");
00744 info = getDefaultCameraInfo(width, height, device_->getColorFocalLength(height));
00745 }
00746 }
00747 else
00748 {
00749
00750 if (device_->getDeviceTypeNo() == OB_STEREO_S_NO || device_->getDeviceTypeNo() == OB_EMBEDDED_S_NO ||
00751 device_->getDeviceTypeNo() == OB_ASTRA_PRO_NO)
00752 {
00753 sensor_msgs::CameraInfo cinfo = convertAstraCameraInfo(device_->getCameraParams(), time);
00754 info = boost::make_shared<sensor_msgs::CameraInfo>(ir_info_manager_->getCameraInfo());
00755 info->D.resize(5, 0.0);
00756 info->K.assign(0.0);
00757 info->R.assign(0.0);
00758 info->P.assign(0.0);
00759 info->distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00760 info->width = width;
00761 info->height = height;
00762 for (int i = 0; i < 5; i++)
00763 {
00764 info->D[i] = cinfo.D[i];
00765 }
00766
00767 for (int i = 0; i < 9; i++)
00768 {
00769 info->K[i] = cinfo.K[i];
00770 info->R[i] = cinfo.R[i];
00771 }
00772
00773 for (int i = 0; i < 12; i++)
00774 {
00775 info->P[i] = cinfo.P[i];
00776 }
00777 }
00778 else
00779 {
00780 info = getDefaultCameraInfo(width, height, device_->getColorFocalLength(height));
00781 }
00782 }
00783
00784
00785 info->header.stamp = time;
00786 info->header.frame_id = color_frame_id_;
00787
00788 return info;
00789 }
00790
00791
00792 sensor_msgs::CameraInfoPtr AstraDriver::getIRCameraInfo(int width, int height, ros::Time time) const
00793 {
00794 sensor_msgs::CameraInfoPtr info;
00795
00796 if (ir_info_manager_->isCalibrated())
00797 {
00798 info = boost::make_shared<sensor_msgs::CameraInfo>(ir_info_manager_->getCameraInfo());
00799 if ( info->width != width )
00800 {
00801
00802 ROS_WARN_ONCE("Image resolution doesn't match calibration of the IR camera. Using default parameters.");
00803 info = getDefaultCameraInfo(width, height, device_->getIRFocalLength(height));
00804 }
00805 }
00806 else
00807 {
00808
00809 info = getDefaultCameraInfo(width, height, device_->getDepthFocalLength(height));
00810 if (device_->getDeviceTypeNo() == OB_STEREO_S_NO || device_->getDeviceTypeNo() == OB_EMBEDDED_S_NO ||
00811 device_->getDeviceTypeNo() == OB_ASTRA_PRO_NO)
00812 {
00813 OBCameraParams p = device_->getCameraParams();
00814 info->D.resize(5, 0.0);
00815 info->D[0] = p.l_k[0];
00816 info->D[1] = p.l_k[1];
00817 info->D[2] = p.l_k[3];
00818 info->D[3] = p.l_k[4];
00819 info->D[4] = p.l_k[2];
00820
00821 info->K.assign(0.0);
00822 info->K[0] = (1 - uvc_flip_)*p.r_intr_p[0] + (uvc_flip_)*(-p.r_intr_p[0]);
00823 info->K[2] = (1 - uvc_flip_)*p.r_intr_p[2] + (uvc_flip_)*(width - p.r_intr_p[2]);
00824 info->K[4] = p.l_intr_p[1];
00825 info->K[5] = p.l_intr_p[3];
00826 info->K[8] = 1.0;
00827
00828 info->P.assign(0.0);
00829 info->P[0] = info->K[0];
00830 info->P[2] = info->K[2];
00831 info->P[5] = info->K[4];
00832 info->P[6] = info->K[5];
00833 info->P[10] = 1.0;
00834 }
00835 }
00836
00837
00838 info->header.stamp = time;
00839 info->header.frame_id = depth_frame_id_;
00840
00841 return info;
00842 }
00843
00844 sensor_msgs::CameraInfoPtr AstraDriver::getDepthCameraInfo(int width, int height, ros::Time time) const
00845 {
00846
00847
00848
00849
00850 double scaling = (double)width / 640;
00851
00852 sensor_msgs::CameraInfoPtr info = getIRCameraInfo(width, height, time);
00853 info->K[2] -= depth_ir_offset_x_*scaling;
00854 info->K[5] -= depth_ir_offset_y_*scaling;
00855 info->P[2] -= depth_ir_offset_x_*scaling;
00856 info->P[6] -= depth_ir_offset_y_*scaling;
00857
00859 return info;
00860 }
00861
00862 sensor_msgs::CameraInfoPtr AstraDriver::getProjectorCameraInfo(int width, int height, ros::Time time) const
00863 {
00864
00865
00866
00867 sensor_msgs::CameraInfoPtr info = getDepthCameraInfo(width, height, time);
00868
00869 info->P[3] = -device_->getBaseline() * info->P[0];
00870 return info;
00871 }
00872
00873 void AstraDriver::readConfigFromParameterServer()
00874 {
00875 if (!pnh_.getParam("device_id", device_id_))
00876 {
00877 ROS_WARN ("~device_id is not set! Using first device.");
00878 device_id_ = "#1";
00879 }
00880
00881
00882 pnh_.param("ir_frame_id", ir_frame_id_, std::string("/openni_ir_optical_frame"));
00883 pnh_.param("rgb_frame_id", color_frame_id_, std::string("/openni_rgb_optical_frame"));
00884 pnh_.param("depth_frame_id", depth_frame_id_, std::string("/openni_depth_optical_frame"));
00885
00886 ROS_DEBUG("ir_frame_id = '%s' ", ir_frame_id_.c_str());
00887 ROS_DEBUG("rgb_frame_id = '%s' ", color_frame_id_.c_str());
00888 ROS_DEBUG("depth_frame_id = '%s' ", depth_frame_id_.c_str());
00889
00890 pnh_.param("rgb_camera_info_url", color_info_url_, std::string());
00891 pnh_.param("depth_camera_info_url", ir_info_url_, std::string());
00892
00893 }
00894
00895 std::string AstraDriver::resolveDeviceURI(const std::string& device_id)
00896 {
00897
00898
00899 boost::shared_ptr<std::vector<std::string> > available_device_URIs =
00900 device_manager_->getConnectedDeviceURIs();
00901
00902
00903 #if 0
00904 for (size_t i = 0; i < available_device_URIs->size(); ++i)
00905 {
00906 std::string s = (*available_device_URIs)[i];
00907 ROS_WARN("------------id %d, available_device_uri is %s-----------", i, s.c_str());
00908 }
00909 #endif
00910
00911
00912 if (device_id.size() > 1 && device_id[0] == '#')
00913 {
00914 std::istringstream device_number_str(device_id.substr(1));
00915 int device_number;
00916 device_number_str >> device_number;
00917 int device_index = device_number - 1;
00918 if (device_index >= available_device_URIs->size() || device_index < 0)
00919 {
00920 THROW_OPENNI_EXCEPTION(
00921 "Invalid device number %i, there are %zu devices connected.",
00922 device_number, available_device_URIs->size());
00923 }
00924 else
00925 {
00926 return available_device_URIs->at(device_index);
00927 }
00928 }
00929
00930
00931
00932
00933 else if (device_id.size() > 1 && device_id.find('@') != std::string::npos && device_id.find('/') == std::string::npos)
00934 {
00935
00936 size_t index = device_id.find('@');
00937 if (index <= 0)
00938 {
00939 THROW_OPENNI_EXCEPTION(
00940 "%s is not a valid device URI, you must give the bus number before the @.",
00941 device_id.c_str());
00942 }
00943 if (index >= device_id.size() - 1)
00944 {
00945 THROW_OPENNI_EXCEPTION(
00946 "%s is not a valid device URI, you must give a number after the @, specify 0 for first device",
00947 device_id.c_str());
00948 }
00949
00950
00951 std::istringstream device_number_str(device_id.substr(index+1));
00952 int device_number;
00953 device_number_str >> device_number;
00954
00955
00956 std::string bus = device_id.substr(0, index);
00957 bus.insert(0, "@");
00958
00959 for (size_t i = 0; i < available_device_URIs->size(); ++i)
00960 {
00961 std::string s = (*available_device_URIs)[i];
00962 if (s.find(bus) != std::string::npos)
00963 {
00964
00965 --device_number;
00966 if (device_number <= 0)
00967 return s;
00968 }
00969 }
00970
00971 THROW_OPENNI_EXCEPTION("Device not found %s", device_id.c_str());
00972 }
00973 else
00974 {
00975
00976 for(std::vector<std::string>::const_iterator it = available_device_URIs->begin();
00977 it != available_device_URIs->end(); ++it)
00978 {
00979 #if 0
00980 try
00981 {
00982 std::string serial = device_manager_->getSerial(*it);
00983 if (serial.size() > 0 && device_id == serial)
00984 return *it;
00985 }
00986 #else
00987 try
00988 {
00989 std::set<std::string>::iterator iter;
00990 if((iter = alreadyOpen.find(*it)) == alreadyOpen.end())
00991 {
00992
00993 std::string serial = device_manager_->getSerial(*it);
00994 if (serial.size() > 0 && device_id == serial)
00995 {
00996 alreadyOpen.insert(*it);
00997 return *it;
00998 }
00999 }
01000 }
01001 #endif
01002 catch (const AstraException& exception)
01003 {
01004 ROS_WARN("Could not query serial number of device \"%s\":", exception.what());
01005 }
01006 }
01007
01008
01009 bool match_found = false;
01010 std::string matched_uri;
01011 for (size_t i = 0; i < available_device_URIs->size(); ++i)
01012 {
01013 std::string s = (*available_device_URIs)[i];
01014 if (s.find(device_id) != std::string::npos)
01015 {
01016 if (!match_found)
01017 {
01018 matched_uri = s;
01019 match_found = true;
01020 }
01021 else
01022 {
01023
01024 THROW_OPENNI_EXCEPTION("Two devices match the given device id '%s': %s and %s.", device_id.c_str(), matched_uri.c_str(), s.c_str());
01025 }
01026 }
01027 }
01028 return matched_uri;
01029 }
01030
01031 return "INVALID";
01032 }
01033
01034 void AstraDriver::initDevice()
01035 {
01036 while (ros::ok() && !device_)
01037 {
01038 try
01039 {
01040 std::string device_URI = resolveDeviceURI(device_id_);
01041 #if 0
01042 if( device_URI == "" )
01043 {
01044 boost::this_thread::sleep(boost::posix_time::milliseconds(500));
01045 continue;
01046 }
01047 #endif
01048 device_ = device_manager_->getDevice(device_URI);
01049 }
01050 catch (const AstraException& exception)
01051 {
01052 if (!device_)
01053 {
01054 ROS_INFO("No matching device found.... waiting for devices. Reason: %s", exception.what());
01055 boost::this_thread::sleep(boost::posix_time::seconds(3));
01056 continue;
01057 }
01058 else
01059 {
01060 ROS_ERROR("Could not retrieve device. Reason: %s", exception.what());
01061 exit(-1);
01062 }
01063 }
01064 }
01065
01066 while (ros::ok() && !device_->isValid())
01067 {
01068 ROS_DEBUG("Waiting for device initialization..");
01069 boost::this_thread::sleep(boost::posix_time::milliseconds(100));
01070 }
01071
01072 }
01073
01074 void AstraDriver::genVideoModeTableMap()
01075 {
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095 video_modes_lookup_.clear();
01096
01097 AstraVideoMode video_mode;
01098
01099
01100 video_mode.x_resolution_ = 1280;
01101 video_mode.y_resolution_ = 1024;
01102 video_mode.frame_rate_ = 30;
01103
01104 video_modes_lookup_[1] = video_mode;
01105
01106
01107 video_mode.x_resolution_ = 1280;
01108 video_mode.y_resolution_ = 1024;
01109 video_mode.frame_rate_ = 15;
01110
01111 video_modes_lookup_[2] = video_mode;
01112
01113
01114 video_mode.x_resolution_ = 1280;
01115 video_mode.y_resolution_ = 720;
01116 video_mode.frame_rate_ = 30;
01117
01118 video_modes_lookup_[3] = video_mode;
01119
01120
01121 video_mode.x_resolution_ = 1280;
01122 video_mode.y_resolution_ = 720;
01123 video_mode.frame_rate_ = 15;
01124
01125 video_modes_lookup_[4] = video_mode;
01126
01127
01128 video_mode.x_resolution_ = 640;
01129 video_mode.y_resolution_ = 480;
01130 video_mode.frame_rate_ = 30;
01131
01132 video_modes_lookup_[5] = video_mode;
01133
01134
01135 video_mode.x_resolution_ = 640;
01136 video_mode.y_resolution_ = 480;
01137 video_mode.frame_rate_ = 25;
01138
01139 video_modes_lookup_[6] = video_mode;
01140
01141
01142 video_mode.x_resolution_ = 320;
01143 video_mode.y_resolution_ = 240;
01144 video_mode.frame_rate_ = 25;
01145
01146 video_modes_lookup_[7] = video_mode;
01147
01148
01149 video_mode.x_resolution_ = 320;
01150 video_mode.y_resolution_ = 240;
01151 video_mode.frame_rate_ = 30;
01152
01153 video_modes_lookup_[8] = video_mode;
01154
01155
01156 video_mode.x_resolution_ = 320;
01157 video_mode.y_resolution_ = 240;
01158 video_mode.frame_rate_ = 60;
01159
01160 video_modes_lookup_[9] = video_mode;
01161
01162
01163 video_mode.x_resolution_ = 160;
01164 video_mode.y_resolution_ = 120;
01165 video_mode.frame_rate_ = 25;
01166
01167 video_modes_lookup_[10] = video_mode;
01168
01169
01170 video_mode.x_resolution_ = 160;
01171 video_mode.y_resolution_ = 120;
01172 video_mode.frame_rate_ = 30;
01173
01174 video_modes_lookup_[11] = video_mode;
01175
01176
01177 video_mode.x_resolution_ = 160;
01178 video_mode.y_resolution_ = 120;
01179 video_mode.frame_rate_ = 60;
01180
01181 video_modes_lookup_[12] = video_mode;
01182
01183
01184 video_mode.x_resolution_ = 640;
01185 video_mode.y_resolution_ = 400;
01186 video_mode.frame_rate_ = 30;
01187
01188 video_modes_lookup_[13] = video_mode;
01189
01190
01191 video_mode.x_resolution_ = 320;
01192 video_mode.y_resolution_ = 200;
01193 video_mode.frame_rate_ = 30;
01194
01195 video_modes_lookup_[14] = video_mode;
01196 }
01197
01198 int AstraDriver::lookupVideoModeFromDynConfig(int mode_nr, AstraVideoMode& video_mode)
01199 {
01200 int ret = -1;
01201
01202 std::map<int, AstraVideoMode>::const_iterator it;
01203
01204 it = video_modes_lookup_.find(mode_nr);
01205
01206 if (it!=video_modes_lookup_.end())
01207 {
01208 video_mode = it->second;
01209 ret = 0;
01210 }
01211
01212 return ret;
01213 }
01214
01215 sensor_msgs::ImageConstPtr AstraDriver::rawToFloatingPointConversion(sensor_msgs::ImageConstPtr raw_image)
01216 {
01217 static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
01218
01219 sensor_msgs::ImagePtr new_image = boost::make_shared<sensor_msgs::Image>();
01220
01221 new_image->header = raw_image->header;
01222 new_image->width = raw_image->width;
01223 new_image->height = raw_image->height;
01224 new_image->is_bigendian = 0;
01225 new_image->encoding = sensor_msgs::image_encodings::TYPE_32FC1;
01226 new_image->step = sizeof(float)*raw_image->width;
01227
01228 std::size_t data_size = new_image->width*new_image->height;
01229 new_image->data.resize(data_size*sizeof(float));
01230
01231 const unsigned short* in_ptr = reinterpret_cast<const unsigned short*>(&raw_image->data[0]);
01232 float* out_ptr = reinterpret_cast<float*>(&new_image->data[0]);
01233
01234 for (std::size_t i = 0; i<data_size; ++i, ++in_ptr, ++out_ptr)
01235 {
01236 if (*in_ptr==0 || *in_ptr==0x7FF)
01237 {
01238 *out_ptr = bad_point;
01239 } else
01240 {
01241 *out_ptr = static_cast<float>(*in_ptr)/1000.0f;
01242 }
01243 }
01244
01245 return new_image;
01246 }
01247
01248 }