Пример #1
0
 def _draw_bag_ends(self, painter):
     """
     Draw markers to indicate the area the bag file represents within the current visible area.
     :param painter: allows access to paint functions,''QPainter''
     """
     x_start, x_end = self.map_stamp_to_x(
         self._start_stamp.to_sec()), self.map_stamp_to_x(
             self._end_stamp.to_sec())
     painter.setBrush(QBrush(self._bag_end_color))
     painter.drawRect(self._history_left, self._history_top,
                      x_start - self._history_left,
                      self._history_bottom - self._history_top)
     painter.drawRect(x_end, self._history_top,
                      self._history_left + self._history_width - x_end,
                      self._history_bottom - self._history_top)
     painter.setBrush(self._default_brush)
     painter.setPen(self._default_pen)
Пример #2
0
    def __init__(self, track, text, starttime, duration):
        self._track = track
        super(TimelineClip, self).__init__(0.0, 0.0, duration, track.height, None, track.scene())
        self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges)
        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setZValue(self._z)
        self.setBrush(QBrush(self._track._colors['item']))
        self.setPen(QPen(self._track._colors['item']))

        self._text = QGraphicsSimpleTextItem(text, self)
        self._text.setBrush(QColor(Qt.black))
        self._text.setFont(QFont('sans', 12))
        self._text.setPos(0.05, 0.05)
        self._text.setFlag(QGraphicsItem.ItemIgnoresTransformations)

        self.set_starttime(starttime)
        self.set_data([])
Пример #3
0
 def enable_param_items(self):
     """
     Create QStdItem per parameter and addColumn them to myself.
     :rtype: None if _dynreconf_client is not initiated.
     """
     if not self._dynreconfclient_widget:
         return None
     paramnames = self._dynreconfclient_widget.get_treenode_names()
     paramnames_items = []
     brush = QBrush(Qt.lightGray)
     for paramname in paramnames:
         item = ReadonlyItem(paramname)
         item.setBackground(brush)
         paramnames_items.append(item)
     rospy.logdebug('enable_param_items len of paramnames={}'.format(
                                                     len(paramnames_items)))
     self.appendColumn(paramnames_items)
Пример #4
0
 def add_curve(self,
               curve_id,
               curve_name,
               curve_color=QColor(Qt.blue),
               markers_on=False,
               dashed=False):
     curve_id = str(curve_id)
     if curve_id in self._curves:
         return
     curve_object = Qwt.QwtPlotCurve(curve_name)
     curve_object.attach(self)
     curve_object.setPen(curve_color)
     if markers_on:
         curve_object.setSymbol(
             Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, QBrush(curve_color),
                           QPen(Qt.black), QSize(4, 4)))
     self._curves[curve_id] = curve_object
Пример #5
0
    def __init__(self,
                 highlight_level,
                 bounding_box,
                 label,
                 shape,
                 color=None,
                 parent=None,
                 label_pos=None,
                 tooltip=None):
        super(NodeItem, self).__init__(highlight_level, parent)

        self._default_color = self._COLOR_BLACK if color is None else color
        self._brush = QBrush(self._default_color)
        self._label_pen = QPen()
        self._label_pen.setColor(self._default_color)
        self._label_pen.setJoinStyle(Qt.RoundJoin)
        self._ellipse_pen = QPen(self._label_pen)
        self._ellipse_pen.setWidth(1)

        self._incoming_edges = set()
        self._outgoing_edges = set()

        if shape == 'box':
            self._graphics_item = QGraphicsRectItem(bounding_box)
        else:
            self._graphics_item = QGraphicsEllipseItem(bounding_box)
        self.addToGroup(self._graphics_item)

        self._label = QGraphicsSimpleTextItem(label)
        self._label.setFont(GraphItem._LABEL_FONT)
        label_rect = self._label.boundingRect()
        if label_pos is None:
            label_rect.moveCenter(bounding_box.center())
        else:
            label_rect.moveCenter(label_pos)
        self._label.setPos(label_rect.x(), label_rect.y())
        self.addToGroup(self._label)
        if tooltip is not None:
            self.setToolTip(tooltip)

        self.set_node_color()

        self.setAcceptHoverEvents(True)

        self.hovershape = None
Пример #6
0
    def data(self, index, role=Qt.DisplayRole):
        column = index.column()
        row = index.row()

        if 0 <= row < self.rowCount() and 0 <= column < self.columnCount():
            column = EntryModel.columns[index.column()]
            entry = self._entries[row]

            if role == Qt.DisplayRole:
                if column == "time":
                    return entry.time_string()
                elif column == "entry":
                    return entry.content

            if role == Qt.ForegroundRole and column == "entry" and entry.is_error:
                return QBrush(Qt.darkRed)

        return None
Пример #7
0
    def _show_release_teleop_message(self, rtn):
        if rtn:
            QMessageBox.warning(self._widget, 'SUCCESS', "RELEASE!!!!",
                                QMessageBox.Ok | QMessageBox.Ok)
            for k in self.robot_item_list.keys():
                if self.robot_item_list[k] == self.current_captured_robot:
                    k.setBackground(0, QBrush(Qt.NoBrush))
                    k.setBackgroundColor(0, QColor(0, 0, 0, 0))
                    robot_name = k.text(0)
                    k.setText(0, robot_name[:robot_name.find(" (captured)")])
        else:
            QMessageBox.warning(self._widget, 'FAIL', "FAIURE RELEASE!!!!",
                                QMessageBox.Ok | QMessageBox.Ok)

        self._widget.setDisabled(False)
        self._widget.capture_teleop_btn.setEnabled(True)
        self._widget.release_teleop_btn.setEnabled(False)
        self.current_captured_robot = None
Пример #8
0
    def __init__(self, scene, track_name, track_type, track_number, color=None):
        self._y = track_number * self.height
        super(TimelineTrack, self).__init__(self.starttime, self._y, self.length, self.height, None, scene)
        self._name = track_name
        self._type = track_type

        # if no color specified and non is assigned for this track type, assign next default color to this track type
        if color is None and self._type not in self._type_colors:
            color = self._default_colors[len(self._type_colors) % len(self._default_colors)]
            self._type_colors[self._type] = color

        self._colors = {}
        for part, alpha in self._color_alphas.items():
            self._colors[part] = QColor(self._type_colors[self._type])
            self._colors[part].setAlphaF(alpha)

        self.setBrush(QBrush(self._colors['track']))
        self.setPen(QPen(Qt.NoPen))
def getComponentBrush(state):
    b = QBrush(QColor(0, 0, 255))  # unconfigured/preoperational
    if state == 'S':  # stopped
        b = QBrush(QColor(255, 255, 255))
    elif state == 'R':  # running
        b = QBrush(QColor(0, 255, 0))
    elif state == 'E':  # error
        b = QBrush(QColor(255, 0, 0))
    elif state == 'F':  # fatal error
        b = QBrush(QColor(255, 127, 127))
    elif state == 'X':  # exception
        b = QBrush(QColor(0, 255, 255))
    return b
Пример #10
0
 def paintEvent(self, event):
     with self.lock:
         if self.status == 1:
             color = self._SUCCESS_COLOR
         elif self.status == 2:
             color = self._WARN_COLOR
         else:
             color = self._UNKNOWN_COLOR
         rect = event.rect()
         qp = QPainter()
         qp.begin(self)
         radius = min(rect.width(), rect.height()) - 100
         qp.setFont(QFont('Helvetica', 100))
         qp.setPen(QPen(QBrush(color), 50))
         qp.setBrush(color)
         qp.drawEllipse((rect.width() - radius) / 2,
                        (rect.height() - radius) / 2, radius, radius)
         qp.end()
         return
