diff --git a/bt_view/src/bt_view/bt_view.py b/bt_view/src/bt_view/bt_view.py index 54eae5c..fe40339 100644 --- a/bt_view/src/bt_view/bt_view.py +++ b/bt_view/src/bt_view/bt_view.py @@ -198,7 +198,7 @@ def _make_history_image( def draw_pygraphviz( g: nx.Graph, fname: str, - modifier, + modifier: Optional[callable] = None, ): A = nx.nx_agraph.to_agraph(g) # convert to a graphviz graph for node in A.nodes(): diff --git a/bt_view/src/bt_view/main.py b/bt_view/src/bt_view/main.py index f3f4014..c12309b 100755 --- a/bt_view/src/bt_view/main.py +++ b/bt_view/src/bt_view/main.py @@ -20,10 +20,12 @@ import sys try: + from bt_view import draw_pygraphviz # type: ignore from bt_view import draw_pygraphviz_w_history # type: ignore from bt_view import draw_pygraphviz_w_returnstates # type: ignore from bt_view import draw_pygraphviz_w_valuemod # type: ignore except ImportError: + from .bt_view import draw_pygraphviz from .bt_view import draw_pygraphviz_w_history from .bt_view import draw_pygraphviz_w_returnstates from .bt_view import draw_pygraphviz_w_valuemod @@ -76,7 +78,7 @@ def main(args=sys.argv[1:]): parser.print_help() sys.exit(1) - if arguments.bt_xml_fname and arguments.bt_log_fbl_fname: + if arguments.bt_xml_fname and arguments.bt_log_fbl_fnames: print('When reading FBL log file, XML file is not needed ' 'and will be ignored') arguments.bt_xml_fname = None @@ -93,6 +95,7 @@ def main(args=sys.argv[1:]): g, _ = xml_to_networkx(bt_xml_fname) # if arguments.assemble_subtrees: # g, xpi = assemble_subtrees(g, xpi) + draw_pygraphviz(g, os.path.splitext(bt_xml_fname)[0]) # read fbl log file if arguments.bt_log_fbl_fnames: diff --git a/bt_view/test/_test_data/behavior_tree.xml b/bt_view/test/_test_data/behavior_tree.xml new file mode 100644 index 0000000..a45573d --- /dev/null +++ b/bt_view/test/_test_data/behavior_tree.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/bt_view/test/_test_data/reference/behavior_tree.png b/bt_view/test/_test_data/reference/behavior_tree.png new file mode 100644 index 0000000..6ed2ddf Binary files /dev/null and b/bt_view/test/_test_data/reference/behavior_tree.png differ diff --git a/bt_view/test/_test_data/reference/behavior_tree.svg b/bt_view/test/_test_data/reference/behavior_tree.svg new file mode 100644 index 0000000..77d517d --- /dev/null +++ b/bt_view/test/_test_data/reference/behavior_tree.svg @@ -0,0 +1,92 @@ + + + + + + + + + +10 + +BehaviorTree +ID: MainTree +category: NODECAT.ROOT +root: True + + + +100 + +Sequence +category: NODECAT.CONTROL +name: root_sequence + + + +10->100 + + + + + +1000 + +SaySomething +category: NODECAT.ACTION +message: Hello +name: action_hello + + + +100->1000 + + + + + +1001 + +OpenGripper +category: NODECAT.ACTION +name: open_gripper + + + +100->1001 + + + + + +1002 + +ApproachObject +category: NODECAT.ACTION +name: approach_object + + + +100->1002 + + + + + +1003 + +CloseGripper +category: NODECAT.ACTION +name: close_gripper + + + +100->1003 + + + + + diff --git a/bt_view/test/systemtests/test_bt_view_main.py b/bt_view/test/systemtests/test_bt_view_main.py index 509ea1e..0ef2957 100644 --- a/bt_view/test/systemtests/test_bt_view_main.py +++ b/bt_view/test/systemtests/test_bt_view_main.py @@ -82,7 +82,7 @@ def test_bt_view_main_single_fbl(self): fname = os.path.join( TEST_DATA_DIR, f'bt_trace{no}_fbl_log_{data}.svg') # load svg file - with open(fname, 'r') as f: + with open(fname, 'r', encoding='utf-8') as f: svg = f.read() svg_hashes_fbl[fname] = hash(svg) self._check_svg_for_nodenames(svg) @@ -230,14 +230,14 @@ def test_bt_view_main_multiple_fbl_files_merge(self): fname = os.path.join( TEST_DATA_DIR, f'bt_trace{no}_fbl_log_{data}.svg') # load svg file - with open(fname, 'r') as f: + with open(fname, 'r', encoding='utf-8') as f: svg = f.read() svg_hashes_fbl[fname] = hash(svg) self._check_svg_for_nodenames(svg) # also hash the combined svg files for fname in fnames_combined_svg: - with open(fname, 'r') as f: + with open(fname, 'r', encoding='utf-8') as f: svg = f.read() svg_hashes_fbl[fname] = hash(svg) self._check_svg_for_nodenames(svg) @@ -273,3 +273,32 @@ def test_bt_view_main_coverage(self): main(['--bt_log_fbl_fname', fname_2, '--coverage-threshold', '0.8']) self.assertEqual(cm.exception.code, 1) + + def test_bt_view_main_xml(self): + """Test if the correct images are created for XML input.""" + base_name: str = 'behavior_tree' + xml_fname = os.path.join( + TEST_DATA_DIR, + f'{base_name}.xml') + main(['--bt_xml_fname', xml_fname]) + + # make sure the files have been created + for ext in self.img_exts: + fname = os.path.join( + TEST_DATA_DIR, f'{base_name}.{ext}') + self.assertTrue(os.path.isfile(fname)) + + # make sure they match the reference + for ext in self.img_exts: + with open(os.path.join( + TEST_DATA_DIR, + f'{base_name}.{ext}' + ), 'rb') as f: + out = f.read() + with open(os.path.join( + TEST_DATA_DIR, + 'reference', + f'{base_name}.{ext}' + ), 'rb') as f: + ref = f.read() + self.assertEqual(out, ref)