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
00034
00035
00036
00037
00038
00039 #include "openni_nodelet.h"
00040 #include "openni_camera/openni_device_kinect.h"
00041 #include "openni_camera/openni_image.h"
00042 #include "openni_camera/openni_depth_image.h"
00043 #include "openni_camera/openni_ir_image.h"
00044 #include <sensor_msgs/image_encodings.h>
00045 #include <sensor_msgs/distortion_models.h>
00046 #include <boost/algorithm/string/replace.hpp>
00047 #include "names.h"
00048
00049 using namespace std;
00050 using namespace openni_wrapper;
00051 namespace openni_camera
00052 {
00053 inline bool operator == (const XnMapOutputMode& mode1, const XnMapOutputMode& mode2)
00054 {
00055 return (mode1.nXRes == mode2.nXRes && mode1.nYRes == mode2.nYRes && mode1.nFPS == mode2.nFPS);
00056 }
00057 inline bool operator != (const XnMapOutputMode& mode1, const XnMapOutputMode& mode2)
00058 {
00059 return !(mode1 == mode2);
00060 }
00061
00062 OpenNINodelet::~OpenNINodelet ()
00063 {
00064 device_->stopDepthStream ();
00065 device_->stopImageStream ();
00066 }
00067
00068 void OpenNINodelet::onInit ()
00069 {
00070 ros::NodeHandle& nh = getNodeHandle();
00071 ros::NodeHandle& param_nh = getPrivateNodeHandle();
00072 image_transport::ImageTransport it(nh);
00074
00075 updateModeMaps();
00076 setupDevice();
00077
00078
00079 reconfigure_server_.reset( new ReconfigureServer(param_nh) );
00080 reconfigure_server_->setCallback(boost::bind(&OpenNINodelet::configCb, this, _1, _2));
00081
00082
00083 param_nh.param("rgb_frame_id", rgb_frame_id_, string("/openni_rgb_optical_frame"));
00084 param_nh.param("depth_frame_id", depth_frame_id_, string("/openni_depth_optical_frame"));
00085 NODELET_INFO("rgb_frame_id = '%s' ", rgb_frame_id_.c_str());
00086 NODELET_INFO("depth_frame_id = '%s' ", depth_frame_id_.c_str());
00087
00088
00089
00090 param_nh.param("depth_ir_offset_x", depth_ir_offset_x_, 5.0);
00091 param_nh.param("depth_ir_offset_y", depth_ir_offset_y_, 4.0);
00092
00093
00094 rgb_info_manager_ = boost::make_shared<CameraInfoManager>(ros::NodeHandle(nh, "rgb"));
00095 ir_info_manager_ = boost::make_shared<CameraInfoManager>(ros::NodeHandle(nh, "ir"));
00096 std::string serial_number = device_->getSerialNumber();
00097 std::string rgb_name, ir_name;
00098 if (serial_number.empty())
00099 {
00100 rgb_name = "rgb";
00101 ir_name = "depth";
00102 }
00103 else
00104 {
00105 rgb_name = "rgb_" + serial_number;
00106 ir_name = "depth_" + serial_number;
00107 }
00108 rgb_info_manager_->setCameraName(rgb_name);
00109 ir_info_manager_ ->setCameraName(ir_name);
00110
00111
00112
00113 std::string info_url;
00114 if (param_nh.getParam("rgb_camera_info_url", info_url))
00115 {
00116 boost::replace_all(info_url, "%s", rgb_name);
00117 if (!rgb_info_manager_->loadCameraInfo(info_url))
00118 NODELET_WARN("Failed to load RGB camera calibration, using default parameters");
00119 }
00120 else
00121 NODELET_INFO("RGB camera uncalibrated, using default parameters");
00122
00123 if (param_nh.getParam("depth_camera_info_url", info_url))
00124 {
00125 boost::replace_all(info_url, "%s", ir_name);
00126 if (!ir_info_manager_->loadCameraInfo(info_url))
00127 NODELET_WARN("Failed to load IR camera calibration, using default parameters");
00128 }
00129 else
00130 NODELET_INFO("IR camera uncalibrated, using default parameters");
00131
00132
00133 image_transport::SubscriberStatusCallback itssc = boost::bind(&OpenNINodelet::connectCb, this);
00134 ros::SubscriberStatusCallback rssc = boost::bind(&OpenNINodelet::connectCb, this);
00135 typedef sensor_msgs::CameraInfo CI;
00136 pub_rgb_raw_ = it.advertise (resolve(nh, "rgb/image_raw"), 1, itssc, itssc);
00137 pub_rgb_mono_ = it.advertise (resolve(nh, "rgb/image_mono"), 1, itssc, itssc);
00138 pub_rgb_color_ = it.advertise (resolve(nh, "rgb/image_color"), 1, itssc, itssc);
00139 pub_rgb_info_ = nh.advertise<CI>(resolve(nh, "rgb/camera_info"), 1, rssc, rssc);
00140 pub_depth_ = it.advertise (resolve(nh, "depth/image_raw"), 1, itssc, itssc);
00141 pub_depth_info_ = nh.advertise<CI>(resolve(nh, "depth/camera_info"), 1, rssc, rssc);
00142 pub_ir_ = it.advertise (resolve(nh, "ir/image_raw"), 1, itssc, itssc);
00143 pub_ir_info_ = nh.advertise<CI>(resolve(nh, "ir/camera_info"), 1, rssc, rssc);
00144 pub_depth_registered_ = it.advertise (resolve(nh, "depth_registered/image_raw"), 1, itssc, itssc);
00145 pub_depth_registered_info_ = nh.advertise<CI>(resolve(nh, "depth_registered/camera_info"), 1, rssc, rssc);
00146
00147
00148 if (param_nh.getParam("time_out", time_out_) && time_out_ > 0.0)
00149 {
00150 time_stamp_ = ros::Time(0,0);
00151 watch_dog_timer_ = nh.createTimer(ros::Duration(time_out_), &OpenNINodelet::watchDog, this);
00152 }
00153 }
00154
00155 void OpenNINodelet::setupDevice ()
00156 {
00157
00158 OpenNIDriver& driver = OpenNIDriver::getInstance ();
00159
00160 do {
00161 driver.updateDeviceList ();
00162
00163 if (driver.getNumberDevices () == 0)
00164 {
00165 NODELET_INFO ("No devices connected.... waiting for devices to be connected");
00166 sleep(3);
00167 continue;
00168 }
00169
00170 NODELET_INFO ("Number devices connected: %d", driver.getNumberDevices ());
00171 for (unsigned deviceIdx = 0; deviceIdx < driver.getNumberDevices (); ++deviceIdx)
00172 {
00173 NODELET_INFO ("%u. device on bus %03u:%02u is a %s (%03x) from %s (%03x) with serial id \'%s\'"
00174 , deviceIdx + 1, driver.getBus (deviceIdx), driver.getAddress (deviceIdx)
00175 , driver.getProductName (deviceIdx), driver.getProductID (deviceIdx), driver.getVendorName (deviceIdx)
00176 , driver.getVendorID (deviceIdx), driver.getSerialNumber (deviceIdx));
00177 }
00178
00179 try {
00180 string device_id;
00181 if (!getPrivateNodeHandle().getParam("device_id", device_id))
00182 {
00183 NODELET_WARN ("~device_id is not set! Using first device.");
00184 device_ = driver.getDeviceByIndex (0);
00185 }
00186 else if (device_id.find ('@') != string::npos)
00187 {
00188 size_t pos = device_id.find ('@');
00189 unsigned bus = atoi (device_id.substr (0, pos).c_str ());
00190 unsigned address = atoi (device_id.substr (pos + 1, device_id.length () - pos - 1).c_str ());
00191 NODELET_INFO ("Searching for device with bus@address = %d@%d", bus, address);
00192 device_ = driver.getDeviceByAddress (bus, address);
00193 }
00194 else if (device_id[0] == '#')
00195 {
00196 unsigned index = atoi (device_id.c_str () + 1);
00197 NODELET_INFO ("Searching for device with index = %d", index);
00198 device_ = driver.getDeviceByIndex (index - 1);
00199 }
00200 else
00201 {
00202 NODELET_INFO ("Searching for device with serial number = '%s'", device_id.c_str ());
00203 device_ = driver.getDeviceBySerialNumber (device_id);
00204 }
00205 }
00206 catch (const OpenNIException& exception)
00207 {
00208 if (!device_)
00209 {
00210 NODELET_INFO ("No matching device found.... waiting for devices. Reason: %s", exception.what ());
00211 sleep (3);
00212 continue;
00213 }
00214 else
00215 {
00216 NODELET_ERROR ("Could not retrieve device. Reason: %s", exception.what ());
00217 exit (-1);
00218 }
00219 }
00220 } while (!device_);
00221
00222 NODELET_INFO ("Opened '%s' on bus %d:%d with serial number '%s'", device_->getProductName (),
00223 device_->getBus (), device_->getAddress (), device_->getSerialNumber ());
00224
00225 device_->registerImageCallback(&OpenNINodelet::imageCb, *this);
00226 device_->registerDepthCallback(&OpenNINodelet::depthCb, *this);
00227 device_->registerIRCallback (&OpenNINodelet::irCb, *this);
00228 }
00229
00230 void OpenNINodelet::imageCb(boost::shared_ptr<openni_wrapper::Image> image, void* cookie)
00231 {
00232 ros::Time time = ros::Time::now () + ros::Duration(config_.image_time_offset);
00233 time_stamp_ = time;
00234
00235 if (pub_rgb_info_.getNumSubscribers() > 0)
00236 pub_rgb_info_.publish(getRgbCameraInfo(time));
00237
00238 if (pub_rgb_raw_.getNumSubscribers () > 0)
00239 publishRgbImageRaw (*image, time);
00240
00241 if (pub_rgb_mono_.getNumSubscribers () > 0)
00242 publishGrayImage (*image, time);
00243
00244 if (pub_rgb_color_.getNumSubscribers () > 0)
00245 publishRgbImage (*image, time);
00246 }
00247
00248 void OpenNINodelet::depthCb(boost::shared_ptr<openni_wrapper::DepthImage> depth_image, void* cookie)
00249 {
00250 ros::Time time = ros::Time::now () + ros::Duration(config_.depth_time_offset);
00251 time_stamp_ = time;
00252
00253 if (device_->isDepthRegistered())
00254 {
00255
00256 if (pub_depth_registered_info_.getNumSubscribers() > 0)
00257 pub_depth_registered_info_.publish(getRgbCameraInfo(time));
00258
00259 if (pub_depth_registered_.getNumSubscribers() > 0)
00260 publishDepthImageRaw(*depth_image, time, rgb_frame_id_, pub_depth_registered_);
00261 }
00262 else
00263 {
00264
00265 if (pub_depth_info_.getNumSubscribers() > 0)
00266 pub_depth_info_.publish(getDepthCameraInfo(time));
00267
00268 if (pub_depth_.getNumSubscribers() > 0)
00269 publishDepthImageRaw(*depth_image, time, depth_frame_id_, pub_depth_);
00270 }
00271 }
00272
00273 void OpenNINodelet::irCb(boost::shared_ptr<openni_wrapper::IRImage> ir_image, void* cookie)
00274 {
00275 ros::Time time = ros::Time::now() + ros::Duration(config_.depth_time_offset);
00276 time_stamp_ = time;
00277
00278 if (pub_ir_info_.getNumSubscribers() > 0)
00279 pub_ir_info_.publish(getIrCameraInfo(time));
00280
00281 if (pub_ir_.getNumSubscribers() > 0)
00282 publishIrImage(*ir_image, time);
00283 }
00284
00285 void OpenNINodelet::connectCb()
00286 {
00287
00288 if (isImageStreamRequired () && !device_->isImageStreamRunning ())
00289 {
00290
00291 if (device_->isIRStreamRunning())
00292 device_->stopIRStream();
00293
00294 device_->startImageStream ();
00295 startSynchronization ();
00296 time_stamp_ = ros::Time(0,0);
00297 }
00298 else if (!isImageStreamRequired () && device_->isImageStreamRunning ())
00299 {
00300 stopSynchronization ();
00301 device_->stopImageStream ();
00302 }
00303
00304 if (isDepthStreamRequired () && !device_->isDepthStreamRunning ())
00305 {
00306
00307 device_->startDepthStream ();
00308 startSynchronization ();
00309 time_stamp_ = ros::Time(0,0);
00310 }
00311 else if ( !isDepthStreamRequired () && device_->isDepthStreamRunning ())
00312 {
00313
00314 stopSynchronization ();
00315 device_->stopDepthStream ();
00316 }
00317
00318 if (isIrStreamRequired() && !device_->isIRStreamRunning())
00319 {
00320
00321 if (device_->isImageStreamRunning())
00322 {
00323 NODELET_ERROR("Cannot stream RGB and IR at the same time. Streaming RGB only.");
00324 }
00325 else
00326 {
00327 device_->startIRStream();
00328 time_stamp_ = ros::Time(0,0);
00329 }
00330 }
00331 else if (!isIrStreamRequired() && device_->isIRStreamRunning())
00332 {
00333 device_->stopIRStream();
00334 }
00335 }
00336
00337 void OpenNINodelet::publishRgbImageRaw (const Image& image, ros::Time time) const
00338 {
00340 sensor_msgs::ImagePtr rgb_msg = boost::make_shared<sensor_msgs::Image > ();
00341 rgb_msg->header.stamp = time;
00342 rgb_msg->header.frame_id = rgb_frame_id_;
00343 if (image.getEncoding () == openni_wrapper::Image::BAYER_GRBG)
00344 {
00345 rgb_msg->encoding = sensor_msgs::image_encodings::BAYER_GRBG8;
00346 rgb_msg->step = image_width_;
00347 }
00348 else if (image.getEncoding () == openni_wrapper::Image::YUV422)
00349 {
00350 rgb_msg->encoding = "yuv422";
00351 rgb_msg->step = image_width_ * 2;
00352 }
00353 rgb_msg->height = image_height_;
00354 rgb_msg->width = image_width_;
00355 rgb_msg->data.resize (rgb_msg->height * rgb_msg->step);
00356 image.fillRaw (&rgb_msg->data[0]);
00357
00358 pub_rgb_raw_.publish (rgb_msg);
00359 }
00360
00361 void OpenNINodelet::publishGrayImage (const Image& image, ros::Time time) const
00362 {
00363 sensor_msgs::ImagePtr gray_msg = boost::make_shared<sensor_msgs::Image > ();
00364 gray_msg->header.stamp = time;
00365 gray_msg->header.frame_id = rgb_frame_id_;
00366 gray_msg->encoding = sensor_msgs::image_encodings::MONO8;
00367 gray_msg->height = image_height_;
00368 gray_msg->width = image_width_;
00369 gray_msg->step = image_width_;
00370 gray_msg->data.resize (gray_msg->height * gray_msg->step);
00371 image.fillGrayscale (gray_msg->width, gray_msg->height, &gray_msg->data[0], gray_msg->step);
00372
00373 pub_rgb_mono_.publish (gray_msg);
00374 }
00375
00376 void OpenNINodelet::publishRgbImage (const Image& image, ros::Time time) const
00377 {
00378 sensor_msgs::ImagePtr rgb_msg = boost::make_shared<sensor_msgs::Image > ();
00379 rgb_msg->header.stamp = time;
00380 rgb_msg->header.frame_id = rgb_frame_id_;
00381 rgb_msg->encoding = sensor_msgs::image_encodings::RGB8;
00382 rgb_msg->height = image_height_;
00383 rgb_msg->width = image_width_;
00384 rgb_msg->step = image_width_ * 3;
00385 rgb_msg->data.resize (rgb_msg->height * rgb_msg->step);
00386 image.fillRGB (rgb_msg->width, rgb_msg->height, &rgb_msg->data[0], rgb_msg->step);
00387
00388 pub_rgb_color_.publish (rgb_msg);
00389 }
00390
00391 void OpenNINodelet::publishDepthImageRaw (const openni_wrapper::DepthImage& depth,
00392 ros::Time time, const std::string& frame_id,
00393 const image_transport::Publisher& pub) const
00394 {
00396 sensor_msgs::ImagePtr depth_msg = boost::make_shared<sensor_msgs::Image> ();
00397 depth_msg->header.stamp = time;
00398 depth_msg->header.frame_id = frame_id;
00399 depth_msg->encoding = sensor_msgs::image_encodings::TYPE_16UC1;
00400 depth_msg->height = depth_height_;
00401 depth_msg->width = depth_width_;
00402 depth_msg->step = depth_msg->width * sizeof (short);
00403 depth_msg->data.resize (depth_msg->height * depth_msg->step);
00404
00405 depth.fillDepthImageRaw (depth_width_, depth_height_, reinterpret_cast<short*>(&depth_msg->data[0]),
00406 depth_msg->step);
00407
00408 pub.publish (depth_msg);
00409 }
00410
00411 void OpenNINodelet::publishIrImage(const openni_wrapper::IRImage& ir, ros::Time time) const
00412 {
00413 sensor_msgs::ImagePtr ir_msg = boost::make_shared<sensor_msgs::Image>();
00414 ir_msg->header.stamp = time;
00415 ir_msg->header.frame_id = depth_frame_id_;
00416 ir_msg->encoding = sensor_msgs::image_encodings::MONO16;
00417 ir_msg->height = ir.getHeight();
00418 ir_msg->width = ir.getWidth();
00419 ir_msg->step = ir_msg->width * sizeof(uint16_t);
00420 ir_msg->data.resize(ir_msg->height * ir_msg->step);
00421
00422 ir.fillRaw(reinterpret_cast<unsigned short*>(&ir_msg->data[0]));
00423
00424 pub_ir_.publish(ir_msg);
00425 }
00426
00427 sensor_msgs::CameraInfoPtr OpenNINodelet::getDefaultCameraInfo(int width, int height, double f) const
00428 {
00429 sensor_msgs::CameraInfoPtr info = boost::make_shared<sensor_msgs::CameraInfo>();
00430
00431 info->width = width;
00432 info->height = height;
00433
00434
00435 info->D.resize(5, 0.0);
00436 info->distortion_model = sensor_msgs::distortion_models::PLUMB_BOB;
00437
00438
00439 info->K.assign(0.0);
00440 info->K[0] = info->K[4] = f;
00441 info->K[2] = (width / 2) - 0.5;
00442
00443
00444 info->K[5] = (width * (3./8.)) - 0.5;
00445 info->K[8] = 1.0;
00446
00447
00448 info->R.assign(0.0);
00449 info->R[0] = info->R[4] = info->R[8] = 1.0;
00450
00451
00452 info->P.assign(0.0);
00453 info->P[0] = info->P[5] = f;
00454 info->P[2] = info->K[2];
00455 info->P[6] = info->K[5];
00456 info->P[10] = 1.0;
00457
00458 return info;
00459 }
00460
00462 sensor_msgs::CameraInfoPtr OpenNINodelet::getRgbCameraInfo(ros::Time time) const
00463 {
00464 sensor_msgs::CameraInfoPtr info;
00465
00466 if (rgb_info_manager_->isCalibrated())
00467 {
00468 info = boost::make_shared<sensor_msgs::CameraInfo>(rgb_info_manager_->getCameraInfo());
00469 }
00470 else
00471 {
00472
00473 info = getDefaultCameraInfo(image_width_, image_height_, device_->getImageFocalLength(image_width_));
00474 }
00475
00476
00477 info->header.stamp = time;
00478 info->header.frame_id = rgb_frame_id_;
00479
00480 return info;
00481 }
00482
00483 sensor_msgs::CameraInfoPtr OpenNINodelet::getIrCameraInfo(ros::Time time) const
00484 {
00485 sensor_msgs::CameraInfoPtr info;
00486
00487 if (ir_info_manager_->isCalibrated())
00488 {
00489 info = boost::make_shared<sensor_msgs::CameraInfo>(ir_info_manager_->getCameraInfo());
00490 }
00491 else
00492 {
00493
00494 info = getDefaultCameraInfo(depth_width_, depth_height_, device_->getDepthFocalLength(depth_width_));
00495 }
00496
00497
00498 info->header.stamp = time;
00499 info->header.frame_id = depth_frame_id_;
00500
00501 return info;
00502 }
00503
00504 sensor_msgs::CameraInfoPtr OpenNINodelet::getDepthCameraInfo(ros::Time time) const
00505 {
00506
00507
00508
00509
00510 sensor_msgs::CameraInfoPtr info = getIrCameraInfo(time);
00511 info->K[2] -= depth_ir_offset_x_;
00512 info->K[5] -= depth_ir_offset_y_;
00513 info->P[2] -= depth_ir_offset_x_;
00514 info->P[6] -= depth_ir_offset_y_;
00515
00517 return info;
00518 }
00519
00520 void OpenNINodelet::configCb(Config &config, uint32_t level)
00521 {
00522 XnMapOutputMode old_image_mode = device_->getImageOutputMode ();
00523 XnMapOutputMode old_depth_mode = device_->getDepthOutputMode ();
00524
00525
00526 XnMapOutputMode image_mode, compatible_image_mode;
00527 image_mode = mapConfigMode2XnMode (config.image_mode);
00528
00529 if (!device_->findCompatibleImageMode (image_mode, compatible_image_mode))
00530 {
00531 XnMapOutputMode default_mode = device_->getDefaultImageMode();
00532 NODELET_WARN("Could not find any compatible image output mode for %d x %d @ %d. "
00533 "Falling back to default image output mode %d x %d @ %d.",
00534 image_mode.nXRes, image_mode.nYRes, image_mode.nFPS,
00535 default_mode.nXRes, default_mode.nYRes, default_mode.nFPS);
00536
00537 config.image_mode = mapXnMode2ConfigMode(default_mode);
00538 image_mode = compatible_image_mode = default_mode;
00539 }
00540
00541 XnMapOutputMode depth_mode, compatible_depth_mode;
00542 depth_mode = mapConfigMode2XnMode (config.depth_mode);
00543 if (!device_->findCompatibleDepthMode (depth_mode, compatible_depth_mode))
00544 {
00545 XnMapOutputMode default_mode = device_->getDefaultDepthMode();
00546 NODELET_WARN ("Could not find any compatible depth output mode for %d x %d @ %d. "
00547 "Falling back to default depth output mode %d x %d @ %d.",
00548 depth_mode.nXRes, depth_mode.nYRes, depth_mode.nFPS,
00549 default_mode.nXRes, default_mode.nYRes, default_mode.nFPS);
00550
00551 config.depth_mode = mapXnMode2ConfigMode(default_mode);
00552 depth_mode = compatible_depth_mode = default_mode;
00553 }
00554
00555 DeviceKinect* kinect = dynamic_cast<DeviceKinect*> (device_.get ());
00556 if (kinect)
00557 {
00558 switch (config.debayering)
00559 {
00560 case OpenNI_Bilinear:
00561 kinect->setDebayeringMethod (ImageBayerGRBG::Bilinear);
00562 break;
00563 case OpenNI_EdgeAware:
00564 kinect->setDebayeringMethod (ImageBayerGRBG::EdgeAware);
00565 break;
00566 case OpenNI_EdgeAwareWeighted:
00567 kinect->setDebayeringMethod (ImageBayerGRBG::EdgeAwareWeighted);
00568 break;
00569 }
00570 }
00571 else if (config.debayering != config_.debayering)
00572 {
00573 NODELET_WARN ("%s does not output bayer images. Selection has no affect.", device_->getProductName () );
00574 }
00575
00576
00577 if (compatible_image_mode != old_image_mode || compatible_depth_mode != old_depth_mode)
00578 {
00579
00580 stopSynchronization();
00581
00582 if (compatible_image_mode != old_image_mode)
00583 device_->setImageOutputMode (compatible_image_mode);
00584
00585 if (compatible_depth_mode != old_depth_mode)
00586 device_->setDepthOutputMode (compatible_depth_mode);
00587
00588 startSynchronization ();
00589 }
00590
00591
00592 image_width_ = image_mode.nXRes;
00593 image_height_ = image_mode.nYRes;
00594 depth_width_ = depth_mode.nXRes;
00595 depth_height_ = depth_mode.nYRes;
00596
00598 if (device_->isDepthRegistered () && !config.depth_registration)
00599 {
00600 device_->setDepthRegistration (false);
00601 }
00602 else if (!device_->isDepthRegistered () && config.depth_registration)
00603 {
00604 device_->setDepthRegistration (true);
00605 }
00606
00607
00608 config_ = config;
00609 }
00610
00611 void OpenNINodelet::startSynchronization ()
00612 {
00613 if (device_->isSynchronizationSupported () && !device_->isSynchronized () &&
00614 device_->getImageOutputMode ().nFPS == device_->getDepthOutputMode ().nFPS &&
00615 device_->isImageStreamRunning () && device_->isDepthStreamRunning () )
00616 device_->setSynchronization (true);
00617 }
00618
00619 void OpenNINodelet::stopSynchronization ()
00620 {
00621 if (device_->isSynchronizationSupported () && device_->isSynchronized ())
00622 device_->setSynchronization (false);
00623 }
00624
00625 void OpenNINodelet::updateModeMaps ()
00626 {
00627 XnMapOutputMode output_mode;
00628
00629 output_mode.nXRes = XN_SXGA_X_RES;
00630 output_mode.nYRes = XN_SXGA_Y_RES;
00631 output_mode.nFPS = 15;
00632 xn2config_map_[output_mode] = OpenNI_SXGA_15Hz;
00633 config2xn_map_[OpenNI_SXGA_15Hz] = output_mode;
00634
00635 output_mode.nXRes = XN_VGA_X_RES;
00636 output_mode.nYRes = XN_VGA_Y_RES;
00637 output_mode.nFPS = 25;
00638 xn2config_map_[output_mode] = OpenNI_VGA_25Hz;
00639 config2xn_map_[OpenNI_VGA_25Hz] = output_mode;
00640 output_mode.nFPS = 30;
00641 xn2config_map_[output_mode] = OpenNI_VGA_30Hz;
00642 config2xn_map_[OpenNI_VGA_30Hz] = output_mode;
00643
00644 output_mode.nXRes = XN_QVGA_X_RES;
00645 output_mode.nYRes = XN_QVGA_Y_RES;
00646 output_mode.nFPS = 25;
00647 xn2config_map_[output_mode] = OpenNI_QVGA_25Hz;
00648 config2xn_map_[OpenNI_QVGA_25Hz] = output_mode;
00649 output_mode.nFPS = 30;
00650 xn2config_map_[output_mode] = OpenNI_QVGA_30Hz;
00651 config2xn_map_[OpenNI_QVGA_30Hz] = output_mode;
00652 output_mode.nFPS = 60;
00653 xn2config_map_[output_mode] = OpenNI_QVGA_60Hz;
00654 config2xn_map_[OpenNI_QVGA_60Hz] = output_mode;
00655
00656 output_mode.nXRes = XN_QQVGA_X_RES;
00657 output_mode.nYRes = XN_QQVGA_Y_RES;
00658 output_mode.nFPS = 25;
00659 xn2config_map_[output_mode] = OpenNI_QQVGA_25Hz;
00660 config2xn_map_[OpenNI_QQVGA_25Hz] = output_mode;
00661 output_mode.nFPS = 30;
00662 xn2config_map_[output_mode] = OpenNI_QQVGA_30Hz;
00663 config2xn_map_[OpenNI_QQVGA_30Hz] = output_mode;
00664 output_mode.nFPS = 60;
00665 xn2config_map_[output_mode] = OpenNI_QQVGA_60Hz;
00666 config2xn_map_[OpenNI_QQVGA_60Hz] = output_mode;
00667 }
00668
00669 int OpenNINodelet::mapXnMode2ConfigMode (const XnMapOutputMode& output_mode) const
00670 {
00671 std::map<XnMapOutputMode, int, modeComp>::const_iterator it = xn2config_map_.find (output_mode);
00672
00673 if (it == xn2config_map_.end ())
00674 {
00675 NODELET_ERROR ("mode %dx%d@%d could not be found", output_mode.nXRes, output_mode.nYRes, output_mode.nFPS);
00676 exit (-1);
00677 }
00678 else
00679 return it->second;
00680 }
00681
00682 XnMapOutputMode OpenNINodelet::mapConfigMode2XnMode (int mode) const
00683 {
00684 std::map<int, XnMapOutputMode>::const_iterator it = config2xn_map_.find (mode);
00685 if (it == config2xn_map_.end ())
00686 {
00687 NODELET_ERROR ("mode %d could not be found", mode);
00688 exit (-1);
00689 }
00690 else
00691 return it->second;
00692 }
00693
00694 void OpenNINodelet::watchDog (const ros::TimerEvent& event)
00695 {
00696 if ( !time_stamp_.isZero() && (device_->isDepthStreamRunning() || device_->isImageStreamRunning()) )
00697 {
00698 ros::Duration duration = ros::Time::now() - time_stamp_;
00699 if (duration.toSec() >= time_out_)
00700 {
00701 NODELET_ERROR("Timeout");
00702 watch_dog_timer_.stop();
00703 throw std::runtime_error("Timeout occured in OpenNINodelet");
00704 }
00705 }
00706 }
00707
00708 }
00709
00710
00711 #include <pluginlib/class_list_macros.h>
00712 PLUGINLIB_DECLARE_CLASS (openni_camera, driver, openni_camera::OpenNINodelet, nodelet::Nodelet);