Пример #11
0
    def _show_release_resource_message(self, rtn):
        if rtn:
            QMessageBox.warning(self, 'SUCCESS', "RELEASE!!!!", QMessageBox.Ok | QMessageBox.Ok)
        else:
            QMessageBox.warning(self, 'FAIL', "FAIURE RELEASE!!!!", QMessageBox.Ok | QMessageBox.Ok)

        self._lock.acquire()
        if rtn:
            for k in self.resource_item_list.keys():
                if self.resource_item_list[k] == self.current_captured_resource:
                    k.setBackground(0, QBrush(Qt.NoBrush))
                    k.setBackgroundColor(0, QColor(0, 0, 0, 0))
                    resource_name= k.text(0)
                    k.setText(0, resource_name[:resource_name.find(" (captured)")])
        self.setDisabled(False)
        self.capture_resource_btn.setEnabled(True)
        self.release_resource_btn.setEnabled(False)
        self.current_captured_resource= None
        self._lock.release()
Пример #12
0
    def draw_scan(self, data):
        old_items = []
        if len(self._scan_items):
            for item in self._scan_items:
                old_items.append(item)

        for pt in data:
            scan_item = self._scene.addRect(pt[0],
                                            pt[1],
                                            1,
                                            1,
                                            pen=QPen(QColor(0, 255, 0)),
                                            brush=QBrush(QColor(0, 255, 0)))
            # Everything must be mirrored
            self._mirror(scan_item)
            self._scan_items.append(scan_item)

        if len(old_items):
            for item in old_items:
                self._scene.removeItem(item)
                self._scan_items.remove(item)
Пример #13
0
    def _draw_selected_region(self, painter):
        """
        Draws a box around the selected region
        :param painter: allows access to paint functions,''QPainter''
        """
        if self._selected_left is None:
            return

        x_left = self.map_stamp_to_x(self._selected_left)
        if self._selected_right is not None:
            x_right = self.map_stamp_to_x(self._selected_right)
        else:
            x_right = self.map_stamp_to_x(self.playhead.to_sec())

        left = x_left
        top = self._history_top - self._playhead_pointer_size[
            1] - 5 - self._time_font_size - 4
        width = x_right - x_left
        height = self._history_top - top

        painter.setPen(self._selected_region_color)
        painter.setBrush(QBrush(self._selected_region_color))
        painter.drawRect(left, top, width, height)

        painter.setPen(self._selected_region_outline_ends_color)
        painter.setBrush(Qt.NoBrush)
        painter.drawLine(left, top, left, top + height)
        painter.drawLine(left + width, top, left + width, top + height)

        painter.setPen(self._selected_region_outline_top_color)
        painter.setBrush(Qt.NoBrush)
        painter.drawLine(left, top, left + width, top)

        painter.setPen(self._selected_region_outline_top_color)
        painter.drawLine(left, self._history_top, left, self._history_bottom)
        painter.drawLine(left + width, self._history_top, left + width,
                         self._history_bottom)

        painter.setBrush(self._default_brush)
        painter.setPen(self._default_pen)
Пример #14
0
    def paintEvent(self, event):
        painter = QPainter(self)
        #painter.begin(self)

        # puts the arrow in the middle
        painter.translate(self.width() / 2, self.height() / 2)
        painter.rotate(self.angleRobo + self.angleVel)

        line = QLineF(0, 0, self.width() / 2 - 3, 0)

        headSize = min(self.width() / 20, 4)
        points = QPolygonF()
        points.append(QPointF(self.width() / 2 - headSize * 2, headSize))
        points.append(QPointF(self.width() / 2 - headSize * 2, -headSize))
        points.append(QPointF(self.width() / 2 - 3, 0))

        pen = QPen(self.color, 2)
        painter.setPen(pen)
        brush = QBrush(self.color)
        painter.setBrush(brush)

        painter.drawLine(line)
        painter.drawConvexPolygon(points)
Пример #15
0
    def _draw_playhead(self, painter):
        """
        Draw a line and 2 triangles to denote the current position being viewed
        :param painter: ,''QPainter''
        """
        px = self.map_stamp_to_x(self.playhead.to_sec())
        pw, ph = self._playhead_pointer_size

        # Line
        painter.setPen(QPen(self._playhead_color))
        painter.setBrush(QBrush(self._playhead_color))
        painter.drawLine(px, self._history_top - 1, px, self._history_bottom + 2)

        # Upper triangle
        py = self._history_top - ph
        painter.drawPolygon(QPolygonF([QPointF(px, py + ph), QPointF(px + pw, py), QPointF(px - pw, py)]))

        # Lower triangle
        py = self._history_bottom + 1
        painter.drawPolygon(QPolygonF([QPointF(px, py), QPointF(px + pw, py + ph), QPointF(px - pw, py + ph)]))

        painter.setBrush(self._default_brush)
        painter.setPen(self._default_pen)
Пример #16
0
    def paintEvent(self, event):
        with self.lock:
            self.event = event
            rect = event.rect()
            qp = QPainter()
            qp.begin(self)
            radius = min(rect.width(), rect.height()) - 50
            qp.setFont(QFont('Helvetica', 100))
            qp.setPen(QPen(QBrush(QColor(255, 255, 255)), 20))

            if self.is_disabled:
                qp.fillRect(rect, self._DISABLED_COLOR)
                qp.drawText(rect, QtCore.Qt.AlignCenter, self._FROWN)
            elif self.is_blackout:
                qp.fillRect(rect, self._BLACKOUT_COLOR)
                qp.drawText(rect, QtCore.Qt.AlignCenter, self._FROWN)
                time_diff = (self.next_whiteout_time -
                             rospy.Time.now()).to_sec()
                if time_diff < 0:
                    time_diff = 0
                time_ratio = time_diff / (self.next_whiteout_time -
                                          self.blackout_time).to_sec()
                qp.setFont(QFont('Helvetica', 30))
                qp.drawText(0,
                            rect.height() - 150, rect.width(), 150,
                            QtCore.Qt.AlignCenter, "%.1f sec" % time_diff)
                # 0-360
                if time_ratio > 0:
                    rad = int(math.fmod(time_ratio * 360 + 90 * 16, 360) * 16)
                    qp.drawArc((rect.width() - radius) / 2,
                               (rect.height() - radius) / 2, radius, radius,
                               90 * 16, rad)
            else:
                qp.fillRect(rect, self._OK_COLOR)
                qp.drawText(rect, QtCore.Qt.AlignCenter, self._SMILEY)
            qp.end()
Пример #17
0
    def do_take_sample(self):
        try:
            px_x = int(self._widget.spinbox_pixel_location_x.value())
            px_y = int(self._widget.spinbox_pixel_location_y.value())

            b = self.cv_image.item(px_y, px_x, 0)
            g = self.cv_image.item(px_y, px_x, 1)
            r = self.cv_image.item(px_y, px_x, 2)

            px_bgr = np.zeros((1, 1, 3), np.uint8)
            px_bgr[:] = tuple((b, g, r))
            px_hsv = cv2.cvtColor(px_bgr, cv2.COLOR_BGR2HSV)

            h = px_hsv.item(0, 0, 0)
            s = px_hsv.item(0, 0, 1)
            v = px_hsv.item(0, 0, 2)

            self._widget.line_edit_pixel_b.setText(str(b))
            self._widget.line_edit_pixel_g.setText(str(g))
            self._widget.line_edit_pixel_r.setText(str(r))

            self._widget.line_edit_pixel_h.setText(str(h))
            self._widget.line_edit_pixel_s.setText(str(s))
            self._widget.line_edit_pixel_v.setText(str(v))

            self.colour_pane_scene.setForegroundBrush(QBrush(QColor(r, g, b)))
            self._widget.graphics_view_colour_pane.show()

            if not self.args.quiet:
                rospy.loginfo("----------------")
                rospy.loginfo("XY:  [%d, %d]" % (px_x, px_y))
                rospy.loginfo("RGB: [%d, %d, %d]" % (r, g, b))
                rospy.loginfo("HSV: [%d, %d, %d]" % (h, s, v))

        except Exception as e:
            rospy.loginfo(e)
