2 #include "ui_rosbag_editor.h" 5 #include <tf/tfMessage.h> 6 #include <tf2_msgs/TFMessage.h> 10 #include <QFileDialog> 14 #include <QDateTimeEdit> 15 #include <QMessageBox> 16 #include <QItemSelectionModel> 17 #include <QPushButton> 18 #include <QListWidget> 23 #include <QProgressDialog> 30 QApplication::setWindowIcon(QIcon(
"://rosbag_editor.png"));
33 QSettings settings(
"DavideFaconti",
"rosbag_editor");
34 _previous_load_path = settings.value(
"RosbagEditor/prevLoadPath", QDir::currentPath()).toString();
37 ui->radioNoCompression->setChecked(
true);
39 restoreGeometry(settings.value(
"RosbagEditor/geometry").toByteArray());
40 restoreState(settings.value(
"RosbagEditor/windowState").toByteArray());
45 QSettings settings(
"DavideFaconti",
"rosbag_editor");
46 settings.setValue(
"RosbagEditor/geometry", saveGeometry());
47 settings.setValue(
"RosbagEditor/windowState", saveState());
48 QMainWindow::closeEvent(event);
58 QString
filename = QFileDialog::getOpenFileName(
this,
61 if( filename.isEmpty())
67 ui->tableWidgetInput->setRowCount(0);
68 ui->tableWidgetOutput->setRowCount(0);
74 QMessageBox::warning(
this,
"Error opening the rosbag",
75 tr(
"rosbag::open thrown an exception: %1\n").arg( ex.what()) );
80 settings.setValue(
"RosbagEditor/prevLoadPath", QFileInfo(filename).absolutePath() );
82 ui->statusbar->showMessage( tr(
"File loaded: %1").arg(filename));
89 QDateTime datetime_begin = QDateTime::fromMSecsSinceEpoch( bag_view.
getBeginTime().
toSec()*1000 );
90 ui->dateTimeInputBegin->setDateTime(datetime_begin);
92 QDateTime datetime_end = QDateTime::fromMSecsSinceEpoch( bag_view.
getEndTime().
toSec()*1000 );
93 ui->dateTimeInputEnd->setDateTime(datetime_end);
96 std::map<QString,QString> connections_ordered;
98 for(std::size_t i = 0; i < connections.size(); i++ )
101 connections_ordered.insert( std::make_pair(QString::fromStdString(connection->
topic),
102 QString::fromStdString(connection->
datatype) ) );
105 ui->tableWidgetInput->setRowCount(connections_ordered.size());
106 ui->tableWidgetInput->setColumnCount(2);
107 ui->tableWidgetInput->setEnabled(
true);
110 for(
const auto conn: connections_ordered )
112 auto type_item =
new QTableWidgetItem( conn.second );
113 QFont font = type_item->font();
114 font.setPointSize(8);
115 font.setItalic(
true);
116 type_item->setFont(font);
118 ui->tableWidgetInput->setItem(row, 0,
new QTableWidgetItem( conn.first ) );
119 ui->tableWidgetInput->setItem(row, 1, type_item);
127 ui->pushButtonMove->setEnabled(
ui->tableWidgetInput->selectionModel()->selectedRows().count() > 0 );
128 bool output = (
ui->tableWidgetInput->rowCount() > 0);
129 ui->tableWidgetOutput->setEnabled( output );
130 ui->dateTimeOutputBegin->setEnabled( output );
131 ui->dateTimeOutputEnd->setEnabled( output );
132 ui->pushButtonSave->setEnabled( output );
134 bool contains_tf = !
ui->tableWidgetInput->findItems(
"/tf", Qt::MatchExactly ).empty();
135 ui->pushButtonFilterTF->setEnabled(
ui->checkBoxFilterTF->isChecked() && contains_tf );
140 QModelIndexList selected_input =
ui->tableWidgetInput->selectionModel()->selectedRows();
141 if( selected_input.count() == 0)
146 for(
int i=0; i < selected_input.count(); i++)
148 QModelIndex index = selected_input.at(i);
149 QTableWidgetItem* item =
ui->tableWidgetInput->item( index.row(), 0);
150 QString topic_name = item->text();
152 if(
ui->tableWidgetOutput->findItems( topic_name, Qt::MatchExactly ).isEmpty() )
154 int row =
ui->tableWidgetOutput->rowCount();
155 ui->tableWidgetOutput->setRowCount(row+1);
156 ui->tableWidgetOutput->setItem(row, 0,
new QTableWidgetItem(topic_name) );
157 QLineEdit* topic_editor =
new QLineEdit(
ui->tableWidgetOutput);
158 ui->tableWidgetOutput->setCellWidget(row, 1, topic_editor);
162 ui->tableWidgetInput->selectionModel()->clearSelection();
164 ui->pushButtonSave->setEnabled(
ui->tableWidgetOutput->rowCount() );
166 ui->dateTimeOutputBegin->setDateTimeRange(
ui->dateTimeInputBegin->dateTime(),
167 ui->dateTimeInputEnd->dateTime() );
168 ui->dateTimeOutputBegin->setDateTime(
ui->dateTimeInputBegin->dateTime());
170 ui->dateTimeOutputEnd->setDateTimeRange(
ui->dateTimeInputBegin->dateTime(),
171 ui->dateTimeInputEnd->dateTime() );
172 ui->dateTimeOutputEnd->setDateTime(
ui->dateTimeInputEnd->dateTime());
179 QItemSelectionModel *select =
ui->tableWidgetInput->selectionModel();
180 ui->pushButtonMove->setEnabled( select->hasSelection() );
185 QItemSelectionModel *select =
ui->tableWidgetOutput->selectionModel();
186 ui->pushButtonRemove->setEnabled( select->hasSelection() );
191 QModelIndexList indexes;
192 while((indexes =
ui->tableWidgetOutput->selectionModel()->selectedIndexes()).size())
194 ui->tableWidgetOutput->model()->removeRow(indexes.first().row());
197 ui->tableWidgetOutput->sortItems(0);
204 QString
filename = QFileDialog::getSaveFileName(
this,
"Save Rosbag",
206 tr(
"Rosbag Files (*.bag)"));
207 if( filename.isEmpty())
211 if (QFileInfo(filename).suffix() !=
"bag")
213 filename.append(
".bag");
218 QMessageBox::warning(
this,
"Wrong file name",
219 "You can not overwrite the input file. Choose another name or directory.",
225 settings.setValue(
"RosbagEditor/prevSavePath", QFileInfo(filename).absolutePath() );
231 if(
ui->radioNoCompression->isChecked()){
234 else if(
ui->radioLZ4->isChecked()){
237 else if(
ui->radioBZ2->isChecked()){
241 std::vector<std::string> input_topics;
242 std::map<std::string,std::string> topis_renamed;
244 for(
int row = 0; row <
ui->tableWidgetOutput->rowCount(); ++row)
246 std::string name =
ui->tableWidgetOutput->item(row,0)->text().toStdString();
247 QLineEdit* line_edit = qobject_cast<QLineEdit*>(
ui->tableWidgetOutput->cellWidget(row, 1));
248 std::string renamed = line_edit->text().toStdString();
249 input_topics.push_back( name );
252 topis_renamed.insert( std::make_pair(name,name));
255 topis_renamed.insert( std::make_pair(name,renamed));
259 double begin_time = std::floor(-0.001 + 0.001*static_cast<double>(
ui->dateTimeOutputBegin->dateTime().toMSecsSinceEpoch()));
260 double end_time = std::ceil( 0.001 + 0.001*static_cast<double>(
ui->dateTimeOutputEnd->dateTime().toMSecsSinceEpoch()));
266 QProgressDialog progress_dialog;
267 progress_dialog.setLabelText(
"Loading... please wait");
268 progress_dialog.setWindowModality( Qt::ApplicationModal );
269 progress_dialog.show();
272 progress_dialog.setRange(0, bag_view.
size()-1);
274 bool do_tf_filtering =
_filtered_frames.size() > 0 &&
ui->checkBoxFilterTF->isChecked();
278 if( msg_count++ %100 == 0)
280 progress_dialog.setValue( msg_count );
281 QApplication::processEvents();
284 const auto& name = topis_renamed.find(msg.getTopic())->second;
286 auto removeTransform = [&](std::vector<geometry_msgs::TransformStamped>& transforms)
288 for (
int i=0; i < transforms.size(); i++)
290 auto frame = std::make_pair(transforms[i].header.frame_id,
291 transforms[i].child_frame_id);
294 transforms.erase( transforms.begin() + i );
301 if( msg.getTopic() ==
"/tf" && do_tf_filtering )
303 tf::tfMessage::Ptr
tf = msg.instantiate<tf::tfMessage>();
306 removeTransform(tf->transforms);
307 out_bag.
write( name, msg.getTime(), tf, msg.getConnectionHeader());
310 tf2_msgs::TFMessage::Ptr
tf2 = msg.instantiate<tf2_msgs::TFMessage>();
313 removeTransform(tf2->transforms);
314 out_bag.
write( name, msg.getTime(), tf2, msg.getConnectionHeader());
318 out_bag.
write( name, msg.getTime(), msg, msg.getConnectionHeader());
323 int ret = QMessageBox::question(
this,
"Done",
"New robag succesfully created. Do you want to close the application?",
324 QMessageBox::Cancel | QMessageBox::Close, QMessageBox::Close );
325 if( ret == QMessageBox::Close )
333 if(
ui->dateTimeOutputBegin->dateTime() > dateTime )
335 ui->dateTimeOutputBegin->setDateTime( dateTime );
341 if(
ui->dateTimeOutputEnd->dateTime() < dateTime )
343 ui->dateTimeOutputEnd->setDateTime( dateTime );
349 bool contains_tf = !
ui->tableWidgetInput->findItems(
"/tf", Qt::MatchExactly ).empty();
350 ui->pushButtonFilterTF->setEnabled( checked && contains_tf );
void on_tableWidgetInput_itemSelectionChanged()
void on_tableWidgetOutput_itemSelectionChanged()
std::vector< const ConnectionInfo * > getConnections()
void open(std::string const &filename, uint32_t mode=bagmode::Read)
void on_pushButtonLoad_pressed()
QString _previous_load_path
void on_dateTimeOutputEnd_dateTimeChanged(const QDateTime &dateTime)
void on_dateTimeOutputBegin_dateTimeChanged(const QDateTime &dateTime)
void on_pushButtonMove_pressed()
QString _previous_save_path
std::set< std::pair< std::string, std::string > > _filtered_frames
void closeEvent(QCloseEvent *event)
void setCompression(CompressionType compression)
void on_checkBoxFilterTF_toggled(bool checked)
void on_pushButtonFilterTF_pressed()
void changeEnabledWidgets()
void on_pushButtonRemove_pressed()
RosbagEditor(QWidget *parent=nullptr)
void write(std::string const &topic, ros::MessageEvent< T > const &event)
void on_pushButtonSave_pressed()