6 qRegisterMetaType<QMessageBox::Icon>();
8 setCentralWidget(parent);
9 QHBoxLayout *layout(
new QHBoxLayout);
10 parent->setLayout(layout);
12 setWindowTitle(
"ROS bag exporter");
14 QMenu *menu(
new QMenu(
"File"));
15 menuBar()->addMenu(menu);
17 QAction *open_bag(
new QAction(
"Open", menu));
18 open_bag->setToolTip(
"Open a bag file");
20 menu->addAction(open_bag);
21 QAction *export_topics(
new QAction(
"Export", menu));
22 export_topics->setToolTip(
"Export topics to files");
24 menu->addAction(export_topics);
26 QVBoxLayout *left =
new QVBoxLayout;
27 left->addWidget(
new QLabel(
"Topics to be exported"));
32 QVBoxLayout *right(
new QVBoxLayout);
33 right->addWidget(
new QLabel(
"Start / end time"));
39 QHBoxLayout *start_end_time(
new QHBoxLayout);
41 start_end_time->addWidget(
new QLabel(
" sec"));
43 start_end_time->addWidget(
new QLabel(
" sec"));
49 QWidget* first_tab(
new QWidget);
50 QVBoxLayout *tab_information(
new QVBoxLayout);
51 QSpinBox* observed_fps(
new QSpinBox);
52 observed_fps->setEnabled(
false);
53 QHBoxLayout *video_fps(
new QHBoxLayout);
54 QSpinBox* fps(
new QSpinBox);
55 fps->setEnabled(
false);
56 video_fps->addWidget(
new QLabel(
"Video FPS"));
57 video_fps->addWidget(fps);
58 tab_information->addWidget(
new QLabel(
"Observed FPS"));
59 tab_information->addWidget(observed_fps);
60 tab_information->addLayout(video_fps);
61 first_tab->setLayout(tab_information);
65 layout->addLayout(left);
66 layout->addLayout(right);
70 connect(
this, SIGNAL(
displayMessageBox(
const QString,
const QString,
const QString,
const QMessageBox::Icon)),
this,
85 rqt_bag_exporter::CloseBag srv;
89 QString::fromStdString(
"Service server " + client.
getService() +
" does not exist."),
91 QMessageBox::Icon::Critical);
95 if (!client.
call(srv))
98 QString::fromStdString(
"Failed to call service " + client.
getService()),
100 QMessageBox::Icon::Critical);
104 if (!srv.response.error.empty())
107 QString::fromStdString(srv.response.error),
109 QMessageBox::Icon::Critical);
116 const std::string file_name(QFileDialog::getOpenFileName(
this,
"Open bag file",
117 settings_->value(
"open_path").toString(),
118 "Bag files (*.bag)", Q_NULLPTR).toStdString());
119 if (file_name.empty())
122 std::string path_file(file_name);
123 const int pos(path_file.find_last_of(
"/"));
124 path_file.erase(pos, std::string::npos);
125 settings_->setValue(
"open_path", QString::fromStdString(path_file));
131 QString::fromStdString(
"Service server " + client.
getService() +
" does not exist."),
133 QMessageBox::Icon::Critical);
137 rqt_bag_exporter::OpenBag srv;
138 srv.request.bag_file = file_name;
139 if (!client.
call(srv))
142 QString::fromStdString(
"Failed to call service " + client.
getService()),
144 QMessageBox::Icon::Critical);
147 if (!srv.response.error.empty())
150 QString::fromStdString(srv.response.error),
152 QMessageBox::Icon::Critical);
160 for (std::size_t i(0); i <
topics_list_.topics_type.size(); ++i)
162 if (
topics_list_.topics_type[i].find(
"sensor_msgs/CompressedImage") != std::string::npos)
170 rqt_bag_exporter::ListTopics srv;
174 QString::fromStdString(
"Service server " + client.
getService() +
" does not exist."),
176 QMessageBox::Icon::Critical);
180 if (!client.
call(srv))
183 QString::fromStdString(
"Failed to call service " + client.
getService()),
185 QMessageBox::Icon::Critical);
189 if (!srv.response.error.empty())
192 QString::fromStdString(srv.response.error),
194 QMessageBox::Icon::Critical);
198 if (srv.response.topics_name.size() != srv.response.topics_type.size())
201 "Topics names and topics type are of different sizes",
203 QMessageBox::Icon::Critical);
209 for (std::size_t i(0); i < srv.response.topics_name.size(); ++i)
211 topics_list_.topics_name.push_back(srv.response.topics_name[i]);
212 topics_list_.topics_type.push_back(srv.response.topics_type[i]);
218 QVBoxLayout* checkbox_layout(
new QVBoxLayout);
221 for (std::size_t i(0); i <
topics_list_.topics_name.size(); ++i)
225 QHBoxLayout *sub_checkbox_layout(
new QHBoxLayout);
226 QCheckBox *checkbox =
new QCheckBox(QString::fromStdString(
topics_list_.topics_name[i]));
228 if (!check_csv_type && !check_video_type)
229 checkbox->setEnabled(
false);
231 checkbox->setObjectName(QString::fromStdString(
topics_list_.topics_type[i]));
232 sub_checkbox_layout->addWidget(checkbox);
233 std::string topic_type(
"(" +
topics_list_.topics_type[i] +
")");
234 sub_checkbox_layout->addWidget(
new QLabel(QString::fromStdString(topic_type)));
235 checkbox_layout->addLayout(sub_checkbox_layout);
241 if (topic_type.find(
"sensor_msgs/CompressedImage") != std::string::npos)
248 if (topic_type.find(
"std_msgs/Bool") != std::string::npos)
251 if (topic_type.find(
"std_msgs/Duration") != std::string::npos)
254 if (topic_type.find(
"std_msgs/Float32") != std::string::npos)
257 if (topic_type.find(
"std_msgs/Float64") != std::string::npos)
260 if (topic_type.find(
"std_msgs/Int16") != std::string::npos)
263 if (topic_type.find(
"std_msgs/Int32") != std::string::npos)
266 if (topic_type.find(
"std_msgs/Int64") != std::string::npos)
269 if (topic_type.find(
"std_msgs/Int8") != std::string::npos)
272 if (topic_type.find(
"std_msgs/String") != std::string::npos)
275 if (topic_type.find(
"std_msgs/Time") != std::string::npos)
278 if (topic_type.find(
"std_msgs/UInt16") != std::string::npos)
281 if (topic_type.find(
"std_msgs/UInt32") != std::string::npos)
284 if (topic_type.find(
"std_msgs/UInt64") != std::string::npos)
287 if (topic_type.find(
"std_msgs/UInt8") != std::string::npos)
296 rqt_bag_exporter::GetDuration srv;
300 QString::fromStdString(
"Service server " + client.
getService() +
" does not exist."),
302 QMessageBox::Icon::Critical);
305 if (!client.
call(srv))
308 QString::fromStdString(
"Failed to call service " + client.
getService()),
310 QMessageBox::Icon::Critical);
314 if (!srv.response.error.empty())
317 QString::fromStdString(srv.response.error),
319 QMessageBox::Icon::Critical);
323 if (srv.response.duration == 0)
326 "Video duration is zero",
328 QMessageBox::Icon::Critical);
335 time_end_->setRange(0, srv.response.duration);
336 time_end_->setValue(srv.response.duration);
342 "estimate_video_fps");
343 rqt_bag_exporter::EstimateVideoFps srv;
344 srv.request.topic_name = topic_name;
348 QString::fromStdString(
"Service server " + client.
getService() +
" does not exist."),
350 QMessageBox::Icon::Critical);
354 if (!client.
call(srv))
357 QString::fromStdString(
"Failed to call service " + client.
getService()),
359 QMessageBox::Icon::Critical);
363 if (srv.response.fps == 0)
365 Q_EMIT
displayMessageBox(
"Error getting topics",
"Fail to get back video fps of rosbag",
"",
366 QMessageBox::Icon::Critical);
370 fps_ = srv.response.fps;
371 QWidget* tab(
new QWidget);
372 QVBoxLayout *tab_information(
new QVBoxLayout);
373 QSpinBox* observed_fps(
new QSpinBox);
374 observed_fps->setEnabled(
false);
375 observed_fps->setValue(srv.response.fps);
376 QHBoxLayout *video_fps(
new QHBoxLayout);
377 QSpinBox* fps(
new QSpinBox);
378 fps->setMaximum(999);
379 fps->setValue(srv.response.fps);
380 video_fps->addWidget(
new QLabel(
"Video FPS"));
381 video_fps->addWidget(fps);
382 tab_information->addWidget(
new QLabel(
"Observed FPS"));
383 tab_information->addWidget(observed_fps);
384 tab_information->addLayout(video_fps);
385 tab->setLayout(tab_information);
386 video_tab_->addTab(tab, QString::fromStdString(srv.request.topic_name));
388 connect(fps, SIGNAL(valueChanged(
int)),
this, SLOT(
updateFps(
int)));
404 if (time_end <= time_begin_->value())
413 Q_EMIT
displayMessageBox(
"Zero topic to export",
"Choose at least one topic to be exported",
"",
414 QMessageBox::Icon::Warning);
419 QFileDialog::getExistingDirectory(
422 settings_->value(
"path_directory").toString(),
423 QFileDialog::ShowDirsOnly).toStdString();
443 Q_EMIT
displayMessageBox(
"Error getting topics",
"Action server does not exist.",
"",
444 QMessageBox::Icon::Critical);
447 rqt_bag_exporter::ExportToCSVGoal goal;
448 rqt_bag_exporter::ExportToCSVResult result;
461 bool finished_before_timeout =
csv_ac_->waitForResult();
462 if (finished_before_timeout)
464 if (!result.error.empty())
466 Q_EMIT
displayMessageBox(
"Error from action", QString::fromStdString(result.error),
"",
467 QMessageBox::Icon::Critical);
473 Q_EMIT
displayMessageBox(
"Error getting topics",
"Action did not finish before the time out.",
"",
474 QMessageBox::Icon::Critical);
476 if (check_video_type)
480 Q_EMIT
displayMessageBox(
"Error getting topics",
"Action server does not exist.",
"",
481 QMessageBox::Icon::Critical);
484 rqt_bag_exporter::ExportToVideoGoal goal;
485 rqt_bag_exporter::ExportToVideoResult result;
498 bool finished_before_timeout =
video_ac_->waitForResult();
500 if (finished_before_timeout)
502 if (!result.error.empty())
504 Q_EMIT
displayMessageBox(
"Error from action", QString::fromStdString(result.error),
"",
505 QMessageBox::Icon::Critical);
511 Q_EMIT
displayMessageBox(
"Error getting topics",
"Action did not finish before the time out.",
"",
512 QMessageBox::Icon::Critical);
522 QList<QCheckBox *> all_check_box =
topics_container_->findChildren<QCheckBox *>();
523 for (
int i(0); i < all_check_box.size(); ++i)
525 if (all_check_box[i]->isChecked())
528 topics_to_export_.topics_type.push_back(all_check_box[i]->objectName().toStdString());
534 const rqt_bag_exporter::ExportToCSVResultConstPtr &result)
540 if (result->error.empty())
552 std::string error_msg(
"Action exportToCSV Aborted with error :" + result->error);
553 Q_EMIT
displayMessageBox(
"Error from action", QString::fromStdString(error_msg),
"",
554 QMessageBox::Icon::Critical);
567 Q_EMIT
progress_dialog_->drawProgress(feedback->progress_value, QString::fromStdString(feedback->progress_msg));
571 const rqt_bag_exporter::ExportToVideoResultConstPtr &result)
577 if (result->error.empty())
589 std::string error_msg(
"Action exportToVideo Aborted with error :" + result->error);
590 Q_EMIT
displayMessageBox(
"Error from action", QString::fromStdString(error_msg),
"",
591 QMessageBox::Icon::Critical);
605 Q_EMIT
progress_dialog_->drawProgress(feedback->progress_value, QString::fromStdString(feedback->progress_msg));
611 settings_ =
new QSettings(
"Institut Maupertuis",
"rqt_bag_exporter");
612 settings_->setValue(
"geometry", saveGeometry());
613 settings_->setValue(
"window_state", saveState());
614 QMainWindow::closeEvent(event);
619 settings_ =
new QSettings(
"Institut Maupertuis",
"rqt_bag_exporter");
620 restoreGeometry(
settings_->value(
"geometry").toByteArray());
621 restoreState(
settings_->value(
"window_state").toByteArray());
625 const QString message,
626 const QString info_msg,
627 const QMessageBox::Icon icon)
629 const bool old(isEnabled());
630 Q_EMIT setEnabled(
false);
632 msg_box.setWindowTitle(title);
633 msg_box.setText(message);
634 msg_box.setInformativeText(info_msg);
635 msg_box.setIcon(icon);
636 msg_box.setStandardButtons(QMessageBox::Ok);
638 Q_EMIT setEnabled(old);
actionlib::SimpleActionClient< rqt_bag_exporter::ExportToVideoAction > ExportToVideoActionClient
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
void fillTopicsToExport()
void csvDoneCb(const actionlib::SimpleClientGoalState &state, const rqt_bag_exporter::ExportToCSVResultConstPtr &result)
void closeEvent(QCloseEvent *event)
void updateTimeBegin(const double time_end)
bool call(MReq &req, MRes &res)
bool isCompressedImageTopic(const std::string topic_type)
void displayMessageBoxHandler(const QString title, const QString message, const QString info_msg="", const QMessageBox::Icon icon=QMessageBox::Icon::Information)
void videoDoneCb(const actionlib::SimpleClientGoalState &state, const rqt_bag_exporter::ExportToVideoResultConstPtr &result)
QDoubleSpinBox * time_begin_
void fillVideoTab(const std::string topic_name)
rqt_bag_exporter::ListTopicsResponse topics_to_export_
QDoubleSpinBox * time_end_
rqt_bag_exporter::ListTopicsResponse topics_list_
std::shared_ptr< ProgressDialog > progress_dialog_
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
QWidget * topics_container_
MainWindow(QWidget *parent=0)
void csvFeedbackCb(const rqt_bag_exporter::ExportToCSVFeedbackConstPtr &feedback)
actionlib::SimpleActionClient< rqt_bag_exporter::ExportToCSVAction > ExportToCSVActionClient
QWidget * start_end_time_
bool isCsvWritableTopic(const std::string topic_type)
void updateTimeEnd(const double time_begin)
std::unique_ptr< ExportToCSVActionClient > csv_ac_
void displayMessageBox(const QString, const QString, const QString, const QMessageBox::Icon)
void updateFps(const int fps)
void videoFeedbackCb(const rqt_bag_exporter::ExportToVideoFeedbackConstPtr &feedback)
void listTopicsInBagFile()
std::unique_ptr< ExportToVideoActionClient > video_ac_