Пример #18
0
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.setWindowTitle('U-CTF View')

        self._scene = QGraphicsScene()
        self._scene.setBackgroundBrush(Qt.white)

        # game cube grass area
        grass_color = QColor(0, 255, 0, 50)
        self._scene.addRect(
            0, 0, CUBE_LENGTH, CUBE_LENGTH,
            QPen(grass_color), QBrush(grass_color))
        # blue team area
        blue_color = QColor(0, 0, 255, 50)
        self._scene.addRect(
            0, -SUPPORT_AREA_DEPTH, CUBE_LENGTH, SUPPORT_AREA_DEPTH,
            QPen(blue_color), QBrush(blue_color))
        # gold team area
        gold_color = QColor(255, 215, 0, 50)
        self._scene.addRect(
            0, CUBE_LENGTH, CUBE_LENGTH, SUPPORT_AREA_DEPTH,
            QPen(gold_color), QBrush(gold_color))
        # penalty area
        orange_color = QColor(0, 200, 0, 50)
        self._scene.addRect(
            CUBE_LENGTH, 0, SUPPORT_AREA_DEPTH, CUBE_LENGTH,
            QPen(orange_color), QBrush(orange_color))

        # rotate view to match the coordinate system of the game cube
        self.rotate(180)
        self.setScene(self._scene)

        # pens and brushes for the vehicles
        self._pens = {
            'blue': QPen(Qt.blue, 2),
            'gold': QPen(QColor(191, 151, 0), 2),
        }
        self._brushes = {
            'blue': QBrush(Qt.blue),
            'gold': QBrush(QColor(191, 151, 0)),
        }

        self._vehicles = {}
 def data(self, index, role=None):
     """
     Sets colors of items based on highlight filters and severity type
     """
     messagelist = self.sourceModel()._messages.get_message_list()
     index = self.mapToSource(index)
     if index.row() >= 0 or index.row() < len(messagelist):
         if index.column() >= 0 or index.column() < messagelist[index.row()].count():
             if role == Qt.ForegroundRole:
                 if index.column() == 1:
                     data = index.data()
                     severity_levels = {'Debug':QBrush(Qt.cyan), \
                                        'Info':QBrush(Qt.darkCyan), \
                                        'Warn':QBrush(Qt.darkYellow), \
                                        'Error':QBrush(Qt.darkRed), \
                                        'Fatal':QBrush(Qt.red)}
                     if data in severity_levels.keys():
                         return severity_levels[data]
                     else:
                         raise KeyError('Unknown severity type: %s'% data)
                 if self._highlight_filters.count_enabled_filters() > 0:
                     if not self._highlight_filters.test_message(messagelist[index.row()]):
                         return QBrush(Qt.gray)
     return self.sourceModel().data(index, role)
Пример #20
0
    def draw_timeline_segment(self, painter, topic, stamp_start, stamp_end, x, y, width, height):
        """
        draws a stream of images for the topic
        :param painter: painter object, ''QPainter''
        :param topic: topic to draw, ''str''
        :param stamp_start: stamp to start drawing, ''rospy.Time''
        :param stamp_end: stamp to end drawing, ''rospy.Time''
        :param x: x to draw images at, ''int''
        :param y: y to draw images at, ''int''
        :param width: width in pixels of the timeline area, ''int''
        :param height: height in pixels of the timeline area, ''int''
        """
        if x < self.timeline._history_left:
            width += x - self.timeline._history_left
            x = self.timeline._history_left
        max_interval_thumbnail = self.timeline.map_dx_to_dstamp(self.thumbnail_combine_px)
        max_interval_thumbnail = max(0.1, max_interval_thumbnail)
        thumbnail_gap = 6
        thumbnail_x, thumbnail_y, thumbnail_height = x + 1, y + 1, height - 2 - thumbnail_gap  # leave 1px border

        # set color to white draw rectangle over messages
        painter.setBrush(QBrush(Qt.white))
        painter.drawRect(x, y, width, height - thumbnail_gap)
        thumbnail_width = None

        while True:
            available_width = (x + width) - thumbnail_x

            # Check for enough remaining to draw thumbnail
            if width > 1 and available_width < self.min_thumbnail_width:
                break

            # Try to display the thumbnail, if its right edge is to the right of the timeline's left side
            if not thumbnail_width or thumbnail_x + thumbnail_width >= self.timeline._history_left:
                stamp = self.timeline.map_x_to_stamp(thumbnail_x, clamp_to_visible=False)
                thumbnail_bitmap = self.thumbnail_cache.get_item(topic, stamp, max_interval_thumbnail)

                # Cache miss
                if not thumbnail_bitmap:
                    thumbnail_details = (thumbnail_height,)
                    self.thumbnail_cache.enqueue((topic, stamp, max_interval_thumbnail, thumbnail_details))
                    if not thumbnail_width:
                        break
                else:
                    thumbnail_width, _ = thumbnail_bitmap.size

                    if width > 1:
                        if available_width < thumbnail_width:
                            thumbnail_width = available_width - 1
                    QtImage = ImageQt(thumbnail_bitmap)
                    pixmap = QPixmap.fromImage(QtImage)
                    painter.drawPixmap(thumbnail_x, thumbnail_y, thumbnail_width, thumbnail_height, pixmap)
            thumbnail_x += thumbnail_width

            if width == 1:
                break

        painter.setPen(QPen(Qt.black))
        painter.setBrush(QBrush(Qt.transparent))
        if width == 1:
            painter.drawRect(x, y, thumbnail_x - x, height - thumbnail_gap - 1)
        else:
            painter.drawRect(x, y, width, height - thumbnail_gap - 1)
        return True
Пример #21
0
    def __init__(self,
                 spline,
                 label,
                 label_center,
                 from_node,
                 to_node,
                 parent=None,
                 **kwargs):
        super(EdgeItem, self).__init__(parent, **kwargs)

        self._edge_pen_width = kwargs.get('edge_pen_width',
                                          self.EDGE_PEN_WIDTH)

        self.from_node = from_node
        self.from_node.add_outgoing_edge(self)

        self.to_node = to_node
        self.to_node.add_incoming_edge(self)

        self._brush = QBrush(self._color)

        self._label_pen = QPen()
        self._label_pen.setColor(self._color)
        self._label_pen.setJoinStyle(Qt.RoundJoin)
        self._label_pen.setWidthF(self._label_pen_width)

        self._edge_pen = QPen()
        self._edge_pen.setColor(self._color)
        self._edge_pen.setWidthF(self._edge_pen_width)

        self._sibling_edges = set()

        self._label = None
        if label is not None:
            self._label = QGraphicsSimpleTextItem(label)

            font = self._label.font()
            font.setPointSize(8)
            self._label.setFont(font)

            label_rect = self._label.boundingRect()
            label_rect.moveCenter(label_center)
            self._label.setPos(label_rect.x(), label_rect.y())

        # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType
        coordinates = spline.split(' ')
        # extract optional end_point
        end_point = None
        if coordinates[0].startswith('e,'):
            parts = coordinates.pop(0)[2:].split(',')
            end_point = QPointF(float(parts[0]), -float(parts[1]))
        # extract optional start_point
        if coordinates[0].startswith('s,'):
            parts = coordinates.pop(0).split(',')

        # first point
        parts = coordinates.pop(0).split(',')
        point = QPointF(float(parts[0]), -float(parts[1]))
        path = QPainterPath(point)

        while len(coordinates) > 2:
            # extract triple of points for a cubic spline
            parts = coordinates.pop(0).split(',')
            point1 = QPointF(float(parts[0]), -float(parts[1]))
            parts = coordinates.pop(0).split(',')
            point2 = QPointF(float(parts[0]), -float(parts[1]))
            parts = coordinates.pop(0).split(',')
            point3 = QPointF(float(parts[0]), -float(parts[1]))
            path.cubicTo(point1, point2, point3)

        self._arrow = None
        if end_point is not None:
            # draw arrow
            self._arrow = QGraphicsPolygonItem()
            polygon = QPolygonF()
            polygon.append(point3)
            offset = QPointF(end_point - point3)
            corner1 = QPointF(-offset.y(), offset.x()) * 0.35
            corner2 = QPointF(offset.y(), -offset.x()) * 0.35
            polygon.append(point3 + corner1)
            polygon.append(end_point)
            polygon.append(point3 + corner2)
            self._arrow.setPolygon(polygon)

        self._path = QGraphicsPathItem()
        self._path.setPath(path)
        self.addToGroup(self._path)

        self._brush.setColor(self._color)
        self._edge_pen.setColor(self._color)
        self._label_pen.setColor(self._color)

        self._path.setPen(self._edge_pen)
        if self._arrow is not None:
            self._arrow.setBrush(self._brush)
            self._arrow.setPen(self._edge_pen)
        if self._label is not None:
            self._label.setBrush(self._brush)
            self._label.setPen(self._label_pen)
