42 #include <sensor_msgs/Image.h> 122 bool approxSync =
true;
123 bool subscribeRGBD =
false;
124 pnh.
param(
"approx_sync", approxSync, approxSync);
125 pnh.
param(
"queue_size", queueSize_, queueSize_);
126 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
129 ROS_ERROR(
"\"depth_cameras\" parameter doesn't exist anymore. It is replaced by \"rgbd_cameras\" with the \"rgbd_image\" input topics. \"subscribe_rgbd\" should be also set to true.");
131 pnh.
param(
"rgbd_cameras", rgbdCameras, rgbdCameras);
140 pnh.
param(
"keep_color", keepColor_, keepColor_);
142 NODELET_INFO(
"RGBDOdometry: approx_sync = %s", approxSync?
"true":
"false");
143 NODELET_INFO(
"RGBDOdometry: queue_size = %d", queueSize_);
144 NODELET_INFO(
"RGBDOdometry: subscribe_rgbd = %s", subscribeRGBD?
"true":
"false");
145 NODELET_INFO(
"RGBDOdometry: rgbd_cameras = %d", rgbdCameras);
146 NODELET_INFO(
"RGBDOdometry: keep_color = %s", keepColor_?
"true":
"false");
148 std::string subscribedTopicsMsg;
153 rgbd_image1_sub_.subscribe(nh,
"rgbd_image0", 1);
154 rgbd_image2_sub_.subscribe(nh,
"rgbd_image1", 1);
157 rgbd_image3_sub_.subscribe(nh,
"rgbd_image2", 1);
161 rgbd_image4_sub_.subscribe(nh,
"rgbd_image3", 1);
172 approxSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
180 exactSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
182 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s \\\n %s",
184 approxSync?
"approx":
"exact",
185 rgbd_image1_sub_.getTopic().c_str(),
186 rgbd_image2_sub_.getTopic().c_str());
188 else if(rgbdCameras == 3)
197 approxSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
206 exactSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
208 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s \\\n %s \\\n %s",
210 approxSync?
"approx":
"exact",
211 rgbd_image1_sub_.getTopic().c_str(),
212 rgbd_image2_sub_.getTopic().c_str(),
213 rgbd_image3_sub_.getTopic().c_str());
215 else if(rgbdCameras == 4)
225 approxSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
235 exactSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
237 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s \\\n %s \\\n %s \\\n %s",
239 approxSync?
"approx":
"exact",
240 rgbd_image1_sub_.getTopic().c_str(),
241 rgbd_image2_sub_.getTopic().c_str(),
242 rgbd_image3_sub_.getTopic().c_str(),
243 rgbd_image4_sub_.getTopic().c_str());
248 rgbdSub_ = nh.
subscribe(
"rgbd_image", 1, &RGBDOdometry::callbackRGBD,
this);
250 subscribedTopicsMsg =
251 uFormat(
"\n%s subscribed to:\n %s",
253 rgbdSub_.getTopic().c_str());
267 image_mono_sub_.subscribe(rgb_it, rgb_nh.
resolveName(
"image"), 1, hintsRgb);
268 image_depth_sub_.subscribe(depth_it, depth_nh.
resolveName(
"image"), 1, hintsDepth);
269 info_sub_.subscribe(rgb_nh,
"camera_info", 1);
282 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s \\\n %s \\\n %s",
284 approxSync?
"approx":
"exact",
285 image_mono_sub_.getTopic().c_str(),
286 image_depth_sub_.getTopic().c_str(),
287 info_sub_.getTopic().c_str());
289 this->startWarningThread(subscribedTopicsMsg, approxSync);
295 ParametersMap::iterator iter = parameters.find(Parameters::kRegStrategy());
296 if(iter != parameters.end() && iter->second.compare(
"0") != 0)
298 ROS_WARN(
"RGBD odometry works only with \"Reg/Strategy\"=0. Ignoring value %s.", iter->second.c_str());
302 int estimationType = Parameters::defaultVisEstimationType();
306 bool subscribeRGBD =
false;
307 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
308 pnh.
param(
"rgbd_cameras", rgbdCameras, rgbdCameras);
309 if(subscribeRGBD && rgbdCameras> 1 && estimationType>0)
311 NODELET_WARN(
"Setting \"%s\" parameter to 0 (%d is not supported " 312 "for multi-cameras) as \"subscribe_rgbd\" is " 313 "true and \"rgbd_cameras\">1. Set \"%s\" to 0 to suppress this warning.",
314 Parameters::kVisEstimationType().c_str(),
316 Parameters::kVisEstimationType().c_str());
317 uInsert(parameters,
ParametersPair(Parameters::kVisEstimationType(),
"0"));
322 const std::vector<cv_bridge::CvImageConstPtr> & rgbImages,
323 const std::vector<cv_bridge::CvImageConstPtr> & depthImages,
324 const std::vector<sensor_msgs::CameraInfo>& cameraInfos)
326 ROS_ASSERT(rgbImages.size() > 0 && rgbImages.size() == depthImages.size() && rgbImages.size() == cameraInfos.size());
328 int imageWidth = rgbImages[0]->image.cols;
329 int imageHeight = rgbImages[0]->image.rows;
330 int depthWidth = depthImages[0]->image.cols;
331 int depthHeight = depthImages[0]->image.rows;
334 imageWidth % depthWidth == 0 && imageHeight % depthHeight == 0 &&
335 imageWidth/depthWidth == imageHeight/depthHeight,
336 uFormat(
"rgb=%dx%d depth=%dx%d", imageWidth, imageHeight, depthWidth, depthHeight).c_str());
338 int cameraCount = rgbImages.size();
341 pcl::PointCloud<pcl::PointXYZ> scanCloud;
342 std::vector<CameraModel> cameraModels;
343 for(
unsigned int i=0; i<rgbImages.size(); ++i)
357 NODELET_ERROR(
"Input type must be image=mono8,mono16,rgb8,bgr8,bgra8,rgba8 and " 358 "image_depth=32FC1,16UC1,mono16. Current rgb=%s and depth=%s",
359 rgbImages[i]->encoding.c_str(),
360 depthImages[i]->encoding.c_str());
363 UASSERT_MSG(rgbImages[i]->image.cols == imageWidth && rgbImages[i]->image.rows == imageHeight,
364 uFormat(
"imageWidth=%d vs %d imageHeight=%d vs %d",
366 rgbImages[i]->image.cols,
368 rgbImages[i]->image.rows).c_str());
369 UASSERT_MSG(depthImages[i]->image.cols == depthWidth && depthImages[i]->image.rows == depthHeight,
370 uFormat(
"depthWidth=%d vs %d depthHeight=%d vs %d",
372 depthImages[i]->image.cols,
374 depthImages[i]->image.rows).c_str());
376 ros::Time stamp = rgbImages[i]->header.stamp>depthImages[i]->header.stamp?rgbImages[i]->header.stamp:depthImages[i]->header.stamp;
382 else if(stamp > higherStamp)
388 if(localTransform.
isNull())
408 cv::Mat subDepth = ptrDepth->image;
413 rgb = cv::Mat(imageHeight, imageWidth*cameraCount, ptrImage->image.type());
417 depth = cv::Mat(depthHeight, depthWidth*cameraCount, subDepth.type());
420 if(ptrImage->image.type() == rgb.type())
422 ptrImage->image.copyTo(cv::Mat(rgb, cv::Rect(i*imageWidth, 0, imageWidth, imageHeight)));
430 if(subDepth.type() == depth.type())
432 subDepth.copyTo(cv::Mat(depth, cv::Rect(i*depthWidth, 0, depthWidth, depthHeight)));
436 NODELET_ERROR(
"Some Depth images are not the same type! %d vs %d", subDepth.type(), depth.type());
450 this->processData(data, higherStamp, rgbImages.size()==1?rgbImages[0]->header.frame_id:
"");
454 const sensor_msgs::ImageConstPtr& image,
455 const sensor_msgs::ImageConstPtr& depth,
456 const sensor_msgs::CameraInfoConstPtr& cameraInfo)
459 if(!this->isPaused())
461 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(1);
462 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(1);
463 std::vector<sensor_msgs::CameraInfo> infoMsgs;
466 infoMsgs.push_back(*cameraInfo);
468 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
473 const rtabmap_ros::RGBDImageConstPtr& image)
476 if(!this->isPaused())
478 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(1);
479 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(1);
480 std::vector<sensor_msgs::CameraInfo> infoMsgs;
482 infoMsgs.push_back(image->rgb_camera_info);
484 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
489 const rtabmap_ros::RGBDImageConstPtr& image,
490 const rtabmap_ros::RGBDImageConstPtr& image2)
493 if(!this->isPaused())
495 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(2);
496 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(2);
497 std::vector<sensor_msgs::CameraInfo> infoMsgs;
500 infoMsgs.push_back(image->rgb_camera_info);
501 infoMsgs.push_back(image2->rgb_camera_info);
503 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
508 const rtabmap_ros::RGBDImageConstPtr& image,
509 const rtabmap_ros::RGBDImageConstPtr& image2,
510 const rtabmap_ros::RGBDImageConstPtr& image3)
513 if(!this->isPaused())
515 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(3);
516 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(3);
517 std::vector<sensor_msgs::CameraInfo> infoMsgs;
521 infoMsgs.push_back(image->rgb_camera_info);
522 infoMsgs.push_back(image2->rgb_camera_info);
523 infoMsgs.push_back(image3->rgb_camera_info);
525 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
530 const rtabmap_ros::RGBDImageConstPtr& image,
531 const rtabmap_ros::RGBDImageConstPtr& image2,
532 const rtabmap_ros::RGBDImageConstPtr& image3,
533 const rtabmap_ros::RGBDImageConstPtr& image4)
536 if(!this->isPaused())
538 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(4);
539 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(4);
540 std::vector<sensor_msgs::CameraInfo> infoMsgs;
545 infoMsgs.push_back(image->rgb_camera_info);
546 infoMsgs.push_back(image2->rgb_camera_info);
547 infoMsgs.push_back(image3->rgb_camera_info);
548 infoMsgs.push_back(image4->rgb_camera_info);
550 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
577 approxSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
586 exactSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
596 approxSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
606 exactSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
617 approxSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
628 exactSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
const std::string BAYER_GRBG8
message_filters::Subscriber< rtabmap_ros::RGBDImage > rgbd_image2_sub_
message_filters::Subscriber< sensor_msgs::CameraInfo > info_sub_
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
void callbackRGBD4(const rtabmap_ros::RGBDImageConstPtr &image, const rtabmap_ros::RGBDImageConstPtr &image2, const rtabmap_ros::RGBDImageConstPtr &image3, const rtabmap_ros::RGBDImageConstPtr &image4)
std::string uFormat(const char *fmt,...)
#define NODELET_ERROR(...)
#define NODELET_WARN(...)
message_filters::sync_policies::ApproximateTime< sensor_msgs::Image, sensor_msgs::Image, sensor_msgs::CameraInfo > MyApproxSyncPolicy
void commonCallback(const std::vector< cv_bridge::CvImageConstPtr > &rgbImages, const std::vector< cv_bridge::CvImageConstPtr > &depthImages, const std::vector< sensor_msgs::CameraInfo > &cameraInfos)
message_filters::Synchronizer< MyExactSync2Policy > * exactSync2_
message_filters::sync_policies::ExactTime< sensor_msgs::Image, sensor_msgs::Image, sensor_msgs::CameraInfo > MyExactSyncPolicy
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
message_filters::Subscriber< rtabmap_ros::RGBDImage > rgbd_image1_sub_
std::pair< std::string, std::string > ParametersPair
std::string resolveName(const std::string &name, bool remap=true) const
message_filters::sync_policies::ApproximateTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyApproxSync2Policy
message_filters::Subscriber< rtabmap_ros::RGBDImage > rgbd_image3_sub_
message_filters::Synchronizer< MyExactSyncPolicy > * exactSync_
std::string getName(void *handle)
message_filters::Synchronizer< MyApproxSync3Policy > * approxSync3_
const std::string TYPE_8UC1
message_filters::sync_policies::ExactTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyExactSync2Policy
message_filters::Synchronizer< MyApproxSync4Policy > * approxSync4_
virtual void onOdomInit()
rtabmap::Transform getTransform(const std::string &fromFrameId, const std::string &toFrameId, const ros::Time &stamp, tf::TransformListener &listener, double waitForTransform)
image_transport::SubscriberFilter image_depth_sub_
void callbackRGBD(const rtabmap_ros::RGBDImageConstPtr &image)
void callbackRGBD2(const rtabmap_ros::RGBDImageConstPtr &image, const rtabmap_ros::RGBDImageConstPtr &image2)
message_filters::sync_policies::ApproximateTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyApproxSync3Policy
void callback(const sensor_msgs::ImageConstPtr &image, const sensor_msgs::ImageConstPtr &depth, const sensor_msgs::CameraInfoConstPtr &cameraInfo)
message_filters::Synchronizer< MyApproxSync2Policy > * approxSync2_
Connection registerCallback(C &callback)
#define UASSERT_MSG(condition, msg_str)
CvImagePtr cvtColor(const CvImageConstPtr &source, const std::string &encoding)
message_filters::Synchronizer< MyApproxSyncPolicy > * approxSync_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
const std::string TYPE_32FC1
rtabmap::CameraModel cameraModelFromROS(const sensor_msgs::CameraInfo &camInfo, const rtabmap::Transform &localTransform=rtabmap::Transform::getIdentity())
const std::string TYPE_16UC1
QMap< QString, QVariant > ParametersMap
image_transport::SubscriberFilter image_mono_sub_
message_filters::sync_policies::ApproximateTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyApproxSync4Policy
void callback(rtabmap_ros::CameraConfig &config, uint32_t level)
message_filters::sync_policies::ExactTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyExactSync4Policy
message_filters::Subscriber< rtabmap_ros::RGBDImage > rgbd_image4_sub_
#define NODELET_INFO(...)
PLUGINLIB_EXPORT_CLASS(rtabmap_ros::RGBDOdometry, nodelet::Nodelet)
virtual void updateParameters(ParametersMap ¶meters)
message_filters::Synchronizer< MyExactSync4Policy > * exactSync4_
void toCvShare(const rtabmap_ros::RGBDImageConstPtr &image, cv_bridge::CvImageConstPtr &rgb, cv_bridge::CvImageConstPtr &depth)
void callbackRGBD3(const rtabmap_ros::RGBDImageConstPtr &image, const rtabmap_ros::RGBDImageConstPtr &image2, const rtabmap_ros::RGBDImageConstPtr &image3)
double timestampFromROS(const ros::Time &stamp)
message_filters::sync_policies::ExactTime< rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage, rtabmap_ros::RGBDImage > MyExactSync3Policy
bool hasParam(const std::string &key) const
message_filters::Synchronizer< MyExactSync3Policy > * exactSync3_
#define NODELET_FATAL(...)
virtual void flushCallbacks()
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)