コード例 #1
0
 def test_add_subgraph_escape_name(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_subgraph_to_graph(g, 'graph')
     self.assertEqual(1, len(g.subgraphs()))
     self.assertEqual('cluster_graph', g.subgraphs()[0].get_name())
     self.assertEqual('graph', g.subgraphs()[0].graph_attr['label'])
コード例 #2
0
 def test_add_subgraph_escape_name(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_subgraph_to_graph(g, 'graph')
     self.assertEqual(1, len(g.subgraphs()))
     self.assertEqual('cluster_graph', g.subgraphs()[0].get_name())
     self.assertEqual('graph', g.subgraphs()[0].graph_attr['label'])
コード例 #3
0
 def test_add_node_escape_name(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'graph')
     self.assertEqual(1, len(g.nodes()))
     self.assertEqual('graph', g.nodes()[0].get_name())
     self.assertEqual('graph', g.nodes()[0].attr['label'])
コード例 #4
0
 def test_add_node_escape_name(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'graph')
     self.assertEqual(1, len(g.nodes()))
     self.assertEqual('graph', g.nodes()[0].get_name())
     self.assertEqual('graph', g.nodes()[0].attr['label'])
コード例 #5
0
 def test_add_edge(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'foo')
     fac.add_node_to_graph(g, 'bar')
     fac.add_edge_to_graph(g, 'foo', 'bar')
     self.assertEqual(2, len(g.nodes()))
     self.assertEqual(1, len(g.edges()))
     self.assertEqual('foo', g.edges()[0][0])
     self.assertEqual('bar', g.edges()[0][1])
コード例 #6
0
 def test_add_edge(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'foo')
     fac.add_node_to_graph(g, 'bar')
     fac.add_edge_to_graph(g, 'foo', 'bar')
     self.assertEqual(2, len(g.nodes()))
     self.assertEqual(1, len(g.edges()))
     self.assertEqual('foo', g.edges()[0][0])
     self.assertEqual('bar', g.edges()[0][1])
コード例 #7
0
 def test_create_dot(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'foo')
     fac.add_node_to_graph(g, 'edge')
     fac.add_edge_to_graph(g, 'foo', 'edge')
     fac.add_subgraph_to_graph(g, 'graph')
     snippets = ['strict digraph {\n\tgraph',
                 'foo',
                 'label=foo',
                 '"edge"',
                 'label="edge"',
                 'foo -> "edge"']
     result = fac.create_dot(g)
     for sn in snippets:
         self.assertTrue(sn in result, '%s \nmissing in\n %s' % (sn, result))
コード例 #8
0
 def test_get_graph(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     self.assertEquals('same', g.graph_attr['rank'])
     self.assertTrue(g.is_directed())
コード例 #9
0
    def __init__(self, context):
        super(RosBehaviourTree, self).__init__(context)
        self.setObjectName('RosBehaviourTree')

        parser = argparse.ArgumentParser()
        RosBehaviourTree.add_arguments(parser, False)
        # if the context doesn't have an argv attribute then assume we're running with --no-roscore
        if not hasattr(context, 'argv'):
            args = sys.argv[1:]
            # Can run the viewer with or without live updating. Running without is
            # intended for viewing of bags only
            self.live_update = False
        else:
            args = context.argv()
            self.live_update = True

        parsed_args = parser.parse_args(args)

        self.context = context
        self.initialized = False
        self._current_dotcode = None  # dotcode for the tree that is currently displayed
        self._viewing_bag = False  # true if a bag file is loaded
        # True if next or previous buttons are pressed. Reset if the tree being
        # viewed is the last one in the list.
        self._browsing_timeline = False

        self._widget = QWidget()

        # factory builds generic dotcode items
        self.dotcode_factory = PygraphvizFactory()  # PydotFactory()
        # self.dotcode_factory = PygraphvizFactory()
        # generator builds rosgraph
        self.dotcode_generator = RosBehaviourTreeDotcodeGenerator()
        self.current_topic = None
        self.behaviour_sub = None
        self._tip_message = None  # message of the tip of the tree
        self._saved_settings_topic = None  # topic subscribed to by previous instance
        self.visibility_level = py_trees.common.VisibilityLevel.DETAIL

        # dot_to_qt transforms into Qt elements using dot layout
        self.dot_to_qt = DotToQtGenerator()

        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_py_trees'), 'resource',
                               'RosBehaviourTree.ui')
        loadUi(ui_file, self._widget,
               {'InteractiveGraphicsView': InteractiveGraphicsView})
        self._widget.setObjectName('RosBehaviourTreeUi')
        if hasattr(context, 'serial_number') and context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))

        self._scene = QGraphicsScene()
        self._scene.setBackgroundBrush(Qt.white)
        self._widget.graphics_view.setScene(self._scene)

        self._widget.highlight_connections_check_box.toggled.connect(
            self._redraw_graph_view)
        self._widget.auto_fit_graph_check_box.toggled.connect(
            self._redraw_graph_view)
        self._widget.fit_in_view_push_button.setIcon(
            QIcon.fromTheme('zoom-original'))
        self._widget.fit_in_view_push_button.pressed.connect(self._fit_in_view)

        self._widget.load_bag_push_button.setIcon(
            QIcon.fromTheme('document-open'))
        self._widget.load_bag_push_button.pressed.connect(self._load_bag)
        self._widget.load_dot_push_button.setIcon(
            QIcon.fromTheme('document-open'))
        self._widget.load_dot_push_button.pressed.connect(self._load_dot)
        self._widget.save_dot_push_button.setIcon(
            QIcon.fromTheme('document-save-as'))
        self._widget.save_dot_push_button.pressed.connect(self._save_dot)
        self._widget.save_as_svg_push_button.setIcon(
            QIcon.fromTheme('document-save-as'))
        self._widget.save_as_svg_push_button.pressed.connect(self._save_svg)
        self._widget.save_as_image_push_button.setIcon(
            QIcon.fromTheme('image'))
        self._widget.save_as_image_push_button.pressed.connect(
            self._save_image)

        for text in visibility.combo_to_py_trees:
            self._widget.visibility_level_combo_box.addItem(text)
        self._widget.visibility_level_combo_box.setCurrentIndex(
            self.visibility_level)
        self._widget.visibility_level_combo_box.currentIndexChanged[
            'QString'].connect(self._update_visibility_level)

        # set up the function that is called whenever the box is resized -
        # ensures that the timeline is correctly drawn.
        self._widget.resizeEvent = self._resize_event

        self._timeline = None
        self._timeline_listener = None

        # Connect the message changed function of this object to a corresponding
        # signal. This signal will be activated whenever the message being
        # viewed changes.
        self._message_changed.connect(self.message_changed)
        self._message_cleared.connect(self.message_cleared)

        # Set up combo box for topic selection
        # when the refresh_combo signal happens, update the combo topics available
        self._refresh_combo.connect(self._update_combo_topics)
        # filter events to catch the event which opens the combo box
        self._combo_event_filter = RosBehaviourTree.ComboBoxEventFilter(
            self._refresh_combo)
        self._widget.topic_combo_box.installEventFilter(
            self._combo_event_filter)
        self._widget.topic_combo_box.activated.connect(self._choose_topic)
        self._update_combo_topics()

        # Set up navigation buttons
        self._widget.previous_tool_button.pressed.connect(self._previous)
        self._widget.previous_tool_button.setIcon(
            QIcon.fromTheme('go-previous'))
        self._widget.next_tool_button.pressed.connect(self._next)
        self._widget.next_tool_button.setIcon(QIcon.fromTheme('go-next'))
        self._widget.first_tool_button.pressed.connect(self._first)
        self._widget.first_tool_button.setIcon(QIcon.fromTheme('go-first'))
        self._widget.last_tool_button.pressed.connect(self._last)
        self._widget.last_tool_button.setIcon(QIcon.fromTheme('go-last'))

        # play, pause and stop buttons
        self._widget.play_tool_button.pressed.connect(self._play)
        self._widget.play_tool_button.setIcon(
            QIcon.fromTheme('media-playback-start'))
        self._widget.stop_tool_button.pressed.connect(self._stop)
        self._widget.stop_tool_button.setIcon(
            QIcon.fromTheme('media-playback-stop'))
        # also connect the navigation buttons so that they stop the timer when
        # pressed while the tree is playing.
        self._widget.first_tool_button.pressed.connect(self._stop)
        self._widget.previous_tool_button.pressed.connect(self._stop)
        self._widget.last_tool_button.pressed.connect(self._stop)
        self._widget.next_tool_button.pressed.connect(self._stop)

        # set up shortcuts for navigation (vim)
        next_shortcut_vi = QShortcut(QKeySequence("l"), self._widget)
        next_shortcut_vi.activated.connect(
            self._widget.next_tool_button.pressed)
        previous_shortcut_vi = QShortcut(QKeySequence("h"), self._widget)
        previous_shortcut_vi.activated.connect(
            self._widget.previous_tool_button.pressed)
        first_shortcut_vi = QShortcut(QKeySequence("^"), self._widget)
        first_shortcut_vi.activated.connect(
            self._widget.first_tool_button.pressed)
        last_shortcut_vi = QShortcut(QKeySequence("$"), self._widget)
        last_shortcut_vi.activated.connect(
            self._widget.last_tool_button.pressed)

        # shortcuts for emacs
        next_shortcut_emacs = QShortcut(QKeySequence("Ctrl+f"), self._widget)
        next_shortcut_emacs.activated.connect(
            self._widget.next_tool_button.pressed)
        previous_shortcut_emacs = QShortcut(QKeySequence("Ctrl+b"),
                                            self._widget)
        previous_shortcut_emacs.activated.connect(
            self._widget.previous_tool_button.pressed)
        first_shortcut_emacs = QShortcut(QKeySequence("Ctrl+a"), self._widget)
        first_shortcut_emacs.activated.connect(
            self._widget.first_tool_button.pressed)
        last_shortcut_emacs = QShortcut(QKeySequence("Ctrl+e"), self._widget)
        last_shortcut_emacs.activated.connect(
            self._widget.last_tool_button.pressed)

        # set up stuff for dotcode cache
        self._dotcode_cache_capacity = 50
        self._dotcode_cache = {}
        # cache is ordered on timestamps from messages, but earliest timestamp
        # isn't necessarily the message that was viewed the longest time ago, so
        # need to store keys
        self._dotcode_cache_keys = []

        # set up stuff for scene cache (dotcode cache doesn't seem to make much difference)
        self._scene_cache_capacity = 50
        self._scene_cache = {}
        self._scene_cache_keys = []

        # Update the timeline buttons to correspond with a completely
        # uninitialised state.
        self._set_timeline_buttons(first_snapshot=False,
                                   previous_snapshot=False,
                                   next_snapshot=False,
                                   last_snapshot=False)

        self._deferred_fit_in_view.connect(self._fit_in_view,
                                           Qt.QueuedConnection)
        self._deferred_fit_in_view.emit()

        # This is used to store a timer which controls how fast updates happen when the play button is pressed.
        self._play_timer = None

        # updates the view
        self._refresh_view.connect(self._refresh_tree_graph)

        self._force_refresh = False

        if self.live_update:
            context.add_widget(self._widget)
        else:
            self.initialized = True  # this needs to be set for trees to be displayed
            context.setCentralWidget(self._widget)

        if parsed_args.bag:
            self._load_bag(parsed_args.bag)
        elif parsed_args.latest_bag:
            # if the latest bag is requested, load it from the default directory, or
            # the one specified in the args
            bag_dir = parsed_args.bag_dir or os.getenv(
                'ROS_HOME', os.path.expanduser('~/.ros')) + '/behaviour_trees'
            self.open_latest_bag(bag_dir, parsed_args.by_time)