Пример #22
0
    def config_timeline_frame(_self):
        self = _self._timeline._timeline_frame

        # Background Rendering
        self._bag_end_color = QColor(
            76, 76, 76
        )  # QColor(0, 0, 0, 25)  # color of background of timeline before first message and after last
        self._history_background_color_alternate = QColor(179, 179, 179, 90)
        self._history_background_color = QColor(204, 204, 204, 102)

        # Timeline Division Rendering
        # Possible time intervals used between divisions
        # 1ms, 5ms, 10ms, 50ms, 100ms, 500ms
        # 1s, 5s, 15s, 30s
        # 1m, 2m, 5m, 10m, 15m, 30m
        # 1h, 2h, 3h, 6h, 12h
        # 1d, 7d
        self._sec_divisions = [
            0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 15, 30, 1 * 60, 2 * 60,
            5 * 60, 10 * 60, 15 * 60, 30 * 60, 1 * 60 * 60, 2 * 60 * 60,
            3 * 60 * 60, 6 * 60 * 60, 12 * 60 * 60, 1 * 60 * 60 * 24,
            7 * 60 * 60 * 24
        ]
        self._minor_spacing = 15
        self._major_spacing = 50
        self._major_divisions_label_indent = 3  # padding in px between line and label
        self._major_division_pen = QPen(QBrush(QColor(76, 76, 76)), 0,
                                        Qt.DashLine)
        self._minor_division_pen = QPen(QBrush(QColor(76, 76, 76, 75)), 0,
                                        Qt.DashLine)
        self._minor_division_tick_pen = QPen(
            QBrush(QColor(128, 128, 128, 128)), 0)

        # Topic Rendering
        self.topics = []
        self._topics_by_datatype = {}
        self._topic_font_height = None
        self._topic_name_sizes = None
        self._topic_name_spacing = 30  # minimum pixels between end of topic name and start of history
        self._topic_font_size = 11
        self._topic_font = QFont("courier new")
        self._topic_font.setPointSize(self._topic_font_size)
        self._topic_font.setBold(False)
        self._topic_vertical_padding = 10
        self._topic_name_max_percent = 25.0  # percentage of the horiz space that can be used for topic display

        # Time Rendering
        self._time_tick_height = 5
        self._time_font_height = None
        self._time_font_size = 10.0
        self._time_font = QFont("courier new")
        self._time_font.setPointSize(self._time_font_size)
        self._time_font.setBold(False)

        # Defaults
        self._default_brush = QBrush(Qt.black, Qt.SolidPattern)
        self._default_pen = QPen(QColor(240, 240, 240))
        self._default_datatype_color = QColor(255, 180, 125,
                                              75)  # QColor(0, 0, 102, 204)
        self._datatype_colors = {
            'sensor_msgs/CameraInfo': QColor(0, 0, 77, 204),
            'sensor_msgs/Image': QColor(0, 77, 77, 204),
            'sensor_msgs/LaserScan': QColor(153, 0, 0, 204),
            'pr2_msgs/LaserScannerSignal': QColor(153, 0, 0, 204),
            'pr2_mechanism_msgs/MechanismState': QColor(0, 153, 0, 204),
            'tf/tfMessage': QColor(0, 153, 0, 204),
        }
        self._default_msg_combine_px = 1.0  # minimum number of pixels allowed between two bag messages before they are combined
        self._active_message_line_width = 3

        # Selected Region Rendering
        self._selected_region_color = QColor(0, 179, 0, 42)
        self._selected_region_outline_top_color = QColor(0.0, 77, 0.0, 102)
        self._selected_region_outline_ends_color = QColor(0.0, 77, 0.0, 204)
        self._selected_left = None
        self._selected_right = None
        self._selection_handle_width = 3.0

        # Playhead Rendering
        self._playhead = None  # timestamp of the playhead
        self._paused = False
        self._playhead_pointer_size = (6, 6)
        self._playhead_line_width = 1
        self._playhead_color = QColor(255, 255, 255, 191)

        # Zoom
        self._zoom_sensitivity = 0.005
        self._min_zoom_speed = 0.5
        self._max_zoom_speed = 2.0
        self._min_zoom = 0.0001  # max zoom out (in px/s)
        self._max_zoom = 50000.0  # max zoom in  (in px/s)

        # Timeline boundries
        self._start_stamp = None  # earliest of all stamps
        self._end_stamp = None  # latest of all stamps
        self._stamp_left = None  # earliest currently visible timestamp on the timeline
        self._stamp_right = None  # latest currently visible timestamp on the timeline
        self._history_top = 30
        self._history_left = 0
        self._history_width = 0
        self._history_bottom = 0
        self._history_bounds = {}
        self._margin_left = 30
        self._margin_right = 20
        self._margin_bottom = 20
