70 from rqt_bag
import MessageView
72 from python_qt_binding
import loadUi
73 from python_qt_binding.QtCore
import Qt, qWarning, Signal
74 from python_qt_binding.QtGui
import QDoubleValidator, QIcon
75 from python_qt_binding.QtWidgets
import QWidget, QPushButton, QTreeWidget, QTreeWidgetItem, QSizePolicy, QApplication, QAbstractItemView
96 super(PlotView, self).
__init__(timeline, topic)
106 _, msg, t = msg_details[:3]
118 class PlotWidget(QWidget):
121 super(PlotWidget, self).
__init__(parent)
122 self.setObjectName(
'PlotWidget')
125 msg_type = self.
timeline.get_datatype(topic)
134 rp = rospkg.RosPack()
135 ui_file = os.path.join(rp.get_path(
'rqt_bag_plugins'),
'resource',
'plot.ui')
136 loadUi(ui_file, self)
142 self.auto_res.stateChanged.connect(self.
autoChanged)
145 self.resolution.setValidator(QDoubleValidator(0.0, 1000.0, 6, self.resolution))
152 self.
plot.set_autoscale(x=
False)
153 self.
plot.set_autoscale(y=DataPlot.SCALE_VISIBLE)
154 self.
plot.autoscroll(
False)
156 self.data_plot_layout.addWidget(self.
plot)
177 bag, entry = self.
timeline.get_entry(start_time, topic)
179 start_time = self.
timeline.get_entry_after(start_time)[1].time
183 msg = bag._read_message(entry.position)
192 self.
plot.vline(position, color=DataPlot.RED)
203 self.
plot.remove_curve(path)
208 """get a generator for the specified time range on our bag"""
250 for entry
in msgdata:
263 for field
in path.split(
'.'):
265 if field.endswith(
']'):
267 field, _, index = field.rpartition(
'[')
268 y_value = getattr(y_value, field)
271 y_value = y_value[index]
272 y[path].append(y_value)
273 x[path].append((entry[2] - self.
start_stamp).to_sec())
287 qWarning(
"Resampling resulted in 0 data points for %s" % path)
290 self.
plot.clear_values(path)
291 self.
plot.update_values(path, x[path], y[path])
293 self.
plot.add_curve(path, path, x[path], y[path])
305 if self.auto_res.isChecked():
306 timestep = round((limits[1] - limits[0]) / 200.0, 5)
308 timestep = float(self.resolution.text())
309 self.resolution.setText(str(timestep))
319 limits = [0.0, limits[1]]
326 self.
plot.set_xlim(limits)
338 self.resolution.setDisabled(
True)
344 self.resolution.setDisabled(
False)
360 super(MessageTree, self).
__init__(parent)
361 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
362 self.setHeaderHidden(
False)
363 self.setHeaderLabel(
'')
364 self.setSelectionMode(QAbstractItemView.ExtendedSelection)
385 if item.isExpanded():
389 if item.checkState(0) == Qt.Checked:
395 self.setHeaderLabel(msg._type)
408 item.setExpanded(
True)
410 item.setExpanded(
False)
415 return item.data(0, Qt.UserRole)[0].replace(
' ',
'')
420 root = self.invisibleRootItem()
428 for i
in range(root.childCount()):
429 child = root.child(i)
436 if hasattr(obj,
'__slots__'):
437 subobjs = [(slot, getattr(obj, slot))
for slot
in obj.__slots__]
438 elif type(obj)
in [list, tuple]:
443 w = int(math.ceil(math.log10(len_obj)))
444 subobjs = [(
'[%*d]' % (w, i), subobj)
for (i, subobj)
in enumerate(obj)]
449 if type(obj)
in [int, long, float]:
451 if type(obj) == float:
452 obj_repr =
'%.6f' % obj
456 if obj_repr[0] ==
'-':
457 label +=
': %s' % obj_repr
459 label +=
': %s' % obj_repr
461 elif type(obj)
in [str, bool, int, long, float, complex, rospy.Time]:
463 obj_repr = codecs.utf_8_decode(str(obj).encode(),
'ignore')[0]
466 if len(obj_repr) >= 50:
467 obj_repr = obj_repr[:50] +
'...'
469 label +=
': ' + obj_repr
470 item = QTreeWidgetItem([label])
473 elif path.find(
'.') == -1
and path.find(
'[') == -1:
474 self.addTopLevelItem(item)
476 parent.addChild(item)
479 item.setCheckState(0, Qt.Checked)
481 item.setCheckState(0, Qt.Unchecked)
482 item.setData(0, Qt.UserRole, (path, obj_type))
484 for subobj_name, subobj
in subobjs:
489 subpath = subobj_name
490 elif subobj_name.startswith(
'['):
491 subpath =
'%s%s' % (path, subobj_name)
493 subpath =
'%s.%s' % (path, subobj_name)
495 if hasattr(subobj,
'_type'):
496 subobj_type = subobj._type
498 subobj_type = type(subobj).__name__
503 if item.data(0, Qt.UserRole) ==
None:
507 if item.checkState(column) == Qt.Checked:
510 self.parent().parent().parent().add_plot(path)
511 if item.checkState(column) == Qt.Unchecked:
514 self.parent().parent().parent().remove_plot(path)
517 if event.modifiers() & Qt.ControlModifier:
519 if key == ord(
'C')
or key == ord(
'c'):
523 elif key == ord(
'A')
or key == ord(
'a'):
530 def get_distance(item, ancestor, distance=0):
531 parent = item.parent()
535 return get_distance(parent, ancestor, distance + 1)
538 if i
in self.selectedItems():
539 text += (
'\t' * (get_distance(i,
None))) + i.text(0) +
'\n'
541 clipboard = QApplication.clipboard()
542 clipboard.setText(text)