Skip to content

Commit

Permalink
Fix handling of namespaces in the node tree
Browse files Browse the repository at this point in the history
- Fix grouping of nodes by namespace
- Fix treenode removal; remove only the treenode that stopped running, and not
all nodes under its corresponding namespace

Signed-off-by: Nick Lamprianidis <[email protected]>
  • Loading branch information
nlamprian committed Aug 27, 2023
1 parent b51243e commit 3e6a356
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 15 deletions.
65 changes: 51 additions & 14 deletions src/rqt_reconfigure/node_selector_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,9 @@ def _add_children_treenode(self, treenodeitem_toplevel,
function gets called recursively going 1 level deeper.
:type treenodeitem_toplevel: TreenodeQstdItem
:type treenodeitem_parent: 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.
:param child_names_left: List of strings that is sorted in hierarchical order.
"""
# TODO(Isaac): Consider moving this method to rqt_py_common.

Expand All @@ -388,8 +387,13 @@ def _add_children_treenode(self, treenodeitem_toplevel,
stditem_currentnode = TreenodeQstdItem(self._context, grn_curr,
TreenodeQstdItem.NODE_FULLPATH)

# item at the bottom is your most recent node.
row_index_parent = treenodeitem_parent.rowCount() - 1
for i in range(treenodeitem_parent.rowCount()):
if treenodeitem_parent.child(i).text() == name_currentnode:
row_index_parent = i
break
else:
# 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 = ''
Expand Down Expand Up @@ -425,22 +429,55 @@ def _add_children_treenode(self, treenodeitem_toplevel,
# 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 _remove_children_treenode(self, treenodeitem_toplevel,
treenodeitem_parent, child_names_left):
"""
Remove child treenode.
: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.
"""
name_currentnode = child_names_left.pop(0)

for i in range(treenodeitem_parent.rowCount()):
if treenodeitem_parent.child(i).text() == name_currentnode:
row_index_parent = i
break
else:
grn_curr = treenodeitem_toplevel.get_raw_param_name()
raise RuntimeError(
f'Failed to remove node {grn_curr}: No treenode {name_currentnode}')

if not child_names_left: # Leaf node
treenodeitem_parent.removeRow(row_index_parent)
return

self._remove_children_treenode(treenodeitem_toplevel,
treenodeitem_parent.child(row_index_parent),
child_names_left)

# After a child has been removed, if none is left, remove the parent as well
if treenodeitem_parent.child(row_index_parent).rowCount() == 0:
treenodeitem_parent.removeRow(row_index_parent)

def _prune_nodetree_pernode(self):
try:
nodes = find_nodes_with_params(self._context.node)
except Exception as e:
logging.error('Reconfigure GUI cannot connect to master.')
raise e # TODO Make sure 'raise' here returns or finalizes func.

for i in reversed(range(0, self._rootitem.rowCount())):
candidate_for_removal = \
self._rootitem.child(i).get_raw_param_name()
if candidate_for_removal not in nodes:
logging.debug(
'Removing {} because the server is no longer available.'.
format(candidate_for_removal))
self._rootitem.removeRow(i)
self._nodeitems.pop(candidate_for_removal).reset()
for candidate_for_removal in list(self._nodeitems.keys()):
if candidate_for_removal in nodes:
continue
logging.debug(f'Removing {candidate_for_removal} because '
'the server is no longer available.')
treenode = self._nodeitems[candidate_for_removal]
treenode_names = treenode.get_treenode_names()
self._remove_children_treenode(treenode, self._rootitem, treenode_names)
self._nodeitems.pop(candidate_for_removal).reset()

def _refresh_nodes(self):
self._prune_nodetree_pernode()
Expand Down
4 changes: 3 additions & 1 deletion src/rqt_reconfigure/treenode_qstditem.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

from __future__ import division

import copy

from python_qt_binding.QtCore import Qt
from python_qt_binding.QtGui import QBrush, QStandardItem

Expand Down Expand Up @@ -129,7 +131,7 @@ def get_treenode_names(self):
:rtype: List of string. Null if param
"""
return self._list_treenode_names
return copy.copy(self._list_treenode_names)

def get_node_name(self):
"""
Expand Down

0 comments on commit 3e6a356

Please sign in to comment.