Пример #23
0
    def __init__(self,
                 highlight_level,
                 spline,
                 label_center,
                 label,
                 from_node,
                 to_node,
                 parent=None,
                 penwidth=1,
                 edge_color=None,
                 style='solid'):
        super(EdgeItem, self).__init__(highlight_level, parent)

        self.from_node = from_node
        self.from_node.add_outgoing_edge(self)
        self.to_node = to_node
        self.to_node.add_incoming_edge(self)

        self._default_edge_color = self._COLOR_BLACK
        if edge_color is not None:
            self._default_edge_color = edge_color

        self._default_text_color = self._COLOR_BLACK
        self._default_color = self._COLOR_BLACK
        self._text_brush = QBrush(self._default_color)
        self._shape_brush = QBrush(self._default_color)
        if style in ['dashed', 'dotted']:
            self._shape_brush = QBrush(Qt.transparent)
        self._label_pen = QPen()
        self._label_pen.setColor(self._default_text_color)
        self._label_pen.setJoinStyle(Qt.RoundJoin)
        self._edge_pen = QPen(self._label_pen)
        self._edge_pen.setWidth(penwidth)
        self._edge_pen.setColor(self._default_edge_color)
        self._edge_pen.setStyle(self._qt_pen_styles.get(style, Qt.SolidLine))

        self._sibling_edges = set()

        self._label = None
        if label is not None:
            self._label = QGraphicsSimpleTextItem(label)
            label_rect = self._label.boundingRect()
            label_rect.moveCenter(label_center)
            self._label.setPos(label_rect.x(), label_rect.y())
            self._label.hoverEnterEvent = self._handle_hoverEnterEvent
            self._label.hoverLeaveEvent = self._handle_hoverLeaveEvent
            self._label.setAcceptHoverEvents(True)

        # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType
        coordinates = spline.split(' ')
        # extract optional end_point
        end_point = None
        if (coordinates[0].startswith('e,')):
            parts = coordinates.pop(0)[2:].split(',')
            end_point = QPointF(float(parts[0]), -float(parts[1]))
        # extract optional start_point
        if (coordinates[0].startswith('s,')):
            parts = coordinates.pop(0).split(',')

        # first point
        parts = coordinates.pop(0).split(',')
        point = QPointF(float(parts[0]), -float(parts[1]))
        path = QPainterPath(point)

        while len(coordinates) > 2:
            # extract triple of points for a cubic spline
            parts = coordinates.pop(0).split(',')
            point1 = QPointF(float(parts[0]), -float(parts[1]))
            parts = coordinates.pop(0).split(',')
            point2 = QPointF(float(parts[0]), -float(parts[1]))
            parts = coordinates.pop(0).split(',')
            point3 = QPointF(float(parts[0]), -float(parts[1]))
            path.cubicTo(point1, point2, point3)

        self._arrow = None
        if end_point is not None:
            # draw arrow
            self._arrow = QGraphicsPolygonItem()
            polygon = QPolygonF()
            polygon.append(point3)
            offset = QPointF(end_point - point3)
            corner1 = QPointF(-offset.y(), offset.x()) * 0.35
            corner2 = QPointF(offset.y(), -offset.x()) * 0.35
            polygon.append(point3 + corner1)
            polygon.append(end_point)
            polygon.append(point3 + corner2)
            self._arrow.setPolygon(polygon)
            self._arrow.hoverEnterEvent = self._handle_hoverEnterEvent
            self._arrow.hoverLeaveEvent = self._handle_hoverLeaveEvent
            self._arrow.setAcceptHoverEvents(True)

        self._path = QGraphicsPathItem()
        self._path.setPath(path)
        self.addToGroup(self._path)

        self.set_node_color()
        self.set_label_color()
Пример #24
0
    def paint(self, ctx):
        assert isinstance(ctx, QPainter)

        base_eye_pos = (self.width / 4.0, self.height / 12.0)

        mx_factor = self.width / 150.0 * 7
        my_factor = self.height / 150.0 * 7
        mx = (self.look_x + 1.0) / 2.0 * mx_factor - 1
        my = (self.look_y + 1.0) / 2.0 * my_factor - 1

        fdx = (self.look_x + 1.0) / 2.0 * 6
        fdy = (self.look_y + 1.0) / 2.0 * 14

        sx = 2
        sy = 2

        # face
        if self.draw_contour:
            ctx.setBrush(self.face_color)
            ctx.setPen(NOPEN)
            ctx.drawEllipse(sx + 4, sy, self.width - 8, self.height)
            ctx.drawEllipse(sx + 4, sy, self.width - 8,
                            int(self.height * 0.66))
        else:
            ctx.fillRect(0, 0, self.width, self.height, self.face_color)

        left_eye_center = fdx + sx + self.width / 2.0, fdy + sy + self.height / 3.0
        right_eye_center = fdx + sx + self.width / 2.0, fdy + sy + self.height / 3.0
        eye_height = int(base_eye_pos[1] * (1.0 + self._emotion[0]) + 2)
        pupil_radius = int(base_eye_pos[0] / 4.0)
        eye_brow_space = int(base_eye_pos[1] * (1.0 + self._emotion[1] / 2.0) +
                             1)
        eye_brow_outer = int(-self._emotion[2] * base_eye_pos[1] / 2.0)
        eye_brow_inner = int(-self._emotion[3] * base_eye_pos[1] / 2.0)
        eye_brow_boldness = 2

        # left eye
        left_eye_offset_x = -int(base_eye_pos[0] * 1.4)
        ctx.setBrush(QBrush(WHITE))
        ctx.setPen(NOPEN)
        ctx.drawChord(left_eye_center[0] + left_eye_offset_x,
                      left_eye_center[1] - eye_height / 2.0, base_eye_pos[0],
                      eye_height, 0, 360 * 16)

        ctx.setBrush(QBrush(LIGHTBLUE))
        ctx.setPen(NOPEN)
        ctx.drawChord(
            left_eye_center[0] + left_eye_offset_x + mx +
            base_eye_pos[0] * 0.5 - pupil_radius / 2.0,
            left_eye_center[1] + my - pupil_radius / 2.0, pupil_radius,
            pupil_radius, 0, 360 * 16)

        ctx.setBrush(QBrush(BLACK))
        ctx.setPen(NOPEN)
        ctx.drawChord(
            left_eye_center[0] + left_eye_offset_x + mx +
            base_eye_pos[0] * 0.5 - pupil_radius / 5.0,
            left_eye_center[1] + my - pupil_radius / 5.0, pupil_radius / 2.5,
            pupil_radius / 2.5, 0, 360 * 16)

        ctx.fillRect(
            left_eye_center[0] + left_eye_offset_x,
            left_eye_center[1] - eye_height / 2.0 - base_eye_pos[0] / 2.0,
            base_eye_pos[0], base_eye_pos[0] / 2.0, self.face_color)
        ctx.fillRect(left_eye_center[0] + left_eye_offset_x,
                     left_eye_center[1] + eye_height / 2.0, base_eye_pos[0],
                     base_eye_pos[0] / 2.0, self.face_color)

        # left eye brow
        ctx.setPen(BLACK)
        for b in range(eye_brow_boldness):
            ctx.drawLine(
                left_eye_center[0] + left_eye_offset_x,
                left_eye_center[1] - eye_brow_space + eye_brow_outer + b,
                left_eye_center[0] + left_eye_offset_x + base_eye_pos[0],
                left_eye_center[1] - eye_brow_space + eye_brow_inner + b)

        # right eye
        right_eye_offset_x = int(base_eye_pos[0] * 0.4)
        ctx.setBrush(QBrush(WHITE))
        ctx.setPen(NOPEN)
        ctx.drawChord(right_eye_center[0] + right_eye_offset_x,
                      right_eye_center[1] - eye_height / 2.0, base_eye_pos[0],
                      eye_height, 0, 360 * 16)

        ctx.setBrush(QBrush(LIGHTBLUE))
        ctx.setPen(NOPEN)
        ctx.drawChord(
            right_eye_center[0] + right_eye_offset_x + mx +
            base_eye_pos[0] * 0.5 - pupil_radius / 2.0,
            right_eye_center[1] + my - pupil_radius / 2.0, pupil_radius,
            pupil_radius, 0, 360 * 16)

        ctx.setBrush(QBrush(BLACK))
        ctx.setPen(NOPEN)
        ctx.drawChord(
            mx + right_eye_center[0] + right_eye_offset_x +
            base_eye_pos[0] * 0.5 - pupil_radius / 5.0,
            my + right_eye_center[1] - pupil_radius / 5.0, pupil_radius / 2.5,
            pupil_radius / 2.5, 0, 360 * 16)

        ctx.fillRect(
            right_eye_center[0] + right_eye_offset_x,
            right_eye_center[1] - eye_height / 2.0 - base_eye_pos[0] / 2.0,
            base_eye_pos[0], base_eye_pos[0] / 2.0, self.face_color)
        ctx.fillRect(right_eye_center[0] + right_eye_offset_x,
                     right_eye_center[1] + eye_height / 2.0, base_eye_pos[0],
                     base_eye_pos[0] / 2.0, self.face_color)

        # right eye brow
        ctx.setPen(BLACK)
        for b in range(eye_brow_boldness):
            ctx.drawLine(
                right_eye_center[0] + right_eye_offset_x,
                right_eye_center[1] - eye_brow_space + eye_brow_inner + b,
                right_eye_center[0] + right_eye_offset_x + base_eye_pos[0],
                right_eye_center[1] - eye_brow_space + eye_brow_outer + b)

        # mouth
        base_mouth_pos = (self.width / 2.0, self.height / 6.0)
        smx = fdx + sx + self.width / 2.0
        smy = fdy + sy + 2.0 * self.height / 3.0
        mw = int(base_mouth_pos[0] * (self._emotion[4] + 4) / 6.0)
        mo = int(base_mouth_pos[1] * (self._emotion[5] + 1) / 3.0)
        mt = int(base_mouth_pos[1] * (self._emotion[6] + 0) / 2.0)
        tv = int(base_mouth_pos[1] * (self._emotion[7] - 1) / 3.0)

        upper_lip = mt - mo
        lower_lip = mt + mo
        shift = -mt

        if upper_lip > 0:
            if lower_lip > 0:
                ctx.setBrush(QBrush(WHITE))
                ctx.setPen(NOPEN)
                ctx.drawChord(smx - mw / 2, shift + smy - lower_lip, mw,
                              lower_lip * 2, -180 * 16, 180 * 16)
            else:
                ctx.setBrush(QBrush(self.face_color))
                ctx.setPen(NOPEN)
                ctx.drawChord(smx - mw / 2, shift + smy + lower_lip, mw,
                              -lower_lip * 2, 0, 180 * 16)
            ctx.setBrush(QBrush(self.face_color))
            ctx.setPen(NOPEN)
            ctx.drawChord(smx - mw / 2, shift + smy - upper_lip, mw,
                          upper_lip * 2, -180 * 16, 180 * 16)
        else:
            ctx.setBrush(QBrush(WHITE))
            ctx.setPen(NOPEN)
            ctx.drawChord(smx - mw / 2, shift + smy + upper_lip, mw,
                          -upper_lip * 2, 0, 180 * 16)
            if lower_lip > 0:
                ctx.setBrush(QBrush(WHITE))
                ctx.setPen(NOPEN)
                ctx.drawChord(smx - mw / 2, shift + smy - lower_lip, mw,
                              lower_lip * 2, -180 * 16, 180 * 16)
            else:
                ctx.setBrush(QBrush(self.face_color))
                ctx.setPen(NOPEN)
                ctx.drawChord(smx - mw / 2, shift + smy + lower_lip, mw,
                              -lower_lip * 2, 0, 180 * 16)

        ctx.fillRect(smx - mw / 2.0, smy + tv, mw, -tv * 2, self.face_color)

        # teeth
        ctx.setPen(self.face_color)
        for i in range(6):
            ctx.drawLine(smx - base_mouth_pos[0] * (0.5 - i * 0.2),
                         smy - abs(mt) - mo,
                         smx - base_mouth_pos[0] * (0.5 - i * 0.2),
                         smy + abs(mt) + mo)
        ctx.drawLine(smx - base_mouth_pos[0] / 2.0, smy,
                     smx + base_mouth_pos[0] / 2.0, smy)

        # lips
        ctx.setBrush(NOBRUSH)
        ctx.setPen(LIGHTRED)
        if upper_lip > 0:
            ctx.drawArc(smx - mw / 2, shift + smy - upper_lip, mw,
                        upper_lip * 2, -180 * 16, 180 * 16)
        else:
            ctx.drawArc(smx - mw / 2, shift + smy + upper_lip, mw,
                        -upper_lip * 2, 0, 180 * 16)
        if lower_lip > 0:
            ctx.drawArc(smx - mw / 2, shift + smy - lower_lip, mw,
                        lower_lip * 2, -180 * 16, 180 * 16)
        else:
            ctx.drawArc(smx - mw / 2, shift + smy + lower_lip, mw,
                        -lower_lip * 2, 0, 180 * 16)
