Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "parameter_server.h"
00019
00020 #include "pcl/ros/conversions.h"
00021 #include <pcl/io/io.h>
00022
00023 #include "pcl_ros/transforms.h"
00024 #include "bagloader.h"
00025 #include <iostream>
00026 #include <sstream>
00027 #include <string>
00028
00029 #include <sensor_msgs/PointCloud2.h>
00030 #include <Eigen/Core>
00031 #include "misc.h"
00032
00033
00034
00035
00036 #include <rosbag/view.h>
00037 #include <boost/foreach.hpp>
00038
00039
00040 #include "scoped_timer.h"
00041
00042 #include <tf/transform_listener.h>
00043
00044 typedef message_filters::Subscriber<sensor_msgs::PointCloud2> pc_sub_type;
00045
00046
00047
00048
00049 BagLoader::BagLoader()
00050 : pause_(ParameterServer::instance()->get<bool>("start_paused")),
00051 data_id_(0)
00052 {
00053 ros::NodeHandle nh;
00054 tflistener_ = new tf::TransformListener(nh);
00055 }
00056
00057
00059
00061 void BagLoader::loadBag(std::string filename)
00062 {
00063 ScopedTimer s(__FUNCTION__);
00064 ros::NodeHandle nh;
00065 ParameterServer* ps = ParameterServer::instance();
00066 std::string points_tpc = ps->get<std::string>("individual_cloud_out_topic").c_str();
00067 ROS_INFO_STREAM("Listening to " << points_tpc);
00068 std::string tf_tpc = std::string("/tf");
00069 tf_pub_ = nh.advertise<tf::tfMessage>(tf_tpc, 10);
00070
00071 ROS_INFO("Loading Bagfile %s", filename.c_str());
00072 Q_EMIT setGUIStatus(QString("Loading ")+filename.c_str());
00073 {
00074 rosbag::Bag bag;
00075 try{
00076 bag.open(filename, rosbag::bagmode::Read);
00077 } catch(rosbag::BagIOException ex) {
00078 ROS_FATAL("Opening Bagfile %s failed: %s Quitting!", filename.c_str(), ex.what());
00079 ros::shutdown();
00080 return;
00081 }
00082 ROS_INFO("Opened Bagfile %s", filename.c_str());
00083 Q_EMIT setGUIStatus(QString("Opened ")+filename.c_str());
00084
00085
00086 std::vector<std::string> topics;
00087 topics.push_back(points_tpc);
00088 topics.push_back(tf_tpc);
00089
00090 rosbag::View view(bag, rosbag::TopicQuery(topics));
00091
00092 std::deque<sensor_msgs::PointCloud2::ConstPtr> pointclouds;
00093 ros::Time last_tf(0);
00094 BOOST_FOREACH(rosbag::MessageInstance const m, view)
00095 {
00096 if(!ros::ok()) return;
00097 while(pause_) {
00098 usleep(100);
00099 ROS_INFO_THROTTLE(5.0,"Paused - press Space to unpause");
00100 if(!ros::ok()) return;
00101 }
00102
00103 ROS_INFO_STREAM("Processing message on topic " << m.getTopic());
00104 if (m.getTopic() == points_tpc || ("/" + m.getTopic() == points_tpc))
00105 {
00106 sensor_msgs::PointCloud2::ConstPtr pointcloud = m.instantiate<sensor_msgs::PointCloud2>();
00107
00108 if (pointcloud) pointclouds.push_back(pointcloud);
00109 ROS_INFO("Found Message of %s", points_tpc.c_str());
00110 }
00111 if (m.getTopic() == tf_tpc|| ("/" + m.getTopic() == tf_tpc)){
00112 tf::tfMessage::ConstPtr tf_msg = m.instantiate<tf::tfMessage>();
00113 if (tf_msg) {
00114
00115
00116 boost::shared_ptr<std::map<std::string, std::string> > msg_header_map = tf_msg->__connection_header;
00117 (*msg_header_map)["callerid"] = "rgbdslam";
00118 tf_pub_.publish(tf_msg);
00119 ROS_INFO("Found Message of %s", tf_tpc.c_str());
00120 last_tf = tf_msg->transforms[0].header.stamp;
00121 last_tf -= ros::Duration(0.3);
00122 }
00123 }
00124 while(!pointclouds.empty() && pointclouds.front()->header.stamp < last_tf){
00125 Q_EMIT setGUIInfo(QString("Processing frame ") + QString::number(data_id_));
00126 callback(pointclouds.front());
00127 pointclouds.pop_front();
00128 }
00129
00130 }
00131 bag.close();
00132 }
00133 ROS_INFO("Bagfile fully processed");
00134 Q_EMIT setGUIStatus(QString("Done with ")+filename.c_str());
00135 Q_EMIT bagFinished();
00136 }
00137
00138
00139 void BagLoader::callback(const sensor_msgs::PointCloud2ConstPtr& point_cloud)
00140 {
00141 ScopedTimer s(__FUNCTION__);
00142 ROS_INFO("Processing cloud");
00143 if(++data_id_ < ParameterServer::instance()->get<int>("skip_first_n_frames")
00144 || data_id_ % ParameterServer::instance()->get<int>("data_skip_step") != 0){
00145 ROS_INFO_THROTTLE(1, "Skipping Frame %i because of data_skip_step setting (this msg is only shown once a sec)", data_id_);
00146 return;
00147 };
00148
00149 pointcloud_type* pc_col = new pointcloud_type();
00150 pcl::fromROSMsg(*point_cloud,*pc_col);
00151 sendWithTransformation(pc_col);
00152 }
00153
00154 BagLoader::~BagLoader(){
00155 delete tflistener_;
00156 }
00157
00158
00159
00160 void BagLoader::togglePause(){
00161 pause_ = !pause_;
00162 ROS_INFO("Pause toggled to: %s", pause_? "true":"false");
00163 if(pause_) Q_EMIT setGUIInfo2("Processing Thread Stopped");
00164 else Q_EMIT setGUIInfo2("Processing Thread Running");
00165 }
00166
00167
00168 void BagLoader::sendWithTransformation(pointcloud_type* cloud)
00169 {
00170 ScopedTimer s(__FUNCTION__);
00171 ParameterServer* ps = ParameterServer::instance();
00172 std::string fixed_frame = ps->get<std::string>("fixed_frame_name");
00173 std::string depth_frame_id = cloud->header.frame_id;
00174 ros::Time depth_time = cloud->header.stamp;
00175 tf::StampedTransform map2points;
00176
00177 try{
00178 tflistener_->waitForTransform(fixed_frame, depth_frame_id, depth_time, ros::Duration(0.005));
00179 tflistener_->lookupTransform( fixed_frame, depth_frame_id, depth_time,map2points);
00180
00181
00182 QMatrix4x4 transform_to_map = g2o2QMatrix(tf2G2O(map2points));
00183 Q_EMIT setPointCloud(cloud, transform_to_map);
00184 }
00185 catch (tf::TransformException ex){
00186 ROS_ERROR("%s - No transformation available",ex.what());
00187 }
00188 }
00189
00190
00191 void BagLoader::loadBagFileAsync(std::string file)
00192 {
00193 QtConcurrent::run(this, &BagLoader::loadBag, file);
00194 }
00195
00196 void BagLoader::loadBagFileAsync(QString file)
00197 {
00198 loadBagFileAsync(file.toStdString());
00199 }
00200
00201 void BagLoader::clearPointCloud(pointcloud_type* pc) {
00202 ROS_DEBUG("Should clear cloud at %p", pc);
00203 delete pc; pc = NULL;
00204 }