def _set_knowledge_base(self, kb_name, pattern_text=""):
        """
        set the knowledge base we want to connect to
        :param kb_name: name of the KB
        :param pattern_text: pattern for the KB update as text, komma separates tuples
        """
        with self.__connect_lock:
            self._widget.kbStatusLabel.setText(
                "Trying to connect to {0}".format(kb_name))
            if hasattr(self, "_kb_cache") and self._kb_cache:
                self._kb_cache.remove_update_listener(
                    self._update_kb_facts_emit_func)
                self._fact_table_model.clear()
            self._kb_name = kb_name
            if len(pattern_text) > 0:
                pattern = pattern_text.split(",")
            else:
                pattern = ()
            self._kb_cache = KnowledgeBaseFactCache(
                pattern=pattern, knowledge_base_name=self._kb_name, timeout=2)
            self._update_discovery(DiscoverInfo(kb_name=kb_name))
            self._kb_cache.add_update_listener(self._update_kb_facts_emit_func)

            # manually update once
            try:
                self._callback_update_fact_update(
                )  # not using emit here to get possible exceptions
            except rospy.ROSException as e:
                rospy.logwarn(e)
                self._widget.kbStatusLabel.setText(
                    "Could not connect to '{0}'".format(kb_name))
    def test_multiple_updates(self):
        prefix = self.__message_prefix + '_test_multiple_updates'
        updated_old_1 = (prefix, 'fact_1', '1')
        updated_old_2 = (prefix, 'fact_2', '2')
        self.__client.push(updated_old_1)
        self.__client.push(updated_old_2)

        cache = KnowledgeBaseFactCache(
            pattern=(prefix, '*', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        updated_new_1 = (prefix, 'fact_1', '1*')
        self.__client.update(updated_old_1, updated_new_1)

        updated_new_2 = (prefix, 'fact_2', '2*')

        update_stamp = cache.update_time
        self.__client.update(updated_old_2, updated_new_2)

        rospy.sleep(0.5)
        while update_stamp == cache.update_time:
            rospy.sleep(0.5)

        current = cache.get_all_matching_facts()

        self.assertEqual(2, len(current))
        self.assertTrue(updated_new_1 in current,
                        'Update of updated_new_1 not noticed')
        self.assertTrue(updated_new_2 in current,
                        'Update of updated_new_2 not noticed')
    def test_update_existing(self):
        """
        Test updating a fact that is already stored.
        """
        prefix = self.__message_prefix + '_test_update_existing'

        updated_old = (prefix, 'updated', '1')

        self.assertTrue(self.__client.push(updated_old))

        rospy.sleep(0.1)

        cache = KnowledgeBaseFactCache(
            pattern=(prefix, '*', '*'),
            knowledge_base_name=self.__knowledge_base_address)
        rospy.sleep(0.1)
        updated_new = (prefix, 'updated', '1')
        self.assertTrue(self.__client.update((prefix, '*', '*'), updated_new))

        rospy.sleep(
            0.5
        )  # don' t wait for updates because we will not get one, as nothing changed

        current = cache.get_all_matching_facts()

        self.assertEqual(1, len(current))
        self.assertTrue(updated_new in current, 'Update corrupted')
Пример #4
0
 def __init__(self,
              pattern,
              optional=False,
              knowledge_base_name=KnowledgeBase.DEFAULT_NAME,
              name=None):
     super(KnowledgeSensor, self).__init__(name=name,
                                           optional=optional,
                                           initial_value=None)
     self.__value_cache = KnowledgeBaseFactCache(
         pattern=pattern, knowledge_base_name=knowledge_base_name)
Пример #5
0
 def __init__(self,
              pattern,
              optional=False,
              knowledge_base_name=KnowledgeBase.DEFAULT_NAME,
              name=None,
              initial_value=None):
     super(KnowledgeFactSensor, self).__init__(name=name,
                                               optional=optional,
                                               initial_value=initial_value)
     self._value_cache = KnowledgeBaseFactCache(
         pattern=pattern, knowledge_base_name=knowledge_base_name)
     self._value_cache.add_update_listener(self._cache_update_callback)
Пример #6
0
    def test_simple_adding(self):
        """
        Tests basic case of adding a tuple
        """
        test_tuple = (self.__message_prefix, 'test_simple_adding', '0', '0')

        cache = KnowledgeBaseFactCache(pattern=test_tuple)
        self.assertFalse(cache.does_fact_exists(),
                         'Tuple is not added, but is indicated as present')

        self.__client.push(test_tuple)
        rospy.sleep(0.1)

        self.assertTrue(cache.does_fact_exists(),
                        'Tuple was added, but is not indicated as present')
Пример #7
0
    def test_update_replacing_several_facts(self):

        prefix = self.__message_prefix + 'test_update_replacing_several_facts'
        updated_old_1 = (prefix, 'toUpdate', '1')
        updated_old_2 = (prefix, 'toUpdate', '2')
        not_influenced = (prefix, 'not_influenced', '1')

        cache = KnowledgeBaseFactCache(pattern=(prefix, '*', '*'))

        rospy.sleep(0.1)

        self.__client.push(updated_old_1)
        self.__client.push(updated_old_2)
        self.__client.push(not_influenced)

        rospy.sleep(0.1)

        self.__check_content(cache, updated_old_1, updated_old_2,
                             not_influenced)

        new_fact = (prefix, 'updated', '3')

        self.__client.update((prefix, 'toUpdate', '*'), new_fact)

        rospy.sleep(0.1)

        self.__check_content(cache, not_influenced, new_fact)
    def test_sub_fact_matching(self):
        prefix = self.__message_prefix + '_test_multiple_updates'
        fact_1 = (prefix, 'fact_1', '1', 'a')
        self.__client.push(fact_1)
        fact_2 = (prefix, 'fact_2', '2', 'a')
        self.__client.push(fact_2)
        fact_3 = (prefix, 'fact_3', '3', 'b')
        self.__client.push(fact_3)

        all_pattern = ()
        cache = KnowledgeBaseFactCache(
            pattern=all_pattern,
            knowledge_base_name=self.__knowledge_base_address)

        # initial check to see if we have a correct setup
        current = cache.get_all_matching_facts()
        self.assertEqual(3, len(current))

        sub_fact_pattern = (prefix, 'fact_2', '2', 'a')
        does_exist = cache.does_sub_fact_exist(pattern=sub_fact_pattern)

        self.assertTrue(does_exist)

        first_sub_fact = cache.get_matching_sub_fact(pattern=sub_fact_pattern)

        self.assertEqual(first_sub_fact, fact_2)

        # test with sub placeholders
        sub_fact_pattern = (prefix, '*', '*', 'a')
        does_exist = cache.does_sub_fact_exist(pattern=sub_fact_pattern)

        self.assertTrue(does_exist)

        first_sub_fact = cache.get_matching_sub_fact(pattern=sub_fact_pattern)

        self.assertEqual(first_sub_fact, fact_1)

        all_sub_facts = cache.get_all_matching_sub_facts(
            pattern=sub_fact_pattern)
        self.assertEqual(2, len(all_sub_facts))
        self.assertTrue(fact_1 in all_sub_facts,
                        "fact_1 not found in sub facts")
        self.assertTrue(fact_2 in all_sub_facts,
                        "fact_2 not found in sub facts")

        # invalid pattern
        sub_fact_pattern = (prefix, 'fact_unknown', '2', 'a')
        does_exist = cache.does_sub_fact_exist(pattern=sub_fact_pattern)

        self.assertFalse(does_exist)
Пример #9
0
class KnowledgeSensor(Sensor):
    """
    Sensor, which provides information about existence of any fact, matching the given pattern
    """
    def __init__(self,
                 pattern,
                 optional=False,
                 knowledge_base_name=KnowledgeBase.DEFAULT_NAME,
                 name=None):
        super(KnowledgeSensor, self).__init__(name=name,
                                              optional=optional,
                                              initial_value=False)
        self._value_cache = KnowledgeBaseFactCache(
            pattern=pattern, knowledge_base_name=knowledge_base_name)
        self._value_cache.add_update_listener(self._cache_update_callback)

    def _cache_update_callback(self):
        self.update(self._value_cache.does_fact_exists())
Пример #10
0
    def test_update(self):
        prefix = self.__message_prefix + '_test_update'
        updated_old = (prefix, 'updated', '1')
        not_influenced = (prefix, 'not_influenced', '1')
        self.__client.push(updated_old)
        self.__client.push(not_influenced)

        cache = KnowledgeBaseFactCache(pattern=(prefix, '*', '*'))

        updated_new = (prefix, 'updated', '0')

        self.__client.update(updated_old, updated_new)
        rospy.sleep(0.1)

        current = cache.get_all_matching_facts()
        self.assertEqual(2, len(current))
        self.assertTrue(updated_new in current, 'Update not noticed')
        self.assertTrue(not_influenced in current,
                        'NotInfluenced was influenced')
Пример #11
0
    def test_remove(self):
        test_tuple = (self.__message_prefix, 'test_remove', '0', '0')

        cache = KnowledgeBaseFactCache(pattern=test_tuple)
        self.assertFalse(cache.does_fact_exists(),
                         'Tuple is not added, but is indicated as present')

        self.__client.push(test_tuple)
        rospy.sleep(0.1)

        self.assertTrue(cache.does_fact_exists(),
                        'Tuple was added, but is not indicated as present')

        self.__client.pop(test_tuple)

        rospy.sleep(0.1)
        self.assertFalse(
            cache.does_fact_exists(),
            'Tuple was removed, but is still indicated as present')
    def test_update_non_existing(self):
        prefix = self.__message_prefix + 'test_update_non_existing'
        updated_not_existing = (prefix, 'updated', '1')

        cache = KnowledgeBaseFactCache(
            pattern=(prefix, '*', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        update_stamp = cache.update_time

        updated_new = (prefix, 'updated', '0')

        self.__client.update(updated_not_existing, updated_new)
        while update_stamp == cache.update_time:
            rospy.sleep(0.5)

        current = cache.get_all_matching_facts()
        self.assertEqual(1, len(current))
        self.assertTrue(updated_new in current, 'Update not noticed')
Пример #13
0
    def test_multiple_updates(self):
        prefix = self.__message_prefix + '_test_multiple_updates'
        updated_old_1 = (prefix, 'fact_1', '1')
        updated_old_2 = (prefix, 'fact_2', '2')
        self.__client.push(updated_old_1)
        self.__client.push(updated_old_2)

        cache = KnowledgeBaseFactCache(pattern=(prefix, '*', '*'))

        updated_new_1 = (prefix, 'fact_1', '3')
        self.__client.update(updated_old_1, updated_new_1)

        updated_new_2 = (prefix, 'fact_2', '4')
        self.__client.update(updated_old_2, updated_new_2)
        rospy.sleep(0.1)

        current = cache.get_all_matching_facts()
        self.assertEqual(2, len(current))
        self.assertTrue(updated_new_1 in current, 'Update not noticed')
        self.assertTrue(updated_new_2 in current, 'Update not noticed')
Пример #14
0
class KnowledgeFactSensor(Sensor):
    """
    Sensor, which provides information about a searched fact; returns list of
    all matching facts
    """
    def __init__(self,
                 pattern,
                 optional=False,
                 knowledge_base_name=KnowledgeBase.DEFAULT_NAME,
                 name=None,
                 initial_value=None):
        super(KnowledgeFactSensor, self).__init__(name=name,
                                                  optional=optional,
                                                  initial_value=initial_value)
        self._value_cache = KnowledgeBaseFactCache(
            pattern=pattern, knowledge_base_name=knowledge_base_name)
        self._value_cache.add_update_listener(self._cache_update_callback)

    def _cache_update_callback(self):
        self.update(self._value_cache.get_all_matching_facts())
    def test_all_pattern_with_update(self):
        prefix = self.__message_prefix + '_test_multiple_updates'
        updated_old_1 = (prefix, 'fact_1', '1')
        self.__client.push(updated_old_1)

        all_pattern = ()
        cache = KnowledgeBaseFactCache(
            pattern=all_pattern,
            knowledge_base_name=self.__knowledge_base_address)
        update_stamp = cache.update_time

        updated_new_1 = (prefix, 'fact_1', '3')
        self.__client.update(updated_old_1, updated_new_1)

        while update_stamp == cache.update_time:
            rospy.sleep(0.1)

        current = cache.get_all_matching_facts()
        self.assertEqual(1, len(current))
        self.assertTrue(updated_new_1 in current, 'Update not noticed')
    def test_mass_updates(self):
        """
        Here we test many updates in a short time period
        """

        prefix = self.__message_prefix + 'test_mass_updates'

        number_of_entries = 500

        # fill KB
        for i in range(number_of_entries):

            updated_old_1 = (prefix, 'fact', str(i))
            self.__client.push(updated_old_1)

        cache = KnowledgeBaseFactCache(
            pattern=(prefix, 'fact_new', '*'),
            knowledge_base_name=self.__knowledge_base_address)
        current = cache.get_all_matching_facts()
        self.assertEqual(0, len(current))

        rospy.sleep(0.5)

        for i in range(number_of_entries):
            updated_old_1 = (prefix, 'fact', str(i))
            updated_new_1 = (prefix, 'fact_new', str(i))
            last_fact = updated_new_1
            self.__client.update(updated_old_1, updated_new_1)

        rospy.sleep(0.5)
        while last_fact != cache.last_updated_fact:
            rospy.sleep(0.5)

        current = cache.get_all_matching_facts()

        # test if we received all tuples
        for i in range(number_of_entries):
            updated_new_1 = (prefix, 'fact_new', str(i))
            self.assertTrue(
                updated_new_1 in current,
                'Update of "' + str(updated_new_1) + '" not noticed')
Пример #17
0
    def test_update_existing(self):
        """
        Test updating an existing fact 
        """
        prefix = self.__message_prefix + '_test_update_empty'

        updated_old = (prefix, 'updated', '1')

        self.__client.push(updated_old)

        cache = KnowledgeBaseFactCache(pattern=(prefix, '*', '*'))

        updated_new = (prefix, 'updated', '1')

        self.__client.update((prefix, '*', '*'), updated_new)
        rospy.sleep(0.1)

        current = cache.get_all_matching_facts()

        self.assertEqual(1, len(current))
        self.assertTrue(updated_new in current, 'Update not noticed')
Пример #18
0
    def test_middle_placeholder(self):
        """
        Test updating an existing fact 
        """
        prefix = self.__message_prefix + '_test_middle_placeholder'

        first_fact = (prefix, 'updated', 'a', '1')

        second_fact = (prefix, 'updated', 'b', '1')

        self.__client.push(first_fact)
        self.__client.push(second_fact)

        cache = KnowledgeBaseFactCache(pattern=(prefix, 'updated', '*', '1'))

        rospy.sleep(0.1)

        current = cache.get_all_matching_facts()

        self.assertEqual(2, len(current))
        self.assertTrue(first_fact in current, 'fact not found')
        self.assertTrue(second_fact in current, 'fact not found')
Пример #19
0
    def test_multiple_caches_for_same_pattern(self):
        test_tuple = (self.__message_prefix,
                      'test_multiple_caches_for_same_pattern', '0', '0')

        cache1 = KnowledgeBaseFactCache(pattern=test_tuple)
        cache2 = KnowledgeBaseFactCache(pattern=test_tuple)

        self.assertFalse(cache1.does_fact_exists(),
                         'Tuple is not added, but is indicated as present')
        self.assertFalse(cache2.does_fact_exists(),
                         'Tuple is not added, but is indicated as present')

        self.__client.push(test_tuple)
        rospy.sleep(0.1)

        self.assertTrue(cache1.does_fact_exists(),
                        'Tuple was added, but is not indicated as present')
        self.assertTrue(cache2.does_fact_exists(),
                        'Tuple was added, but is not indicated as present')
    def test_update_with_partly_matching_patterns(self):
        """
        test an update that replaces several existing facts with a single new one or adds a new fact as a result of an
        update
        """
        prefix = self.__message_prefix + 'test_update_reduction'
        updated_old_1 = (prefix, 'fact_1', '1')
        updated_old_2 = (prefix, 'fact_2', '1')
        self.__client.push(updated_old_1)
        self.__client.push(updated_old_2)

        cache_all = KnowledgeBaseFactCache(
            pattern=(prefix, '*', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        cache_specific_1 = KnowledgeBaseFactCache(
            pattern=(prefix, 'fact_1', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        cache_specific_2 = KnowledgeBaseFactCache(
            pattern=(prefix, 'fact_2', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        cache_specific_3 = KnowledgeBaseFactCache(
            pattern=(prefix, 'fact_3', '*'),
            knowledge_base_name=self.__knowledge_base_address)

        current_all = cache_all.get_all_matching_facts()
        current_specific_1 = cache_specific_1.get_all_matching_facts()
        current_specific_2 = cache_specific_2.get_all_matching_facts()
        current_specific_3 = cache_specific_3.get_all_matching_facts()

        self.assertEqual(2, len(current_all))
        self.assertEqual(1, len(current_specific_1))
        self.assertEqual(1, len(current_specific_2))
        self.assertEqual(0, len(current_specific_3))

        updated_new = (prefix, 'fact_3', '1')
        update_stamp1 = cache_all.update_time
        update_stamp2 = cache_specific_1.update_time
        update_stamp3 = cache_specific_2.update_time
        update_stamp4 = cache_specific_3.update_time
        self.__client.update((prefix, '*', '1'), updated_new)

        # wait until the caches are updated
        rospy.sleep(0.5)
        while update_stamp1 == cache_all.update_time or \
                update_stamp2 == cache_specific_1.update_time or update_stamp3 == cache_specific_2.update_time \
                or update_stamp4 == cache_specific_3.update_time:
            rospy.sleep(0.1)

        current_all = cache_all.get_all_matching_facts()
        current_specific_1 = cache_specific_1.get_all_matching_facts()
        current_specific_2 = cache_specific_2.get_all_matching_facts()
        current_specific_3 = cache_specific_3.get_all_matching_facts()

        self.assertEqual(1, len(current_all))
        self.assertEqual(0, len(current_specific_1))
        self.assertEqual(0, len(current_specific_2))
        self.assertEqual(1, len(current_specific_3))
        self.assertTrue(updated_new in current_all,
                        'Update general cache of not noticed')
        self.assertTrue(updated_new not in current_specific_1,
                        'Delete update in specific cache 1 not noticed')
        self.assertTrue(updated_new not in current_specific_2,
                        'Delete update in specific cache 2 not noticed')
        self.assertTrue(updated_new in current_specific_3,
                        'Add update in specific cache 3 not noticed')
class KbUi(Plugin):
    """
    KnowledgeBase Monitor Plugin main class

    The Plugin allows to connect to a running KB and enables displaying and editing of the current fact base
    """

    _update_kb_facts = pyqtSignal()
    _set_kb = pyqtSignal(str, str)
    _update_discover = pyqtSignal(DiscoverInfo)

    def __init__(self, context):
        super(KbUi, self).__init__(context)

        self.setObjectName('KnowledgeBase UI')

        self.__edit_lock = threading.Lock()
        self.__connect_lock = threading.Lock()

        self._kb_name = KnowledgeBase.DEFAULT_NAME

        # Give QObjects reasonable names
        self.setObjectName('kb_monitor')

        # Storing discovered knowledge base names
        self._kb_node_collection = []

        # Create QWidget
        self._widget = QWidget()
        # Get path to UI file which should be in the "resource" folder of this node
        ui_file = os.path.join(rospkg.RosPack().get_path('knowledge_base'),
                               'src', 'kb_rqt_plugin', 'resource', 'main.ui')
        # Extend the widget with all attributes and children from UI file
        loadUi(ui_file, self._widget)
        # Give QObjects reasonable names
        self._widget.setObjectName('KnowledgeBase Monitor')
        # Show _widget.windowTitle on left-top of each plugin (when it's set in _widget).
        # This is useful when you open multiple plugins at once. Also if you open multiple instances of your
        # plugin at once, these lines add number to make it easy to tell from pane to pane.
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        # Add widget to the user interface
        context.add_widget(self._widget)

        self._widget.kbConnectPushButton.clicked.connect(
            self._connect_button_callback)

        self._fact_table_model = FactTableModel(kb_name=self._kb_name,
                                                parent=self._widget)

        self._widget.kbTableView.setModel(self._fact_table_model)

        self._widget.kbPatternlineEdit.setToolTip(
            "Separate tuples with , and use * as placeholder, keep empty to "
            "match all tuples")

        # configuring TableView event for item edit
        self._cell_edit_delegate = ItemDelegate(self._widget)
        self._cell_edit_delegate.cellEditingStarted.connect(
            self._callback_kb_editing_started)
        self._cell_edit_delegate.cellEditingFinished.connect(
            self._callback_kb_editing_finished)
        self._widget.kbTableView.setItemDelegate(self._cell_edit_delegate)

        # connecting signals
        self._update_kb_facts.connect(self._callback_update_fact_update)
        # this is necessary to correctly (un)register in KnowledgeBaseFactCache, directly using .emit returns
        #  uncomparable objects
        self._update_kb_facts_emit_func = self._update_kb_facts.emit
        self._update_discover.connect(self._update_discovery)
        self._set_kb.connect(self._set_knowledge_base)

        # subscribe to our information source
        self.__kb_discovery = rospy.Subscriber(
            KnowledgeBase.DISCOVERY_TOPIC_NAME, DiscoverInfo,
            self._update_discover.emit)

    def _set_knowledge_base(self, kb_name, pattern_text=""):
        """
        set the knowledge base we want to connect to
        :param kb_name: name of the KB
        :param pattern_text: pattern for the KB update as text, komma separates tuples
        """
        with self.__connect_lock:
            self._widget.kbStatusLabel.setText(
                "Trying to connect to {0}".format(kb_name))
            if hasattr(self, "_kb_cache") and self._kb_cache:
                self._kb_cache.remove_update_listener(
                    self._update_kb_facts_emit_func)
                self._fact_table_model.clear()
            self._kb_name = kb_name
            if len(pattern_text) > 0:
                pattern = pattern_text.split(",")
            else:
                pattern = ()
            self._kb_cache = KnowledgeBaseFactCache(
                pattern=pattern, knowledge_base_name=self._kb_name, timeout=2)
            self._update_discovery(DiscoverInfo(kb_name=kb_name))
            self._kb_cache.add_update_listener(self._update_kb_facts_emit_func)

            # manually update once
            try:
                self._callback_update_fact_update(
                )  # not using emit here to get possible exceptions
            except rospy.ROSException as e:
                rospy.logwarn(e)
                self._widget.kbStatusLabel.setText(
                    "Could not connect to '{0}'".format(kb_name))

    def _connect_button_callback(self):
        self.start_kb_update_thread(self._widget.kbNodeComboBox.currentText(),
                                    self._widget.kbPatternlineEdit.text())

    def _callback_kb_editing_started(self, row, column):
        self.__edit_lock.acquire()

    def _callback_kb_editing_finished(self, row, column):
        self.__edit_lock.release()

    def _callback_update_fact_update(self):
        if self.__edit_lock.acquire(False):
            try:
                facts = self._kb_cache.get_all_matching_facts()
                self._fact_table_model.update(new_facts=facts)
                self._fact_table_model.kb_name = self._kb_name
                self._widget.kbStatusLabel.setText("Last Update: {0}".format(
                    time.ctime()))
            finally:
                self.__edit_lock.release()

    def _update_discovery(self, kb_discovery):
        """
        Update kb list
        :param kb_discovery: 
        :type kb_discovery DiscoverInfo
        """
        kb_name = kb_discovery.kb_name
        if kb_name not in self._kb_node_collection:
            self._kb_node_collection.append(kb_name)
            self._widget.kbNodeComboBox.addItem(kb_name)
            rospy.loginfo("Added kb node: %s", kb_name)
            self._widget.kbStatusLabel.setText(
                "Added new KB node '{0}'".format(kb_name))

    def shutdown_plugin(self):
        self.__kb_discovery.unregister()

    def save_settings(self, plugin_settings, instance_settings):
        rospy.loginfo("saving knowledge_base setting")
        instance_settings.set_value("knowledge_base_name", self._kb_name)

    def restore_settings(self, plugin_settings, instance_settings):
        rospy.loginfo("restoring knowledge_base setting")
        stored_kb_name = instance_settings.value("knowledge_base_name")
        if type(stored_kb_name) == unicode:
            stored_kb_name = stored_kb_name.encode('ascii', 'ignore')
        if stored_kb_name:
            rospy.loginfo("Using stored prefix: %s", stored_kb_name)
            kb_name = stored_kb_name
        else:
            kb_name = KnowledgeBase.DEFAULT_NAME

        self.start_kb_update_thread(kb_name)

    def start_kb_update_thread(self, kb_name, pattern_text=""):
        """
        starting a background thread for kb update (new kb or pattern)
        :param kb_name: name of the knowledge base
        :param pattern_text: pattern to use for updates
        """

        # update with local function and thread
        def run_kb_update():
            try:
                self._set_knowledge_base(kb_name=kb_name,
                                         pattern_text=pattern_text)
            except rospy.ROSException as e:
                rospy.logwarn(e)
                self._widget.kbStatusLabel.setText("Error: ".format(str(e)))

        initial_update_thread = threading.Thread(target=run_kb_update)
        initial_update_thread.start()