Пример #25
0
class MessageDataModel(QAbstractTableModel):

    # the column names must match the message attributes
    columns = ['message', 'severity', 'node', 'stamp', 'location']

    severity_colors = {
        Message.DEBUG: QBrush(Qt.darkCyan),
        Message.INFO: QBrush(Qt.darkBlue),
        Message.WARN: QBrush(Qt.darkYellow),
        Message.ERROR: QBrush(Qt.darkRed),
        Message.FATAL: QBrush(Qt.red),
    }

    def __init__(self):
        super(MessageDataModel, self).__init__()
        self._messages = MessageList()
        self._message_limit = 20000
        self._info_icon = QIcon.fromTheme('dialog-information')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._error_icon = QIcon.fromTheme('dialog-error')

    # BEGIN Required implementations of QAbstractTableModel functions

    def rowCount(self, parent=None):
        return len(self._messages)

    def columnCount(self, parent=None):
        return len(MessageDataModel.columns) + 1

    def data(self, index, role=None):
        if role is None:
            role = Qt.DisplayRole
        if index.row() >= 0 and index.row() < len(self._messages):
            msg = self._messages[index.row()]
            if index.column() == 0:
                if role == Qt.DisplayRole:
                    return '#%d' % msg.id
            elif index.column() > 0 and index.column() < len(MessageDataModel.columns) + 1:
                column = MessageDataModel.columns[index.column() - 1]
                if role == Qt.DisplayRole or role == Qt.UserRole:
                    if column == 'stamp':
                        if role != Qt.UserRole:
                            data = msg.get_stamp_string()
                        else:
                            data = msg.get_stamp_for_compare()
                    else:
                        data = getattr(msg, column)
                    # map severity enum to label
                    if role == Qt.DisplayRole and column == 'severity':
                        data = Message.SEVERITY_LABELS[data]
                    # implode topic names
                    if column == 'topics':
                        data = ', '.join(data)
                    # append row number to define strict order
                    if role == Qt.UserRole:
                        # append row number to define strict order
                        # shortest string representation to compare stamps
                        # print(column, data, str(index.row()).zfill(len(str(len(self._messages)))))
                        data = str(data) + ' %08x' % index.row()
                    return data

                # decorate message column with severity icon
                if role == Qt.DecorationRole and column == 'message':
                    if msg.severity in [Message.DEBUG, Message.INFO]:
                        return self._info_icon
                    elif msg.severity in [Message.WARN]:
                        return self._warning_icon
                    elif msg.severity in [Message.ERROR, Message.FATAL]:
                        return self._error_icon

                # colorize severity label
                if role == Qt.ForegroundRole and column == 'severity':
                    assert msg.severity in MessageDataModel.severity_colors, \
                        'Unknown severity type: %s' % msg.severity
                    return MessageDataModel.severity_colors[msg.severity]

                if role == Qt.ToolTipRole and column != 'severity':
                    if column == 'stamp':
                        data = msg.get_stamp_string()
                    elif column == 'topics':
                        data = ', '.join(msg.topics)
                    else:
                        data = getattr(msg, column)
                    # <font> tag enables word wrap by forcing rich text
                    return '<font>' + data + '<br/><br/>' + \
                        self.tr('Right click for menu.') + '</font>'

    def headerData(self, section, orientation, role=None):
        if role is None:
            role = Qt.DisplayRole
        if orientation == Qt.Horizontal:
            if role == Qt.DisplayRole:
                if section == 0:
                    return self.tr('#')
                else:
                    return MessageDataModel.columns[section - 1].capitalize()
            if role == Qt.ToolTipRole:
                if section == 0:
                    return self.tr('Sort the rows by serial number in descendig order')
                else:
                    return self.tr(
                        'Sorting the table by a column other then the serial number slows down the '
                        'interaction especially when recording high frequency data')

    # END Required implementations of QAbstractTableModel functions

    def get_message_limit(self):
        return self._message_limit

    def set_message_limit(self, new_limit):
        self._message_limit = new_limit
        self._enforce_message_limit(self._message_limit)

    def _enforce_message_limit(self, limit):
        if len(self._messages) > limit:
            self.beginRemoveRows(QModelIndex(), limit, len(self._messages) - 1)
            del self._messages[limit:len(self._messages)]
            self.endRemoveRows()

    def insert_rows(self, msgs):
        # never try to insert more message than the limit
        if len(msgs) > self._message_limit:
            msgs = msgs[-self._message_limit:]
        # reduce model before insert
        limit = self._message_limit - len(msgs)
        self._enforce_message_limit(limit)
        # insert newest messages
        self.beginInsertRows(QModelIndex(), 0, len(msgs) - 1)
        self._messages.extend(msgs)
        self.endInsertRows()

    def remove_rows(self, rowlist):
        """
        :param rowlist: list of row indexes, ''list(int)''
        :returns: True if the indexes were removed successfully, ''bool''
        """
        if len(rowlist) == 0:
            if len(self._messages) > 0:
                try:
                    self.beginRemoveRows(QModelIndex(), 0, len(self._messages))
                    del self._messages[0:len(self._messages)]
                    self.endRemoveRows()
                except:
                    return False
        else:
            rowlist = list(set(rowlist))
            rowlist.sort(reverse=True)
            dellist = [rowlist[0]]
            for row in rowlist[1:]:
                if dellist[-1] - 1 > row:
                    try:
                        self.beginRemoveRows(QModelIndex(), dellist[-1], dellist[0])
                        del self._messages[dellist[-1]:dellist[0] + 1]
                        self.endRemoveRows()
                    except:
                        return False
                    dellist = []
                dellist.append(row)
            if len(dellist) > 0:
                try:
                    self.beginRemoveRows(QModelIndex(), dellist[-1], dellist[0])
                    del self._messages[dellist[-1]:dellist[0] + 1]
                    self.endRemoveRows()
                except:
                    return False
        return True

    def get_selected_text(self, rowlist):
        """
        Returns an easily readable block of text for the currently selected rows
        :param rowlist: list of row indexes, ''list(int)''
        :returns: the text from those indexes, ''str''
        """
        text = None
        if len(rowlist) != 0:
            text = ''
            rowlist = list(set(rowlist))
            for row in rowlist:
                text += self._messages[row].pretty_print()
        return text

    def get_time_range(self, rowlist):
        """
        :param rowlist: a list of row indexes, ''list''
        :returns: a tuple of min and max times in a rowlist in
                  '(unix timestamp).(fraction of second)' format, ''tuple(str,str)''
        """
        min_ = float("inf")
        max_ = float("-inf")
        for row in rowlist:
            item = self._messages[row].time_as_datestamp()
            if float(item) > float(max_):
                max_ = item
            if float(item) < float(min_):
                min_ = item
        return min_, max_

    def get_unique_nodes(self):
        nodes = set()
        for message in self._messages:
            nodes.add(message.node)
        return nodes

    def get_unique_severities(self):
        severities = set()
        for message in self._messages:
            severities.add(message.severity)
        return severities

    def get_unique_topics(self):
        topics = set()
        for message in self._messages:
            for topic in message.topics:
                topics.add(topic)
        return topics

    def get_severity_dict(self):
        return Message.SEVERITY_LABELS

    def get_message_between(self, start_time, end_time=None):
        """
        :param start_time: time to start in timestamp form (including decimal
        fractions of a second is acceptable, ''unixtimestamp''
        :param end_time: time to end in timestamp form (including decimal
        fractions of a second is acceptable, ''unixtimestamp'' (Optional)
        :returns: list of messages in the time range ''list[message]''
        """
        msgs = []
        for message in self._messages:
            msg_time = message.stamp[0] + float(message.stamp[1]) / 10**9
            if msg_time >= float(start_time) and (end_time is None or msg_time <= float(end_time)):
                msgs.append(message)
        return msgs
