42 #include <sensor_msgs/Image.h> 121 bool approxSync =
true;
122 bool subscribeRGBD =
false;
123 pnh.
param(
"approx_sync", approxSync, approxSync);
124 pnh.
param(
"queue_size", queueSize_, queueSize_);
125 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
128 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.");
130 pnh.
param(
"rgbd_cameras", rgbdCameras, rgbdCameras);
140 NODELET_INFO(
"RGBDOdometry: approx_sync = %s", approxSync?
"true":
"false");
141 NODELET_INFO(
"RGBDOdometry: queue_size = %d", queueSize_);
142 NODELET_INFO(
"RGBDOdometry: subscribe_rgbd = %s", subscribeRGBD?
"true":
"false");
143 NODELET_INFO(
"RGBDOdometry: rgbd_cameras = %d", rgbdCameras);
145 std::string subscribedTopicsMsg;
150 rgbd_image1_sub_.subscribe(nh,
"rgbd_image0", 1);
151 rgbd_image2_sub_.subscribe(nh,
"rgbd_image1", 1);
154 rgbd_image3_sub_.subscribe(nh,
"rgbd_image2", 1);
158 rgbd_image4_sub_.subscribe(nh,
"rgbd_image3", 1);
169 approxSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
177 exactSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
179 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s,\n %s",
181 approxSync?
"approx":
"exact",
182 rgbd_image1_sub_.getTopic().c_str(),
183 rgbd_image2_sub_.getTopic().c_str());
185 else if(rgbdCameras == 3)
194 approxSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
203 exactSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
205 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s,\n %s,\n %s",
207 approxSync?
"approx":
"exact",
208 rgbd_image1_sub_.getTopic().c_str(),
209 rgbd_image2_sub_.getTopic().c_str(),
210 rgbd_image3_sub_.getTopic().c_str());
212 else if(rgbdCameras == 4)
222 approxSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
232 exactSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
234 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s,\n %s,\n %s,\n %s",
236 approxSync?
"approx":
"exact",
237 rgbd_image1_sub_.getTopic().c_str(),
238 rgbd_image2_sub_.getTopic().c_str(),
239 rgbd_image3_sub_.getTopic().c_str(),
240 rgbd_image4_sub_.getTopic().c_str());
245 rgbdSub_ = nh.
subscribe(
"rgbd_image", 1, &RGBDOdometry::callbackRGBD,
this);
247 subscribedTopicsMsg =
248 uFormat(
"\n%s subscribed to:\n %s",
250 rgbdSub_.getTopic().c_str());
264 image_mono_sub_.subscribe(rgb_it, rgb_nh.
resolveName(
"image"), 1, hintsRgb);
265 image_depth_sub_.subscribe(depth_it, depth_nh.
resolveName(
"image"), 1, hintsDepth);
266 info_sub_.subscribe(rgb_nh,
"camera_info", 1);
279 subscribedTopicsMsg =
uFormat(
"\n%s subscribed to (%s sync):\n %s,\n %s,\n %s",
281 approxSync?
"approx":
"exact",
282 image_mono_sub_.getTopic().c_str(),
283 image_depth_sub_.getTopic().c_str(),
284 info_sub_.getTopic().c_str());
286 this->startWarningThread(subscribedTopicsMsg, approxSync);
292 ParametersMap::iterator iter = parameters.find(Parameters::kRegStrategy());
293 if(iter != parameters.end() && iter->second.compare(
"0") != 0)
295 ROS_WARN(
"RGBD odometry works only with \"Reg/Strategy\"=0. Ignoring value %s.", iter->second.c_str());
299 int estimationType = Parameters::defaultVisEstimationType();
303 bool subscribeRGBD =
false;
304 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
305 pnh.
param(
"rgbd_cameras", rgbdCameras, rgbdCameras);
306 if(subscribeRGBD && rgbdCameras> 1 && estimationType>0)
308 NODELET_WARN(
"Setting \"%s\" parameter to 0 (%d is not supported " 309 "for multi-cameras) as \"subscribe_rgbd\" is " 310 "true and \"rgbd_cameras\">1. Set \"%s\" to 0 to suppress this warning.",
311 Parameters::kVisEstimationType().c_str(),
313 Parameters::kVisEstimationType().c_str());
314 uInsert(parameters,
ParametersPair(Parameters::kVisEstimationType(),
"0"));
319 const std::vector<cv_bridge::CvImageConstPtr> & rgbImages,
320 const std::vector<cv_bridge::CvImageConstPtr> & depthImages,
321 const std::vector<sensor_msgs::CameraInfo>& cameraInfos)
323 ROS_ASSERT(rgbImages.size() > 0 && rgbImages.size() == depthImages.size() && rgbImages.size() == cameraInfos.size());
325 int imageWidth = rgbImages[0]->image.cols;
326 int imageHeight = rgbImages[0]->image.rows;
327 int depthWidth = depthImages[0]->image.cols;
328 int depthHeight = depthImages[0]->image.rows;
331 imageWidth % depthWidth == 0 && imageHeight % depthHeight == 0 &&
332 imageWidth/depthWidth == imageHeight/depthHeight,
333 uFormat(
"rgb=%dx%d depth=%dx%d", imageWidth, imageHeight, depthWidth, depthHeight).c_str());
335 int cameraCount = rgbImages.size();
338 pcl::PointCloud<pcl::PointXYZ> scanCloud;
339 std::vector<CameraModel> cameraModels;
340 for(
unsigned int i=0; i<rgbImages.size(); ++i)
354 NODELET_ERROR(
"Input type must be image=mono8,mono16,rgb8,bgr8,bgra8,rgba8 and " 355 "image_depth=32FC1,16UC1,mono16. Current rgb=%s and depth=%s",
356 rgbImages[i]->encoding.c_str(),
357 depthImages[i]->encoding.c_str());
360 UASSERT_MSG(rgbImages[i]->image.cols == imageWidth && rgbImages[i]->image.rows == imageHeight,
361 uFormat(
"imageWidth=%d vs %d imageHeight=%d vs %d",
363 rgbImages[i]->image.cols,
365 rgbImages[i]->image.rows).c_str());
366 UASSERT_MSG(depthImages[i]->image.cols == depthWidth && depthImages[i]->image.rows == depthHeight,
367 uFormat(
"depthWidth=%d vs %d depthHeight=%d vs %d",
369 depthImages[i]->image.cols,
371 depthImages[i]->image.rows).c_str());
373 ros::Time stamp = rgbImages[i]->header.stamp>depthImages[i]->header.stamp?rgbImages[i]->header.stamp:depthImages[i]->header.stamp;
379 else if(stamp > higherStamp)
385 if(localTransform.
isNull())
398 cv::Mat subDepth = ptrDepth->image;
403 rgb = cv::Mat(imageHeight, imageWidth*cameraCount, ptrImage->image.type());
407 depth = cv::Mat(depthHeight, depthWidth*cameraCount, subDepth.type());
410 if(ptrImage->image.type() == rgb.type())
412 ptrImage->image.copyTo(cv::Mat(rgb, cv::Rect(i*imageWidth, 0, imageWidth, imageHeight)));
420 if(subDepth.type() == depth.type())
422 subDepth.copyTo(cv::Mat(depth, cv::Rect(i*depthWidth, 0, depthWidth, depthHeight)));
440 this->processData(data, higherStamp);
444 const sensor_msgs::ImageConstPtr& image,
445 const sensor_msgs::ImageConstPtr& depth,
446 const sensor_msgs::CameraInfoConstPtr& cameraInfo)
449 if(!this->isPaused())
451 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(1);
452 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(1);
453 std::vector<sensor_msgs::CameraInfo> infoMsgs;
456 infoMsgs.push_back(*cameraInfo);
458 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
463 const rtabmap_ros::RGBDImageConstPtr& image)
466 if(!this->isPaused())
468 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(1);
469 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(1);
470 std::vector<sensor_msgs::CameraInfo> infoMsgs;
472 infoMsgs.push_back(image->rgbCameraInfo);
474 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
479 const rtabmap_ros::RGBDImageConstPtr& image,
480 const rtabmap_ros::RGBDImageConstPtr& image2)
483 if(!this->isPaused())
485 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(2);
486 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(2);
487 std::vector<sensor_msgs::CameraInfo> infoMsgs;
490 infoMsgs.push_back(image->rgbCameraInfo);
491 infoMsgs.push_back(image2->rgbCameraInfo);
493 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
498 const rtabmap_ros::RGBDImageConstPtr& image,
499 const rtabmap_ros::RGBDImageConstPtr& image2,
500 const rtabmap_ros::RGBDImageConstPtr& image3)
503 if(!this->isPaused())
505 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(3);
506 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(3);
507 std::vector<sensor_msgs::CameraInfo> infoMsgs;
511 infoMsgs.push_back(image->rgbCameraInfo);
512 infoMsgs.push_back(image2->rgbCameraInfo);
513 infoMsgs.push_back(image3->rgbCameraInfo);
515 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
520 const rtabmap_ros::RGBDImageConstPtr& image,
521 const rtabmap_ros::RGBDImageConstPtr& image2,
522 const rtabmap_ros::RGBDImageConstPtr& image3,
523 const rtabmap_ros::RGBDImageConstPtr& image4)
526 if(!this->isPaused())
528 std::vector<cv_bridge::CvImageConstPtr> imageMsgs(4);
529 std::vector<cv_bridge::CvImageConstPtr> depthMsgs(4);
530 std::vector<sensor_msgs::CameraInfo> infoMsgs;
535 infoMsgs.push_back(image->rgbCameraInfo);
536 infoMsgs.push_back(image2->rgbCameraInfo);
537 infoMsgs.push_back(image3->rgbCameraInfo);
538 infoMsgs.push_back(image4->rgbCameraInfo);
540 this->commonCallback(imageMsgs, depthMsgs, infoMsgs);
567 approxSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
576 exactSync2_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD2,
this, _1, _2));
586 approxSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
596 exactSync3_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD3,
this, _1, _2, _3));
607 approxSync4_->
registerCallback(boost::bind(&RGBDOdometry::callbackRGBD4,
this, _1, _2, _3, _4));
618 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)