rosout_publisher.cpp
Go to the documentation of this file.
00001 #include "rosout_publisher.h"
00002 #include "PlotJuggler/any.hpp"
00003 #include "../shape_shifter_factory.hpp"
00004 #include "../qnodedialog.h"
00005 #include <QSettings>
00006 #include <rosbag/bag.h>
00007 
00008 RosoutPublisher::RosoutPublisher():
00009     _enabled(false ),
00010     _tablemodel(nullptr),
00011     _log_window(nullptr)
00012 {
00013 
00014 }
00015 
00016 RosoutPublisher::~RosoutPublisher()
00017 {
00018 
00019 }
00020 
00021 
00022 void RosoutPublisher::setEnabled(bool to_enable)
00023 {
00024     _enabled = to_enable;
00025 
00026     if( enabled())
00027     {
00028         _minimum_time_usec = std::numeric_limits<int64_t>::max();
00029         _maximum_time_usec = std::numeric_limits<int64_t>::min();
00030 
00031         if( _tablemodel == nullptr ){
00032           _tablemodel = new LogsTableModel(this);
00033         }
00034 
00035         _log_window = new RosoutWindow();
00036 
00037         auto logwidget = new rqt_console_plus::LogWidget( *_tablemodel, _log_window);
00038         _log_window->setCentralWidget( logwidget );
00039         Qt::WindowFlags flags = _log_window->windowFlags();
00040         _log_window->setWindowFlags( flags | Qt::SubWindow );
00041 
00042         connect( this, &RosoutPublisher::timeRangeChanged,
00043                  logwidget, &rqt_console_plus::LogWidget::on_timeRangeChanged );
00044 
00045         connect(_log_window, &RosoutWindow::closed,
00046                 this, &RosoutPublisher::onWindowClosed );
00047 
00048         QSettings settings;
00049         _log_window->restoreGeometry(settings.value("RosoutPublisher.geometry").toByteArray());
00050 
00051         _log_window->show();
00052     }
00053     else{
00054         if( _log_window )
00055         {
00056             _log_window->close();
00057         }
00058     }
00059 
00060     StatePublisher::setEnabled(_enabled);
00061 }
00062 
00063 void RosoutPublisher::onWindowClosed()
00064 {
00065     QSettings settings;
00066     settings.setValue("RosoutPublisher.geometry", _log_window->saveGeometry());
00067 
00068     if( _tablemodel ){
00069       _tablemodel->deleteLater();
00070       _tablemodel = nullptr;
00071     }
00072     if( _log_window ) {
00073       _log_window->deleteLater();
00074       _log_window = nullptr;
00075     }
00076     _enabled = false;
00077 }
00078 
00079 
00080 std::vector<const PlotDataAny *> RosoutPublisher::findRosoutTimeseries()
00081 {
00082     std::vector<const PlotDataAny*> logs_timeseries;
00083 
00084     for(const auto& data_it: _datamap->user_defined )
00085     {
00086         const std::string& topic_name = data_it.first;
00087 
00088         // check if I registered this message before
00089         const RosIntrospection::ShapeShifter* registered_shapeshifted_msg = RosIntrospectionFactory::get().getShapeShifter( topic_name );
00090         if( ! registered_shapeshifted_msg )
00091         {
00092             continue; // will not be able to use this anyway, just skip
00093         }
00094 
00095         if(registered_shapeshifted_msg->getMD5Sum() != std::string(ros::message_traits::MD5Sum< rosgraph_msgs::Log >::value()) )
00096         {
00097             continue; // it is NOT a rosgraph_msgs::Log
00098         }
00099 
00100         logs_timeseries.push_back(  &data_it.second );
00101     }
00102 
00103     return logs_timeseries;
00104 }
00105 
00106 void RosoutPublisher::syncWithTableModel(const std::vector<const PlotDataAny*>& logs_timeseries)
00107 {
00108     const int64_t threshold_time = _maximum_time_usec;
00109 
00110     std::vector<rosgraph_msgs::LogConstPtr> logs;
00111     logs.reserve(100);
00112 
00113     // most of the time we expect logs_timeseries to have just 1 element
00114     for(const  PlotDataAny* type_erased_logs:  logs_timeseries )
00115     {
00116         const int first_index = type_erased_logs->getIndexFromX( threshold_time );
00117 
00118         if( first_index != -1)
00119         { 
00120             for( int i=first_index; i< type_erased_logs->size(); i++)
00121             {
00122                 const auto&        any_msg   = type_erased_logs->at(i);
00123                 const nonstd::any& any_value = any_msg.y;
00124 
00125                 const bool isRawBuffer     = any_value.type() == typeid( std::vector<uint8_t>);
00126                 const bool isRosbagMessage = any_value.type() == typeid( rosbag::MessageInstance );
00127                 std::vector<uint8_t> raw_buffer;
00128 
00129                 if( isRawBuffer){
00130                   raw_buffer = nonstd::any_cast<std::vector<uint8_t>>( any_value );
00131                 }
00132                 else if( isRosbagMessage ){
00133                   const rosbag::MessageInstance& msg_instance = nonstd::any_cast<rosbag::MessageInstance>( any_value );
00134                   raw_buffer.resize( msg_instance.size() );
00135                   ros::serialization::OStream stream(raw_buffer.data(), raw_buffer.size());
00136                   msg_instance.write(stream);
00137                 }
00138                 else{
00139                   continue;
00140                 }
00141 
00142                 rosgraph_msgs::LogPtr p(boost::make_shared<rosgraph_msgs::Log>());
00143                 ros::serialization::IStream stream(raw_buffer.data(), raw_buffer.size() );
00144                 ros::serialization::deserialize(stream, *p);
00145 
00146                 int64_t usec = p->header.stamp.toNSec() / 1000;
00147                 _minimum_time_usec = std::min( _minimum_time_usec, usec);
00148                 _maximum_time_usec = std::max( _maximum_time_usec, usec);
00149 
00150                 if( usec >= threshold_time){
00151                     logs.push_back( p );
00152                 }
00153             } 
00154         }
00155     }
00156     std::sort( logs.begin(), logs.end(),
00157                [](const rosgraph_msgs::LogConstPtr& a, const rosgraph_msgs::LogConstPtr& b)
00158     {
00159         return a->header.stamp < b->header.stamp;
00160     } );
00161     _tablemodel->push_back( logs );
00162 }
00163 
00164 void RosoutPublisher::updateState(double current_time)
00165 {
00166     if(!_enabled && !_tablemodel) return;
00167 
00168     std::vector<const PlotDataAny*> logs_timeseries = findRosoutTimeseries();
00169 
00170     syncWithTableModel(logs_timeseries);
00171 
00172     using namespace std::chrono;
00173     TimePoint p_min  = TimePoint() + microseconds(_minimum_time_usec);
00174     //TimePoint p_max  = TimePoint() + microseconds(_maximum_time_usec);
00175     TimePoint p_curr = TimePoint() + microseconds( (int64_t)(current_time*1000000));
00176 
00177     emit timeRangeChanged(p_min, p_curr);
00178 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Wed Jul 3 2019 19:28:05