Пример #26
0
    def _draw_topic_history(self, painter, topic):
        """
        Draw boxes corrisponding to message regions on the timeline.
        :param painter: allows access to paint functions,''QPainter''
        :param topic: the topic for which message boxes should be drawn, ''str''
        """

#        x, y, w, h = self._history_bounds[topic]
        _, y, _, h = self._history_bounds[topic]

        msg_y = y + 2
        msg_height = h - 2

        datatype = self.scene().get_datatype(topic)

        # Get the renderer and the message combine interval
        renderer = None
        msg_combine_interval = None
        if topic in self._rendered_topics:
            renderer = self._timeline_renderers.get(datatype)
            if not renderer is None:
                msg_combine_interval = self.map_dx_to_dstamp(renderer.msg_combine_px)
        if msg_combine_interval is None:
            msg_combine_interval = self.map_dx_to_dstamp(self._default_msg_combine_px)

        # Get the cache
        if topic not in self.index_cache:
            return
        all_stamps = self.index_cache[topic]

#        start_index = bisect.bisect_left(all_stamps, self._stamp_left)
        end_index = bisect.bisect_left(all_stamps, self._stamp_right)
        # Set pen based on datatype
        datatype_color = self._datatype_colors.get(datatype, self._default_datatype_color)
        # Iterate through regions of connected messages
        width_interval = self._history_width / (self._stamp_right - self._stamp_left)

        # Draw stamps
        for (stamp_start, stamp_end) in self._find_regions(all_stamps[:end_index], self.map_dx_to_dstamp(self._default_msg_combine_px)):
            if stamp_end < self._stamp_left:
                continue

            region_x_start = self._history_left + (stamp_start - self._stamp_left) * width_interval
            if region_x_start < self._history_left:
                region_x_start = self._history_left  # Clip the region
            region_x_end = self._history_left + (stamp_end - self._stamp_left) * width_interval
            region_width = max(1, region_x_end - region_x_start)

            painter.setBrush(QBrush(datatype_color))
            painter.setPen(QPen(datatype_color, 1))
            painter.drawRect(region_x_start, msg_y, region_width, msg_height)

        # Draw active message
        if topic in self.scene()._listeners:
            curpen = painter.pen()
            oldwidth = curpen.width()
            curpen.setWidth(self._active_message_line_width)
            painter.setPen(curpen)
            playhead_stamp = None
            playhead_index = bisect.bisect_right(all_stamps, self.playhead.to_sec()) - 1
            if playhead_index >= 0:
                playhead_stamp = all_stamps[playhead_index]
                if playhead_stamp > self._stamp_left and playhead_stamp < self._stamp_right:
                    playhead_x = self._history_left + (all_stamps[playhead_index] - self._stamp_left) * width_interval
                    painter.drawLine(playhead_x, msg_y, playhead_x, msg_y + msg_height)
            curpen.setWidth(oldwidth)
            painter.setPen(curpen)

        # Custom renderer
        if renderer:
            # Iterate through regions of connected messages
            for (stamp_start, stamp_end) in self._find_regions(all_stamps[:end_index], msg_combine_interval):
                if stamp_end < self._stamp_left:
                    continue

                region_x_start = self._history_left + (stamp_start - self._stamp_left) * width_interval
                region_x_end = self._history_left + (stamp_end - self._stamp_left) * width_interval
                region_width = max(1, region_x_end - region_x_start)
                renderer.draw_timeline_segment(painter, topic, stamp_start, stamp_end, region_x_start, msg_y, region_width, msg_height)

        painter.setBrush(self._default_brush)
        painter.setPen(self._default_pen)
