dataload_ros.cpp
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             // change the names in load_configuration
00092             load_configuration.append( item ).append(" ");
00093         }
00094         // load the rules
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         // WORKAROUND. There are some problems related to renaming when the character / is
00130         // used as prefix. We will remove that here.
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         // this single line takes almost the entire time of the loop
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         // apply time offsets
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         } //end of for renamed_value
00207 
00208         //-----------------------------------------
00209         // adding raw serialized topic for future uses.
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 


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56