diff --git a/tools/rostopic/src/rostopic/__init__.py b/tools/rostopic/src/rostopic/__init__.py index 4cc43e89bb..a903b68664 100644 --- a/tools/rostopic/src/rostopic/__init__.py +++ b/tools/rostopic/src/rostopic/__init__.py @@ -1121,42 +1121,60 @@ def _rostopic_list_bag(bag_file, topic=None): break def _sub_rostopic_list(master, pubs, subs, publishers_only, subscribers_only, verbose, indent=''): - def topic_type(t, topic_types): - matches = [t_type for t_name, t_type in topic_types if t_name == t] - if matches: - return matches[0] - return 'unknown type' - if verbose: topic_types = _master_get_topic_types(master) if not subscribers_only: print("\n%sPublished topics:"%indent) - for t, l in pubs: - if len(l) > 1: - print(indent+" * %s [%s] %s publishers"%(t, topic_type(t, topic_types), len(l))) + for t, ttype, tlist in pubs: + if len(tlist) > 1: + print(indent+" * %s [%s] %s publishers"%(t, ttype, len(tlist))) else: - print(indent+" * %s [%s] 1 publisher"%(t, topic_type(t, topic_types))) + print(indent+" * %s [%s] 1 publisher"%(t, ttype)) if not publishers_only: print(indent) print(indent+"Subscribed topics:") - for t,l in subs: - if len(l) > 1: - print(indent+" * %s [%s] %s subscribers"%(t, topic_type(t, topic_types), len(l))) + for t, ttype, tlist in subs: + if len(tlist) > 1: + print(indent+" * %s [%s] %s subscribers"%(t, ttype, len(llist))) else: - print(indent+" * %s [%s] 1 subscriber"%(t, topic_type(t, topic_types))) + print(indent+" * %s [%s] 1 subscriber"%(t, ttype)) print('') else: if publishers_only: - topics = [t for t,_ in pubs] + topics = [t for t, _, _ in pubs] elif subscribers_only: - topics = [t for t,_ in subs] + topics = [t for t, _, _ in subs] else: - topics = list(set([t for t,_ in pubs] + [t for t,_ in subs])) + topics = list(set([t for t, _, _ in pubs] + [t for t, _, _ in subs])) topics.sort() print('\n'.join(["%s%s"%(indent, t) for t in topics])) +def get_topic_list(master=None): + if not master: + master = rosgraph.Master('/rostopic') + def topic_type(t, topic_types): + matches = [t_type for t_name, t_type in topic_types if t_name == t] + if matches: + return matches[0] + return 'unknown type' + + # Return an array of tuples; (, , ) + state = master.getSystemState() + topic_types = _master_get_topic_types(master) + + pubs, subs, _ = state + pubs_out = [] + for topic, nodes in pubs: + pubs_out.append((topic, topic_type(topic, topic_types), nodes)) + subs_out = [] + for topic, nodes in subs: + subs_out.append((topic, topic_type(topic, topic_types), nodes)) + + # List of published topics, list of subscribed topics. + return (pubs_out, subs_out) + # #3145 def _rostopic_list_group_by_host(master, pubs, subs): """ @@ -1165,7 +1183,7 @@ def _rostopic_list_group_by_host(master, pubs, subs): """ def build_map(master, state, uricache): tmap = {} - for topic, tnodes in state: + for topic, ttype, tnodes in state: for p in tnodes: if not p in uricache: uricache[p] = master.lookupNode(p) @@ -1204,15 +1222,11 @@ def _rostopic_list(topic, verbose=False, master = rosgraph.Master('/rostopic') try: - state = master.getSystemState() - - pubs, subs, _ = state + pubs, subs = get_topic_list(master=master) if topic: - # filter based on topic - topic_ns = rosgraph.names.make_global_ns(topic) + topic_ns = rosgraph.names.make_global_ns(topic) subs = (x for x in subs if x[0] == topic or x[0].startswith(topic_ns)) pubs = (x for x in pubs if x[0] == topic or x[0].startswith(topic_ns)) - except socket.error: raise ROSTopicIOException("Unable to communicate with master!") @@ -1251,9 +1265,7 @@ def topic_type(t, topic_types): master = rosgraph.Master('/rostopic') try: - state = master.getSystemState() - - pubs, subs, _ = state + pubs, subs = get_topic_list(master=master) # filter based on topic subs = [x for x in subs if x[0] == topic] pubs = [x for x in pubs if x[0] == topic] @@ -1270,7 +1282,7 @@ def topic_type(t, topic_types): if pubs: buff.write("Publishers: \n") - for p in itertools.chain(*[l for x, l in pubs]): + for p in itertools.chain(*[nodes for topic, ttype, nodes in pubs]): buff.write(" * %s (%s)\n"%(p, get_api(master, p))) else: buff.write("Publishers: None\n") @@ -1278,7 +1290,7 @@ def topic_type(t, topic_types): if subs: buff.write("Subscribers: \n") - for p in itertools.chain(*[l for x, l in subs]): + for p in itertools.chain(*[nodes for topic, ttype, nodes in subs]): buff.write(" * %s (%s)\n"%(p, get_api(master, p))) else: buff.write("Subscribers: None\n") diff --git a/tools/rostopic/test/test_rostopic.py b/tools/rostopic/test/test_rostopic.py index 388bedd1f8..33da321cdf 100644 --- a/tools/rostopic/test/test_rostopic.py +++ b/tools/rostopic/test/test_rostopic.py @@ -281,7 +281,7 @@ def test_cmd_list(self): # test main entry rostopic.rostopicmain([cmd, 'list']) - # test directly + # test through running command topics = ['/chatter', '/foo/chatter', '/bar/chatter', '/rosout', '/rosout_agg'] with fakestdout() as b: @@ -289,6 +289,12 @@ def test_cmd_list(self): v = [x.strip() for x in b.getvalue().split('\n') if x.strip()] self.failIf(set(topics)-set(v)) + # test through public function + topics = ['/chatter', '/foo/chatter', '/bar/chatter', '/rosout', '/rosout_agg'] + + v = rostopic.get_topic_list() + self.failIf(set(topics)-set(v)) + # publishers-only topics = ['/chatter', '/foo/chatter', '/bar/chatter', '/rosout', '/rosout_agg'] with fakestdout() as b: