@@ -29,13 +29,53 @@ namespace rviz_plugins
29
29
MetricsVisualizePanel::MetricsVisualizePanel (QWidget * parent)
30
30
: rviz_common::Panel(parent), grid_(new QGridLayout())
31
31
{
32
- setLayout (grid_);
32
+ // Initialize the main tab widget
33
+ tab_widget_ = new QTabWidget ();
34
+
35
+ // Create and configure the "All Metrics" tab
36
+ QWidget * all_metrics_widget = new QWidget ();
37
+ grid_ = new QGridLayout (all_metrics_widget); // Apply grid layout to the widget directly
38
+ all_metrics_widget->setLayout (grid_);
39
+
40
+ // Add topic selector combobox
33
41
topic_selector_ = new QComboBox ();
34
42
for (const auto & topic : topics_) {
35
43
topic_selector_->addItem (QString::fromStdString (topic));
36
44
}
37
- grid_->addWidget (topic_selector_, 0 , 0 , 1 , -1 );
45
+ grid_->addWidget (topic_selector_, 0 , 0 , 1 , -1 ); // Add topic selector to the grid layout
38
46
connect (topic_selector_, SIGNAL (currentIndexChanged (int )), this , SLOT (onTopicChanged ()));
47
+
48
+ tab_widget_->addTab (
49
+ all_metrics_widget, " All Metrics" ); // Add "All Metrics" tab to the tab widget
50
+
51
+ // Create and configure the "Specific Metrics" tab
52
+ QWidget * specific_metrics_widget = new QWidget ();
53
+ QVBoxLayout * specific_metrics_layout = new QVBoxLayout ();
54
+ specific_metrics_widget->setLayout (specific_metrics_layout);
55
+
56
+ // Add specific metric selector combobox
57
+ specific_metric_selector_ = new QComboBox ();
58
+ specific_metrics_layout->addWidget (specific_metric_selector_);
59
+ connect (
60
+ specific_metric_selector_, SIGNAL (currentIndexChanged (int )), this ,
61
+ SLOT (onSpecificMetricChanged ()));
62
+
63
+ // Add clear button
64
+ QPushButton * clear_button = new QPushButton (" Clear" );
65
+ specific_metrics_layout->addWidget (clear_button);
66
+ connect (clear_button, &QPushButton::clicked, this , &MetricsVisualizePanel::onClearButtonClicked);
67
+
68
+ // Add chart view for specific metrics
69
+ specific_metric_chart_view_ = new QChartView ();
70
+ specific_metrics_layout->addWidget (specific_metric_chart_view_);
71
+
72
+ tab_widget_->addTab (
73
+ specific_metrics_widget, " Specific Metrics" ); // Add "Specific Metrics" tab to the tab widget
74
+
75
+ // Set the main layout of the panel
76
+ QVBoxLayout * main_layout = new QVBoxLayout ();
77
+ main_layout->addWidget (tab_widget_);
78
+ setLayout (main_layout);
39
79
}
40
80
41
81
void MetricsVisualizePanel::onInitialize ()
@@ -91,6 +131,56 @@ void MetricsVisualizePanel::onTopicChanged()
91
131
showCurrentTopicWidgets ();
92
132
}
93
133
134
+ void MetricsVisualizePanel::updateSelectedMetric (const std::string & metric_name)
135
+ {
136
+ std::lock_guard<std::mutex> message_lock (mutex_);
137
+
138
+ for (const auto & [topic, msg] : current_msg_map_) {
139
+ const auto time = msg->header .stamp .sec + msg->header .stamp .nanosec * 1e-9 ;
140
+ for (const auto & status : msg->status ) {
141
+ if (metric_name == status.name ) {
142
+ selected_metrics_ = {metric_name, Metric (status)};
143
+ selected_metrics_->second .updateData (time , status);
144
+ return ;
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ void MetricsVisualizePanel::updateViews ()
151
+ {
152
+ if (!selected_metrics_) {
153
+ return ;
154
+ }
155
+
156
+ Metric & metric = selected_metrics_->second ;
157
+ specific_metric_chart_view_->setChart (metric.getChartView ()->chart ());
158
+ auto * specific_metrics_widget = dynamic_cast <QWidget *>(tab_widget_->widget (1 ));
159
+ auto * specific_metrics_layout = dynamic_cast <QVBoxLayout *>(specific_metrics_widget->layout ());
160
+ specific_metrics_layout->removeWidget (specific_metric_table_);
161
+ specific_metric_table_ = metric.getTable ();
162
+ QSizePolicy sizePolicy (QSizePolicy::Preferred, QSizePolicy::Fixed );
163
+ sizePolicy.setHeightForWidth (specific_metric_table_->sizePolicy ().hasHeightForWidth ());
164
+ specific_metric_table_->setSizePolicy (sizePolicy);
165
+ specific_metrics_layout->insertWidget (1 , specific_metric_table_);
166
+ }
167
+
168
+ void MetricsVisualizePanel::onSpecificMetricChanged ()
169
+ {
170
+ const auto selected_metrics_str = specific_metric_selector_->currentText ().toStdString ();
171
+ updateSelectedMetric (selected_metrics_str);
172
+ updateViews ();
173
+ }
174
+
175
+ void MetricsVisualizePanel::onClearButtonClicked ()
176
+ {
177
+ if (!selected_metrics_) {
178
+ return ;
179
+ }
180
+ updateSelectedMetric (selected_metrics_->first );
181
+ updateViews ();
182
+ }
183
+
94
184
void MetricsVisualizePanel::onTimer ()
95
185
{
96
186
std::lock_guard<std::mutex> message_lock (mutex_);
@@ -99,6 +189,11 @@ void MetricsVisualizePanel::onTimer()
99
189
metric.updateGraph ();
100
190
metric.updateTable ();
101
191
}
192
+
193
+ if (selected_metrics_) {
194
+ selected_metrics_->second .updateGraph ();
195
+ selected_metrics_->second .updateTable ();
196
+ }
102
197
}
103
198
104
199
void MetricsVisualizePanel::onMetrics (
@@ -117,26 +212,48 @@ void MetricsVisualizePanel::onMetrics(
117
212
118
213
// Calculate grid position
119
214
const size_t row = num_current_metrics / GRAPH_COL_SIZE * 2 +
120
- 1 ; // start from 1 to leave space for the topic selector
215
+ 2 ; // start from 2 to leave space for the topic selector and tab widget
121
216
const size_t col = num_current_metrics % GRAPH_COL_SIZE;
122
217
123
218
// Get the widgets from the metric
124
219
const auto tableWidget = metric.getTable ();
125
220
const auto chartViewWidget = metric.getChartView ();
126
221
127
- // Add the widgets to the grid layout
128
- grid_->addWidget (tableWidget, row, col);
129
- grid_->setRowStretch (row, false );
130
- grid_->addWidget (chartViewWidget, row + 1 , col);
131
- grid_->setRowStretch (row + 1 , true );
132
- grid_->setColumnStretch (col, true );
222
+ // Get the layout for the "All Metrics" tab
223
+ auto all_metrics_widget = dynamic_cast <QWidget *>(tab_widget_->widget (0 ));
224
+ QGridLayout * all_metrics_layout = dynamic_cast <QGridLayout *>(all_metrics_widget->layout ());
133
225
134
- // Also add the widgets to the graph_widgets_ vector for easy removal later
226
+ // Add the widgets to the "All Metrics" tab layout
227
+ all_metrics_layout->addWidget (tableWidget, row, col);
228
+ all_metrics_layout->setRowStretch (row, false );
229
+ all_metrics_layout->addWidget (chartViewWidget, row + 1 , col);
230
+ all_metrics_layout->setRowStretch (row + 1 , true );
231
+ all_metrics_layout->setColumnStretch (col, true );
232
+
233
+ // Also add the widgets to the topic_widgets_map_ for easy management
135
234
topic_widgets_map_[topic_name][status.name ] = std::make_pair (tableWidget, chartViewWidget);
136
235
}
137
-
138
236
metrics_.at (status.name ).updateData (time , status);
237
+
238
+ // update selected metrics
239
+ const auto selected_metrics_str = specific_metric_selector_->currentText ().toStdString ();
240
+ if (selected_metrics_str == status.name ) {
241
+ if (selected_metrics_) {
242
+ selected_metrics_->second .updateData (time , status);
243
+ }
244
+ }
139
245
}
246
+
247
+ // Update the specific metric selector
248
+ QSignalBlocker blocker (specific_metric_selector_);
249
+ for (const auto & status : msg->status ) {
250
+ if (specific_metric_selector_->findText (QString::fromStdString (status.name )) == -1 ) {
251
+ specific_metric_selector_->addItem (QString::fromStdString (status.name ));
252
+ }
253
+ }
254
+
255
+ // save the message for metrics selector
256
+ current_msg_map_[topic_name] = msg;
140
257
}
141
258
142
259
} // namespace rviz_plugins
0 commit comments