コード例 #10
0
 def test_create_dot(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'foo')
     fac.add_node_to_graph(g, 'edge')
     fac.add_edge_to_graph(g, 'foo', 'edge')
     fac.add_subgraph_to_graph(g, 'graph')
     snippets = ['strict digraph {\n\tgraph',
                 'foo',
                 'label=foo',
                 '"edge"',
                 'label="edge"',
                 'foo -> "edge"']
     result = fac.create_dot(g)
     for sn in snippets:
         self.assertTrue(sn in result, '%s \nmissing in\n %s' % (sn, result))
コード例 #11
0
 def test_get_graph(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     self.assertEquals('same', g.graph_attr['rank'])
     self.assertTrue(g.is_directed())
コード例 #12
0
 def test_create_dot(self):
     fac = PygraphvizFactory()
     g = fac.get_graph()
     fac.add_node_to_graph(g, 'foo')
     fac.add_node_to_graph(g, 'edge')
     fac.add_edge_to_graph(g, 'foo', 'edge')
     fac.add_subgraph_to_graph(g, 'graph')
     snippets = [
         'strict digraph { graph', 'foo', 'label=foo', '"edge"',
         'label="edge"', 'foo -> "edge"'
     ]
     result = fac.create_dot(g)
     # get rid of version specific quotes / whitespaces
     result = re.sub('""', ' ', result)
     result = re.sub('[\n\t ]+', ' ', result)
     for sn in snippets:
         self.assertTrue(sn in result,
                         '%s \nmissing in\n %s' % (sn, result))