def _add_children_treenode(self, treenodeitem_toplevel, treenodeitem_parent, child_names_left): """ Evaluate current treenode and the previous treenode at the same depth. If the name of both nodes is the same, current node instance is ignored (that means children will be added to the same parent). If not, the current node gets added to the same parent node. At the end, this function gets called recursively going 1 level deeper. :type treenodeitem_toplevel: TreenodeQstdItem :type treenodeitem_parent: TreenodeQstdItem. :type child_names_left: List of str :param child_names_left: List of strings that is sorted in hierarchical order of params. """ # TODO(Isaac): Consider moving this method to rqt_py_common. name_currentnode = child_names_left.pop(0) grn_curr = treenodeitem_toplevel.get_raw_param_name() stditem_currentnode = TreenodeQstdItem(grn_curr, TreenodeQstdItem.NODE_FULLPATH) # item at the bottom is your most recent node. row_index_parent = treenodeitem_parent.rowCount() - 1 # Obtain and instantiate prev node in the same depth. name_prev = '' stditem_prev = None if treenodeitem_parent.child(row_index_parent): stditem_prev = treenodeitem_parent.child(row_index_parent) name_prev = stditem_prev.text() stditem = None # If the name of both nodes is the same, current node instance is # ignored (that means children will be added to the same parent) if name_prev != name_currentnode: stditem_currentnode.setText(name_currentnode) # Arrange alphabetically by display name insert_index = 0 while insert_index < treenodeitem_parent.rowCount( ) and treenodeitem_parent.child( insert_index).text() < name_currentnode: insert_index += 1 treenodeitem_parent.insertRow(insert_index, stditem_currentnode) stditem = stditem_currentnode else: stditem = stditem_prev if child_names_left: # TODO: Model is closely bound to a certain type of view (treeview) # here. Ideally isolate those two. Maybe we should split into 2 # class, 1 handles view, the other does model. self._add_children_treenode(treenodeitem_toplevel, stditem, child_names_left) else: # Selectable ROS Node. #TODO: Accept even non-terminal treenode as long as it's ROS Node. self._item_model.set_item_from_index(grn_curr, stditem.index())
def _update_nodetree_pernode(self): """ """ # TODO(Isaac): 11/25/2012 dynamic_reconfigure only returns params that # are associated with nodes. In order to handle independent # params, different approach needs taken. try: nodes = dyn_reconf.find_reconfigure_services() except rosservice.ROSServiceIOException as e: rospy.logerr("Reconfigure GUI cannot connect to master.") raise e # TODO Make sure 'raise' here returns or finalizes func. if not nodes == self._nodes_previous: i_node_curr = 1 num_nodes = len(nodes) elapsedtime_overall = 0.0 for node_name_grn in nodes: time_siglenode_loop = time.time() ####(Begin) For DEBUG ONLY; skip some dynreconf creation # if i_node_curr % 2 != 0: # i_node_curr += 1 # continue #### (End) For DEBUG ONLY. #### # Instantiate QStandardItem. Inside, dyn_reconf client will # be generated too. treenodeitem_toplevel = TreenodeQstdItem( node_name_grn, TreenodeQstdItem.NODE_FULLPATH) _treenode_names = treenodeitem_toplevel.get_treenode_names() try: treenodeitem_toplevel.connect_param_server() except rospy.exceptions.ROSException as e: rospy.logerr(e.message) #Skip item that fails to connect to its node. continue #TODO: Needs to show err msg on GUI too. # Using OrderedDict here is a workaround for StdItemModel # not returning corresponding item to index. self._nodeitems[node_name_grn] = treenodeitem_toplevel self._add_children_treenode(treenodeitem_toplevel, self._rootitem, _treenode_names) time_siglenode_loop = time.time() - time_siglenode_loop elapsedtime_overall += time_siglenode_loop _str_progress = 'reconf ' + \ 'loading #{}/{} {} / {}sec node={}'.format( i_node_curr, num_nodes, round(time_siglenode_loop, 2), round(elapsedtime_overall, 2), node_name_grn) # NOT a debug print - please DO NOT remove. This print works # as progress notification when loading takes long time. rospy.logdebug(_str_progress) i_node_curr += 1
def _update_nodetree_pernode(self): # TODO(Isaac): 11/25/2012 dynamic_reconfigure only returns params that # are associated with nodes. In order to handle independent # params, different approach needs taken. try: nodes = find_nodes_with_params(self._context.node) except Exception as e: self._logger.error(e) # TODO: print to sysmsg pane raise e # TODO Make sure 'raise' here returns or finalizes func. if not nodes == self._nodes_previous: i_node_curr = 1 num_nodes = len(nodes) elapsedtime_overall = 0.0 for node_name_grn in nodes: # Skip this grn if we already have it if node_name_grn in self._nodeitems: i_node_curr += 1 continue time_siglenode_loop = time.time() # (Begin) For DEBUG ONLY; skip some dynreconf creation # if i_node_curr % 2 != 0: # i_node_curr += 1 # continue # (End) For DEBUG ONLY. #### # Instantiate QStandardItem. Inside, dyn_reconf client will # be generated too. treenodeitem_toplevel = TreenodeQstdItem( self._context, node_name_grn, TreenodeQstdItem.NODE_FULLPATH) _treenode_names = treenodeitem_toplevel.get_treenode_names() # Using OrderedDict here is a workaround for StdItemModel # not returning corresponding item to index. self._nodeitems[node_name_grn] = treenodeitem_toplevel self._add_children_treenode(treenodeitem_toplevel, self._rootitem, _treenode_names) time_siglenode_loop = time.time() - time_siglenode_loop elapsedtime_overall += time_siglenode_loop _str_progress = 'reconf ' + \ 'loading #{}/{} {} / {}sec node={}'.format( i_node_curr, num_nodes, round(time_siglenode_loop, 2), round(elapsedtime_overall, 2), node_name_grn ) # NOT a debug print - please DO NOT remove. This print works # as progress notification when loading takes long time. logging.debug(_str_progress) i_node_curr += 1
def _add_children_treenode(self, treenodeitem_toplevel, treenodeitem_parent, child_names_left): """ Evaluate current treenode and the previous treenode at the same depth. If the name of both nodes is the same, current node instance is ignored (that means children will be added to the same parent). If not, the current node gets added to the same parent node. At the end, this function gets called recursively going 1 level deeper. :type treenodeitem_toplevel: TreenodeQstdItem :type treenodeitem_parent: TreenodeQstdItem. :type child_names_left: List of str :param child_names_left: List of strings that is sorted in hierarchical order of params. """ # TODO(Isaac): Consider moving this method to rqt_py_common. name_currentnode = child_names_left.pop(0) grn_curr = treenodeitem_toplevel.get_raw_param_name() stditem_currentnode = TreenodeQstdItem(grn_curr, TreenodeQstdItem.NODE_FULLPATH) # item at the bottom is your most recent node. row_index_parent = treenodeitem_parent.rowCount() - 1 # Obtain and instantiate prev node in the same depth. name_prev = '' stditem_prev = None if treenodeitem_parent.child(row_index_parent): stditem_prev = treenodeitem_parent.child(row_index_parent) name_prev = stditem_prev.text() stditem = None # If the name of both nodes is the same, current node instance is # ignored (that means children will be added to the same parent) if name_prev != name_currentnode: stditem_currentnode.setText(name_currentnode) # Arrange alphabetically by display name insert_index = 0 while insert_index < treenodeitem_parent.rowCount() and treenodeitem_parent.child(insert_index).text() < name_currentnode: insert_index += 1 treenodeitem_parent.insertRow(insert_index, stditem_currentnode) stditem = stditem_currentnode else: stditem = stditem_prev if child_names_left: # TODO: Model is closely bound to a certain type of view (treeview) # here. Ideally isolate those two. Maybe we should split into 2 # class, 1 handles view, the other does model. self._add_children_treenode(treenodeitem_toplevel, stditem, child_names_left) else: # Selectable ROS Node. #TODO: Accept even non-terminal treenode as long as it's ROS Node. self._item_model.set_item_from_index(grn_curr, stditem.index())
class TestTreenodeQstdItem(unittest.TestCase): """ :author: Isaac Saito """ _nodename_raw = "/base_hokuyo_node" _nodename_extracted = "base_hokuyo_node" def setUp(self): unittest.TestCase.setUp(self) # self._item = TreenodeQstdItem(self._nodename_raw, 0) # For unknown reason # this stops operation. self._item = TreenodeQstdItem(self._nodename_raw) def tearDown(self): unittest.TestCase.tearDown(self) del self._item def test_get_node_name(self): self.assertEqual(self._item.get_node_name(), self._nodename_extracted)
class TestTreenodeQstdItem(unittest.TestCase): """ :author: Isaac Saito """ _nodename_raw = '/base_hokuyo_node' _nodename_extracted = 'base_hokuyo_node' def setUp(self): unittest.TestCase.setUp(self) # For unknown reason this stops operation. # self._item = TreenodeQstdItem(self._nodename_raw, 0) self._item = TreenodeQstdItem(self._nodename_raw) def tearDown(self): unittest.TestCase.tearDown(self) del self._item def test_get_node_name(self): self.assertEqual(self._item.get_node_name(), self._nodename_extracted)
def setUp(self): unittest.TestCase.setUp(self) # self._item = TreenodeQstdItem(self._nodename_raw, 0) # For unknown reason # this stops operation. self._item = TreenodeQstdItem(self._nodename_raw)
def setUp(self): unittest.TestCase.setUp(self) # For unknown reason this stops operation. # self._item = TreenodeQstdItem(self._nodename_raw, 0) self._item = TreenodeQstdItem(self._nodename_raw)