Пример #27
0
    def add_robot(self):
        rospy.loginfo('rqt_simulation : A new robot tab has been added.')
        # Add tab
        self.num_robots += 1
        self.tab_list.append(RobotTab(self.num_robots, self.robots))
        #self.tab_list[self.num_robots-1].signalRobotNameChanged.connect(self.robot_name_changed)
        self.tabWidget.addTab(self.tab_list[self.num_robots - 1],
                              ('Robot ' + str(self.num_robots)))
        self.button_remove_robot.setEnabled(True)
        self.current_graphicsScene.addItem(
            self.tab_list[self.num_robots - 1].initial_pose[
                'start_' + str(self.num_robots).zfill(2)]['text_item'])

        # Set initial pose
        if self.num_robots > 1:
            for i in range(0, len(self.FTS.region_of_interest)):
                self.tab_list[self.num_robots - 1].robot_comboBox_init.addItem(
                    self.FTS.region_of_interest.keys()[i])
            self.tab_list[self.num_robots -
                          1].robot_comboBox_init.model().sort(0)
        if len(self.current_graphicsScene.items_dict) > 0:
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.position.x = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['position'][0]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.position.y = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['position'][1]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.position.z = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['position'][2]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.orientation.w = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['orientation'][0]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.orientation.x = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['orientation'][1]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.orientation.y = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['orientation'][2]
            self.tab_list[
                self.num_robots -
                1].init_pose_msg.orientation.z = self.FTS.region_of_interest[
                    self.FTS.region_of_interest.keys()
                    [0]]['pose']['orientation'][3]

            self.current_graphicsScene.items_dict['r01'][
                'ellipse_item'].setBrush(QBrush(QColor('green')))
            rect = self.current_graphicsScene.items_dict['r01'][
                'ellipse_item'].rect()
            point = rect.topLeft()
            self.tab_list[self.num_robots - 1].initial_pose[
                'start_' + str(self.num_robots).zfill(2)]['text_item'].setPos(
                    point.x() - 11,
                    point.y() - 22)

        # Connect initial pose comboBox with set_init_pose_id function
        self.tab_list[self.num_robots -
                      1].robot_comboBox_init.signalIndexChanged.connect(
                          self.set_init_pose_id)
    def draw_flipper_state(self):
	length = 100

	self._widget.flipper_front_current.setText(str(self.flipper_state)) 

	#self.flipper_state += self.flipper_diff;

	if(self.flipper_state > self.flipper_front_max_state):
		self.flipper_diff *= -1	
	#	self.flipper_state = self.flipper_front_max_state

	if(self.flipper_state < self.flipper_front_min_state):
		self.flipper_diff *= -1	
	#	self.flipper_state = self.flipper_front_min_state

	self.flipper_scene.clear()

	self.draw_flipper_max()
	self.draw_flipper_min()

	#red chassi
	self.flipper_scene.addRect(65, 60, 145, 25, QPen(), QBrush(QColor(255,0,0)))

	#right wheel
	self.flipper_scene.addEllipse(150, 50, 50, 50, QPen(), QBrush(QColor(0,0,0)))

	#left wheel
	self.flipper_scene.addEllipse(50, 50, 50, 50, QPen(), QBrush(QColor(0,0,0)))
	
	#flipper wheel
	transform = QTransform()
	transform.translate(155,70)
	transform.rotateRadians(-self.flipper_state)
	transform.translate(-25,-25)

	#flipper wheel connection
	flipper_wheel = QtGui.QGraphicsEllipseItem(120,5, 50, 50)
	flipper_wheel.setTransform(transform)
	flipper_wheel.setBrush( QBrush(QColor(0,0,0)))

	self.flipper_scene.addItem(flipper_wheel)
	#self.flipper_scene.addEllipse(250, 50, 50, 50, QPen(), QBrush(QColor(0,0,0)))


	transform = QTransform()
	transform.translate(160,75)
	transform.rotateRadians(-self.flipper_state)
	transform.translate(-10,-10)
	flipper_link = QtGui.QGraphicsRectItem(0,0, 135, 20)
	flipper_link.setBrush( QBrush(QColor(163,163,163)))

	flipper_link.setTransform(transform)

	self.flipper_scene.addItem(flipper_link)

	#front connection
	self.flipper_scene.addEllipse(155, 70, 10, 10, QPen(), QBrush(QColor(0,0,0)))

	transform = QTransform()
	transform.translate(160,75)
	transform.rotateRadians(-self.flipper_state)
	transform.translate(-10,-10)

	#flipper wheel connection
	flipper_wheel_connection = QtGui.QGraphicsEllipseItem(120,5, 10, 10)
	flipper_wheel_connection.setTransform(transform)
	flipper_wheel_connection.setBrush( QBrush(QColor(0,0,0)))

	self.flipper_scene.addItem(flipper_wheel_connection)
Пример #29
0
    def redraw(self, event):
        """
        
        Draw timeline's "cells" (ie. boxes that represent seconds). 
                
        Taken from robot_monitor.message_timeline.on_paint
        
        @deprecated: This way (using QPainter) didn't work as intended.
        """

        #super(TimelineView, self).paintEvent(event)

        # painter = QPainter(self)
        ## This yields warning that says:
        ## "QPainter::begin: Widget painting can only begin as a result of a paintEvent"

        painter = QPainter()
        painter.begin(self.viewport())
        pen = QPen(
            Qt.black,
            2)  #, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)  # Needs modified.
        painter.setPen(pen)

        is_enabled = self.isEnabled()

        #(width_tl, height_tl) = self.size()
        qsize = self.size()
        width_tl = qsize.width()
        height_tl = qsize.height()

        length_tl = self._max_num_seconds + 1 - self._min_num_seconds
        rospy.logdebug('paintEvent is_enabled=%s length_tl=%d', is_enabled,
                       length_tl)
        value_size = width_tl / float(length_tl)
        for i in xrange(0, length_tl):
            brush = None
            color_index = i + self._min_num_seconds
            if (is_enabled):
                qcolor = self._color_callback(color_index)
            else:
                qcolor = QColor('grey')
            end_color = QColor(0.5 * QColor('red').value(),
                               0.5 * QColor('green').value(),
                               0.5 * QColor('blue').value())
            #painter.setBrush(qcolor)
            painter.setBrush(QBrush(qcolor))
            start = i * value_size
            end = (i + 1) * value_size
            rect = QRect(start, 0, end, height_tl)

            # dc.GradientFillLinear(wx.Rect(start, 0, end, height_tl),
            #                       qcolor, end_color, wx.SOUTH)
            rospy.logdebug('paintEvent i=%d start=%s end=%s height_tl=%s', i,
                           start, end, height_tl)
            #painter.fillRect(QRect(start, end, 100, height_tl), qcolor)
            painter.fillRect(rect, qcolor)

            if (i > 0):
                # dc.SetPen(wx.BLACK_PEN)
                pen.setColor(Qt.black)
                # dc.DrawLine(start, 0, start, height_tl)
                painter.drawLine(start, 0, start, height_tl)

        size_marker = QSize(20, 20)
        marker_x = (
            (self._xpos_marker - 1) * value_size + (value_size / 2.0) -
            (self._timeline_marker.actualSize(size_marker).width() / 2.0))

        # dc.DrawBitmap(self._timeline_marker, marker_x, 0, True)
        qrect = QRect(marker_x, 0, size_marker.width(), size_marker.height())
        self._timeline_marker.paint(painter, qrect)
        rospy.logdebug(' paintEvent marker_x=%s', marker_x)

        painter.end()
Пример #30
0
 def scene_draw_circle(self, id, pos, radius, color):
     ellipse = QGraphicsEllipseItem(pos['x'] - radius, pos['y'] - radius,
                                    radius * 2, radius * 2)
     ellipse.setBrush(QBrush(getattr(QtCore.Qt, color.lower())))
     self._scene.addItem(ellipse)
     self.items_cache['circle'][id] = ellipse