Go to the documentation of this file.00001 #include "dataload_ros.h"
00002 #include <QTextStream>
00003 #include <QFile>
00004 #include <QMessageBox>
00005 #include <QDebug>
00006 #include <QApplication>
00007 #include <QProgressDialog>
00008 #include <QElapsedTimer>
00009 #include <QFileInfo>
00010 #include <QProcess>
00011 #include <rosbag/view.h>
00012 #include <sys/sysinfo.h>
00013
00014 #include "../dialog_select_ros_topics.h"
00015 #include "../shape_shifter_factory.hpp"
00016 #include "../rule_editing.h"
00017
00018
00019 DataLoadROS::DataLoadROS()
00020 {
00021 _extensions.push_back( "bag");
00022 }
00023
00024 const std::vector<const char*> &DataLoadROS::compatibleFileExtensions() const
00025 {
00026 return _extensions;
00027 }
00028
00029 size_t getAvailableRAM()
00030 {
00031 struct sysinfo info;
00032 sysinfo(&info);
00033 return info.freeram;
00034 }
00035
00036 PlotDataMap DataLoadROS::readDataFromFile(const QString &file_name,
00037 QString &load_configuration )
00038 {
00039 using namespace RosIntrospection;
00040
00041 std::vector<std::pair<QString,QString>> all_topics;
00042 PlotDataMap plot_map;
00043
00044 try{
00045 _bag.close();
00046 _bag.open( file_name.toStdString(), rosbag::bagmode::Read );
00047 }
00048 catch( rosbag::BagException& ex)
00049 {
00050 QMessageBox::warning(0, tr("Error"),
00051 QString("rosbag::open thrown an exception:\n")+
00052 QString(ex.what()) );
00053 return plot_map;
00054 }
00055
00056 rosbag::View bag_view ( _bag, ros::TIME_MIN, ros::TIME_MAX, true );
00057 std::vector<const rosbag::ConnectionInfo *> connections = bag_view.getConnections();
00058
00059 std::map<std::string,ROSType> rostype;
00060
00061 for(unsigned i=0; i<connections.size(); i++)
00062 {
00063 const auto& topic = connections[i]->topic;
00064 const auto& md5sum = connections[i]->md5sum;
00065 const auto& datatype = connections[i]->datatype;
00066 const auto& definition = connections[i]->msg_def;
00067
00068 all_topics.push_back( std::make_pair(QString( topic.c_str()), QString( datatype.c_str()) ) );
00069 RosIntrospectionFactory::get().registerMessage(topic, md5sum, datatype, definition);
00070 rostype.insert( std::make_pair(datatype, ROSType(datatype)) );
00071 }
00072
00073 int count = 0;
00074
00075
00076 QStringList default_topic_names = load_configuration.split(' ',QString::SkipEmptyParts);
00077 load_configuration.clear();
00078
00079 DialogSelectRosTopics* dialog = new DialogSelectRosTopics( all_topics, default_topic_names );
00080
00081 std::set<std::string> topic_selected;
00082
00083 if( dialog->exec() == static_cast<int>(QDialog::Accepted) )
00084 {
00085 const auto& selected_items = dialog->getSelectedItems();
00086 for(const auto& item: selected_items)
00087 {
00088 std::string ss_topic = item.toStdString();
00089 topic_selected.insert( ss_topic );
00090
00091
00092 load_configuration.append( item ).append(" ");
00093 }
00094
00095 if( dialog->checkBoxUseRenamingRules()->isChecked())
00096 {
00097 _rules = RuleEditing::getRenamingRules();
00098 }
00099 else{
00100 _rules.clear();
00101 }
00102 }
00103
00104
00105 QProgressDialog progress_dialog;
00106 progress_dialog.setLabelText("Loading... please wait");
00107 progress_dialog.setWindowModality( Qt::ApplicationModal );
00108
00109 rosbag::View bag_view_selected ( true );
00110 bag_view_selected.addQuery( _bag, [&topic_selected](rosbag::ConnectionInfo const* connection)
00111 {
00112 return topic_selected.find( connection->topic ) != topic_selected.end();
00113 } );
00114 progress_dialog.setRange(0, bag_view_selected.size()-1);
00115 progress_dialog.show();
00116
00117 QElapsedTimer timer;
00118 timer.start();
00119
00120 ROSTypeFlat flat_container;
00121
00122 SString topicname_SS;
00123 std::vector<uint8_t> buffer;
00124
00125 for(rosbag::MessageInstance msg_instance: bag_view_selected )
00126 {
00127 const std::string& topic = msg_instance.getTopic();
00128
00129
00130
00131 if( topic.at(0) == '/' )
00132 topicname_SS.assign( topic.data() +1, topic.size()-1 );
00133 else
00134 topicname_SS.assign( topic.data(), topic.size() );
00135
00136 const auto& datatype = msg_instance.getDataType();
00137 const auto msg_size = msg_instance.size();
00138 buffer.resize(msg_size);
00139
00140 if( count++ %100 == 0)
00141 {
00142 progress_dialog.setValue( count );
00143 QApplication::processEvents();
00144
00145 if( progress_dialog.wasCanceled() ) {
00146 return PlotDataMap();
00147 }
00148 }
00149
00150 ros::serialization::OStream stream(buffer.data(), buffer.size());
00151
00152
00153 msg_instance.write(stream);
00154
00155 auto typelist = RosIntrospectionFactory::get().getRosTypeList( topic );
00156 if( !typelist )
00157 {
00158 throw std::runtime_error("Can't retrieve the ROSTypeList from RosIntrospectionFactory");
00159 }
00160 buildRosFlatType( *typelist, rostype[datatype], topicname_SS,
00161 buffer.data(), &flat_container, 250);
00162
00163 static RenamedValues renamed_value;
00164
00165 auto rules_it = _rules.find(datatype);
00166 if(rules_it != _rules.end())
00167 {
00168 applyNameTransform( rules_it->second, flat_container, renamed_value );
00169 }
00170 else{
00171 applyNameTransform( std::vector<SubstitutionRule>(), flat_container, renamed_value );
00172 }
00173
00174
00175 double msg_time = 0;
00176
00177 if(dialog->checkBoxUseHeaderStamp()->isChecked() == false)
00178 {
00179 msg_time = msg_instance.getTime().toSec();
00180 }
00181 else{
00182 auto offset = FlatContainedContainHeaderStamp(renamed_value);
00183 if(offset){
00184 msg_time = offset.value();
00185 }
00186 else{
00187 msg_time = msg_instance.getTime().toSec();
00188 }
00189 }
00190
00191 for(const auto& it: renamed_value )
00192 {
00193 const std::string& field_name = it.first;
00194
00195 auto plot_pair = plot_map.numeric.find( field_name );
00196 if( plot_pair == plot_map.numeric.end() )
00197 {
00198 PlotDataPtr temp(new PlotData(field_name.data()));
00199 auto res = plot_map.numeric.insert( std::make_pair(field_name, temp ) );
00200 plot_pair = res.first;
00201 }
00202
00203 PlotDataPtr& plot_data = plot_pair->second;
00204 const RosIntrospection::VarNumber& var_value = it.second;
00205 plot_data->pushBack( PlotData::Point(msg_time, var_value.convert<double>() ));
00206 }
00207
00208
00209
00210 {
00211 auto plot_pair = plot_map.user_defined.find( topic );
00212
00213 if( plot_pair == plot_map.user_defined.end() )
00214 {
00215 PlotDataAnyPtr temp(new PlotDataAny(topic.c_str()));
00216 auto res = plot_map.user_defined.insert( std::make_pair( topic, temp ) );
00217 plot_pair = res.first;
00218 }
00219 PlotDataAnyPtr& plot_raw = plot_pair->second;
00220 plot_raw->pushBack( PlotDataAny::Point(msg_time, nonstd::any(std::move(msg_instance)) ));
00221 }
00222 }
00223
00224 qDebug() << "The loading operation took" << timer.elapsed() << "milliseconds";
00225 return plot_map;
00226 }
00227
00228
00229 DataLoadROS::~DataLoadROS()
00230 {
00231
00232 }
00233
00234