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
00007 RosoutPublisher::RosoutPublisher():
00008 enabled_(false ),
00009 _tablemodel(nullptr)
00010 {
00011
00012 }
00013
00014 RosoutPublisher::~RosoutPublisher()
00015 {
00016
00017 }
00018
00019
00020 void RosoutPublisher::setEnabled(bool to_enable)
00021 {
00022 enabled_ = to_enable;
00023
00024 if( enabled())
00025 {
00026 _minimum_time_usec = std::numeric_limits<int64_t>::max();
00027 _maximum_time_usec = std::numeric_limits<int64_t>::min();
00028
00029 if( _tablemodel == nullptr ){
00030 _tablemodel = new LogsTableModel(this);
00031 }
00032
00033 _log_window = new RosoutWindow();
00034
00035 auto logwidget = new rqt_console_plus::LogWidget( *_tablemodel, _log_window);
00036 _log_window->setCentralWidget( logwidget );
00037 Qt::WindowFlags flags = _log_window->windowFlags();
00038 _log_window->setWindowFlags( flags | Qt::SubWindow );
00039
00040 connect( this, &RosoutPublisher::timeRangeChanged,
00041 logwidget, &rqt_console_plus::LogWidget::on_timeRangeChanged );
00042
00043 connect(_log_window, &RosoutWindow::closed,
00044 this, &RosoutPublisher::onWindowClosed );
00045
00046 QSettings settings( "IcarusTechnology", "PlotJuggler");
00047 _log_window->restoreGeometry(settings.value("RosoutPublisher.geometry").toByteArray());
00048
00049 _log_window->show();
00050 }
00051 else{
00052 if( _log_window )
00053 {
00054 _log_window->close();
00055 }
00056 }
00057 }
00058
00059 void RosoutPublisher::onWindowClosed()
00060 {
00061 QSettings settings( "IcarusTechnology", "PlotJuggler");
00062 settings.setValue("RosoutPublisher.geometry", _log_window->saveGeometry());
00063
00064 if( _tablemodel ){
00065 _tablemodel->deleteLater();
00066 _tablemodel = nullptr;
00067 }
00068 if( _log_window ) {
00069 _log_window->deleteLater();
00070 _log_window = nullptr;
00071 }
00072 enabled_ = false;
00073 }
00074
00075
00076 std::vector<const PlotDataAny *> RosoutPublisher::findRosoutTimeseries(PlotDataMap *datamap)
00077 {
00078 std::vector<const PlotDataAny*> logs_timeseries;
00079
00080 for(const auto& data_it: datamap->user_defined )
00081 {
00082 const std::string& topic_name = data_it.first;
00083
00084
00085 const RosIntrospection::ShapeShifter* registered_shapeshifted_msg = RosIntrospectionFactory::get().getShapeShifter( topic_name );
00086 if( ! registered_shapeshifted_msg )
00087 {
00088 continue;
00089 }
00090
00091 if(registered_shapeshifted_msg->getMD5Sum() != std::string(ros::message_traits::MD5Sum< rosgraph_msgs::Log >::value()) )
00092 {
00093 continue;
00094 }
00095
00096 logs_timeseries.push_back( data_it.second.get() );
00097 }
00098
00099 return logs_timeseries;
00100 }
00101
00102 void RosoutPublisher::syncWithTableModel(const std::vector<const PlotDataAny*>& logs_timeseries)
00103 {
00104 const int64_t threshold_time = _maximum_time_usec;
00105
00106 std::vector<rosgraph_msgs::LogConstPtr> logs;
00107 logs.reserve(100);
00108
00109
00110 for(const PlotDataAny* type_erased_logs: logs_timeseries )
00111 {
00112 const int first_index = type_erased_logs->getIndexFromX( threshold_time );
00113
00114 if( first_index != -1)
00115 {
00116 for( int i=first_index; i< type_erased_logs->size(); i++)
00117 {
00118 auto any_msg = type_erased_logs->at(i);
00119 nonstd::any any_value = any_msg.y;
00120
00121 std::vector<uint8_t> raw_buffer = nonstd::any_cast<std::vector<uint8_t>>( any_value );
00122
00123 rosgraph_msgs::LogPtr p(boost::make_shared<rosgraph_msgs::Log>());
00124 ros::serialization::IStream stream(raw_buffer.data(), raw_buffer.size() );
00125 ros::serialization::deserialize(stream, *p);
00126
00127 int64_t usec = p->header.stamp.toNSec() / 1000;
00128 _minimum_time_usec = std::min( _minimum_time_usec, usec);
00129 _maximum_time_usec = std::max( _maximum_time_usec, usec);
00130
00131 if( usec >= threshold_time){
00132 logs.push_back( p );
00133 }
00134 }
00135 }
00136 }
00137 std::sort( logs.begin(), logs.end(), [](const rosgraph_msgs::LogConstPtr& a, const rosgraph_msgs::LogConstPtr& b)
00138 {
00139 return a->header.stamp < b->header.stamp;
00140 } );
00141 _tablemodel->push_back( logs );
00142 }
00143
00144 void RosoutPublisher::updateState(PlotDataMap *datamap, double current_time)
00145 {
00146 if(!enabled_ && !_tablemodel) return;
00147
00148 std::vector<const PlotDataAny*> logs_timeseries = findRosoutTimeseries(datamap);
00149
00150 syncWithTableModel(logs_timeseries);
00151
00152 using namespace std::chrono;
00153 TimePoint p_min = TimePoint() + microseconds(_minimum_time_usec);
00154
00155 TimePoint p_curr = TimePoint() + microseconds( (int64_t)(current_time*1000000));
00156
00157 emit timeRangeChanged(p_min, p_curr);
00158 }