10 #include <QProgressDialog> 12 #include <QApplication> 16 #include <QFileDialog> 22 #include "../dialog_select_ros_topics.h" 23 #include "../rule_editing.h" 24 #include "../qnodedialog.h" 25 #include "../shape_shifter_factory.hpp" 30 _destination_data(nullptr),
31 _action_saveIntoRosbag(nullptr),
43 const std::string &topic_name)
50 const auto& md5sum = msg->getMD5Sum();
51 const auto& datatype = msg->getDataType();
52 const auto& definition = msg->getMessageDefinition() ;
64 static std::vector<uint8_t> buffer;
66 buffer.resize( msg->size() );
83 for (
auto& it:
dataMap().user_defined ){
96 std::lock_guard<std::mutex> lock(
mutex() );
97 const std::string prefixed_topic_name =
_prefix + topic_name;
103 if( plot_pair ==
dataMap().user_defined.end() )
107 PlotDataAny& user_defined_data = plot_pair->second;
117 const std::string key = prefixed_topic_name + (
"/_MSG_INDEX_") ;
123 index_it->second.pushBack( PlotData::Point(msg_time, index) );
129 using namespace std::chrono;
130 milliseconds wait_time_ms(1000);
132 QProgressDialog progress_dialog;
133 progress_dialog.setLabelText(
"Collecting ROS topic samples to understand data layout. ");
134 progress_dialog.setRange(0, wait_time_ms.count());
135 progress_dialog.setAutoClose(
true);
136 progress_dialog.setAutoReset(
true);
138 progress_dialog.show();
140 auto start_time = system_clock::now();
142 while ( system_clock::now() - start_time < (wait_time_ms) )
145 int i = duration_cast<milliseconds>(system_clock::now() - start_time).count() ;
146 progress_dialog.setValue( i );
147 QApplication::processEvents();
148 if( progress_dialog.wasCanceled() )
154 if( progress_dialog.wasCanceled() == false )
156 progress_dialog.cancel();
165 auto ret = QMessageBox::warning(
nullptr,
167 tr(
"The roscore master cannot be detected.\n\n" 168 "Do you want to try reconnecting to it? \n\n" 169 "NOTE: if you select CONTINUE, you might need" 170 " to stop and restart this plugin."),
188 _spinner = std::make_shared<ros::AsyncSpinner>(1);
204 QMessageBox::warning(
nullptr, tr(
"Warning"), tr(
"Your buffer is empty. Nothing to save.\n") );
208 QFileDialog saveDialog;
209 saveDialog.setAcceptMode(QFileDialog::AcceptSave);
210 saveDialog.setDefaultSuffix(
"bag");
213 if(saveDialog.result() != QDialog::Accepted || saveDialog.selectedFiles().empty())
218 QString fileName = saveDialog.selectedFiles().first();
220 if( fileName.size() > 0)
226 const std::string& topicname = it.first;
227 const auto& plotdata = it.second;
230 if(!registered_msg_type)
continue;
233 msg.
morph(registered_msg_type->getMD5Sum(),
234 registered_msg_type->getDataType(),
235 registered_msg_type->getMessageDefinition());
237 for (
int i=0;
i< plotdata.size();
i++)
239 const auto& point = plotdata.at(
i);
243 if(type_erased_buffer.
type() !=
typeid( std::vector<uint8_t> ))
249 std::vector<uint8_t> raw_buffer =
nonstd::any_cast<std::vector<uint8_t>>( type_erased_buffer );
260 args <<
"reindex" << fileName;
261 process.start(
"rosbag" , args);
270 boost::function<void(const rosgraph_msgs::Clock::ConstPtr&) > callback;
271 callback = [
this](
const rosgraph_msgs::Clock::ConstPtr&
msg) ->
void 280 boost::function<void(const topic_tools::ShapeShifter::ConstPtr&) > callback;
307 std::lock_guard<std::mutex> lock(
mutex() );
314 std::vector<std::pair<QString,QString>> all_topics;
319 all_topics.push_back(
320 std::make_pair(QString(topic_info.name.c_str()),
321 QString(topic_info.datatype.c_str()) ) );
325 timer.setSingleShot(
false);
326 timer.setInterval( 1000);
331 connect( &timer, &QTimer::timeout, [&]()
338 all_topics.push_back(
339 std::make_pair(QString(topic_info.name.c_str()),
340 QString(topic_info.datatype.c_str()) ) );
345 int res = dialog.exec();
373 _spinner = std::make_shared<ros::AsyncSpinner>(1);
394 it.second.shutdown();
396 _subscribers.clear();
409 QDomElement stamp_elem = doc.createElement(
"use_header_stamp");
411 plugin_elem.appendChild( stamp_elem );
413 QDomElement rename_elem = doc.createElement(
"use_renaming_rules");
415 plugin_elem.appendChild( rename_elem );
417 QDomElement discard_elem = doc.createElement(
"discard_large_arrays");
419 plugin_elem.appendChild( discard_elem );
421 QDomElement max_elem = doc.createElement(
"max_array_size");
423 plugin_elem.appendChild( max_elem );
430 QDomElement stamp_elem = parent_element.firstChildElement(
"use_header_stamp" );
433 QDomElement rename_elem = parent_element.firstChildElement(
"use_renaming_rules" );
436 QDomElement discard_elem = parent_element.firstChildElement(
"discard_large_arrays" );
439 QDomElement max_elem = parent_element.firstChildElement(
"max_array_size" );
449 iconSave.addFile(QStringLiteral(
":/icons/resources/light/save.png"), QSize(26, 26));
ValueType any_cast(any const &operand)
void topicCallback(const topic_tools::ShapeShifter::ConstPtr &msg, const std::string &topic_name)
std::unordered_map< std::string, PlotData > numeric
PlotDataMapRef & dataMap()
void initByFullCallbackType(const std::string &_topic, uint32_t _queue_size, const boost::function< void(P)> &_callback, const boost::function< boost::shared_ptr< typename ParameterAdapter< P >::Message >(void)> &factory_fn=DefaultMessageCreator< typename ParameterAdapter< P >::Message >())
static void registerMessage(const std::string &topic_name, const std::string &md5sum, const std::string &datatype, const std::string &definition)
void updateTopicList(std::vector< std::pair< QString, QString >> topic_list)
bool discard_large_arrays
void extractInitialSamples()
virtual void addActionsToParentMenu(QMenu *menu) override
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
void saveDefaultSettings()
QStringList selected_topics
static RosIntrospectionFactory & get()
void loadDefaultSettings()
std::unordered_map< std::string, PlotDataAny >::iterator addUserDefined(const std::string &name)
std::vector< TopicInfo > V_TopicInfo
virtual void shutdown() override
std::unordered_map< std::string, PlotDataAny > user_defined
void morph(const std::string &md5sum, const std::string &datatype_, const std::string &msg_def_)
ROSCPP_DECL CallbackQueue * getGlobalCallbackQueue()
TransportHints & tcpNoDelay(bool nodelay=true)
PlotDataMapRef * _destination_data
void read(Stream &stream)
virtual bool start(QStringList *selected_datasources) override
std::map< std::string, int > _msg_index
bool _roscore_disconnection_already_notified
void setMaxArrayPolicy(size_t max_array_size, bool discard_entire_array)
void pushMessageRef(const std::string &topic_name, const MessageRef &msg, double timestamp) override
virtual bool xmlLoadState(const QDomElement &parent_element) override
static RosIntrospection::SubstitutionRuleMap getRenamingRules()
virtual void extractData(PlotDataMapRef &destination, const std::string &prefix) override
Configuration getResult() const
static ros::NodeHandlePtr getNode()
TransportHints transport_hints
virtual ~DataStreamROS() override
RosMessageParser _ros_parser
virtual bool xmlSaveState(QDomDocument &doc, QDomElement &parent_element) const override
DialogSelectRosTopics::Configuration _config
std::unordered_map< std::string, PlotData >::iterator addNumeric(const std::string &name)
static RosIntrospection::ShapeShifter * getShapeShifter(const std::string &topic_name)
virtual bool isRunning() const override
The DataStreamer base class to create your own plugin.
const std::type_info & type() const any_noexcept
void clockCallback(const rosgraph_msgs::Clock::ConstPtr &msg)
std::map< std::string, ros::Subscriber > _subscribers
void setUseHeaderStamp(bool use)
static void saveIntoRosbag(const PlotDataMapRef &data)
void addRules(const RosIntrospection::SubstitutionRuleMap &rules)
bool registerSchema(const std::string &topic_name, const std::string &md5sum, RosIntrospection::ROSType type, const std::string &definition)
std::shared_ptr< ros::AsyncSpinner > _spinner
QAction * _action_saveIntoRosbag