def test_blind_branch() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac4) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append(LogicItem(ac1.id, ac3.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac4.id)) project.logic.append(LogicItem(ac4.id, LogicItem.END)) with pytest.raises(SourceException, match=f"Action {ac3.name} has no outputs."): program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene))
def test_constant() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) const_value = 1234 const = ProjectParameter("int_const", "integer", json.dumps(const_value)) project.parameters.append(const) ac1 = Action( "ac1", f"{obj.id}/test_par", flows=[Flow()], parameters=[ ActionParameter("param", ActionParameter.TypeEnum.CONSTANT, json.dumps(const.id)) ], ) ap1.actions.append(ac1) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) assert f"{const.name} = {const_value}" in src assert f"test_name.{Test.test_par.__name__}({const.name}, an='ac1')" in src
def test_prev_result() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/{Test.get_int.__name__}", flows=[Flow(outputs=["res"])]) ap1.actions.append(ac1) ac2 = Action( "ac2", f"{obj.id}/{Test.test_par.__name__}", flows=[Flow()], parameters=[ ActionParameter("param", ActionParameter.TypeEnum.LINK, json.dumps(f"{ac1.id}/default/0")) ], ) ap1.actions.append(ac2) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, ac2.id)) project.logic.append(LogicItem(ac2.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) assert f"res = test_name.{Test.get_int.__name__}(an='{ac1.name}')" in src assert f"test_name.{Test.test_par.__name__}(res, an='{ac2.name}')" in src # test wrong order of logic project.logic.clear() project.logic.append(LogicItem(LogicItem.START, ac2.id)) project.logic.append(LogicItem(ac2.id, ac1.id)) project.logic.append(LogicItem(ac1.id, LogicItem.END)) with pytest.raises(SourceException): program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene))
def test_branched_output_2() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow(outputs=["bool2_res"])]) ap1.actions.append(ac4) ac5 = Action("ac5", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac5) ac6 = Action("ac6", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac6) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append( LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append( LogicItem(ac1.id, ac4.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac3.id)) project.logic.append(LogicItem(ac3.id, ac6.id)) project.logic.append( LogicItem(ac4.id, ac5.id, ProjectLogicIf(f"{ac4.id}/default/0", json.dumps(True)))) project.logic.append(LogicItem(ac5.id, ac6.id)) project.logic.append(LogicItem(ac6.id, LogicItem.END)) project.logic.append( LogicItem(ac4.id, LogicItem.END, ProjectLogicIf(f"{ac4.id}/default/0", json.dumps(False)))) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) parse(src) """ bool_res = test_name.test(res.ac1) if (bool_res == False): bool2_res = test_name.test(res.ac4) if (bool2_res == False): continue elif (bool2_res == True): test_name.test(res.ac5) elif (bool_res == True): test_name.test(res.ac2) test_name.test(res.ac3) test_name.test(res.ac6) """ spl = src.splitlines() # it has to be robust against changed order of blocks ac1_idx = subs_index(spl, "bool_res = test_name.test(an='ac1')") if_bool_res_false_idx = subs_index(spl, "if (bool_res == False):") assert if_bool_res_false_idx > ac1_idx assert cntsp(spl[ac1_idx]) == cntsp(spl[if_bool_res_false_idx]) bool2_res_idx = subs_index(spl, "bool2_res = test_name.test(an='ac4')") assert bool2_res_idx > if_bool_res_false_idx assert cntsp(spl[if_bool_res_false_idx]) == cntsp(spl[bool2_res_idx]) - TAB if_bool_2_res_false_idx = subs_index(spl, "if (bool2_res == False):") assert cntsp(spl[if_bool_2_res_false_idx]) == cntsp(spl[bool2_res_idx]) assert if_bool_2_res_false_idx > bool2_res_idx assert "continue" in spl[if_bool_2_res_false_idx + 1] assert cntsp( spl[bool2_res_idx]) == cntsp(spl[if_bool_2_res_false_idx + 1]) - TAB if_bool_2_res_true_idx = subs_index(spl, "if (bool2_res == True):") assert if_bool_2_res_true_idx > bool2_res_idx assert "test_name.test(an='ac5')" in spl[if_bool_2_res_true_idx + 1] assert cntsp(spl[if_bool_2_res_true_idx]) == cntsp( spl[if_bool_2_res_true_idx + 1]) - TAB if_bool_res_true_idx = subs_index(spl, "if (bool_res == True):") assert if_bool_res_true_idx > ac1_idx assert cntsp(spl[ac1_idx]) == cntsp(spl[if_bool_res_true_idx]) assert "test_name.test(an='ac2')" in spl[if_bool_res_true_idx + 1] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 1]) - TAB assert "test_name.test(an='ac3')" in spl[if_bool_res_true_idx + 2] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 2]) - TAB ac6_idx = subs_index(spl, "test_name.test(an='ac6')") assert cntsp(spl[ac1_idx]) == cntsp(spl[ac6_idx]) assert ac6_idx > if_bool_2_res_false_idx assert ac6_idx > if_bool_2_res_true_idx
def test_object_parameters(start_processes: None, ars: ARServer, scene: Scene) -> None: assert ars.call_rpc(rpc.s.OpenScene.Request(uid(), IdArgs(scene.id)), rpc.s.OpenScene.Response).result event(ars, events.s.OpenScene) assert ars.call_rpc( rpc.s.AddObjectToScene.Request( uid(), rpc.s.AddObjectToScene.Request.Args("ows", ObjectWithActions.__name__)), rpc.s.AddObjectToScene.Response, ).result obj = event(ars, events.s.SceneObjectChanged).data assert obj is not None assert ars.call_rpc( rpc.p.NewProject.Request( uid(), rpc.p.NewProject.Request.Args(scene.id, "Project name")), rpc.p.NewProject.Response, ).result event(ars, events.p.OpenProject) assert ars.call_rpc( rpc.p.AddActionPoint.Request( uid(), rpc.p.AddActionPoint.Request.Args("ap", Position())), rpc.p.AddActionPoint.Response, ).result ap = event(ars, events.p.ActionPointChanged).data assert ap is not None assert ars.call_rpc( rpc.p.AddAction.Request( uid(), rpc.p.AddAction.Request.Args( ap.id, "a1", f"{obj.id}/{ObjectWithActions.bool_action.__name__}", [], [Flow(outputs=["bool_result"])], ), ), rpc.p.AddAction.Response, ).result a1 = event(ars, events.p.ActionChanged).data assert a1 is not None assert ars.call_rpc( rpc.p.AddAction.Request( uid(), rpc.p.AddAction.Request.Args( ap.id, "a2", f"{obj.id}/{ObjectWithActions.str_action.__name__}", [], [Flow()], ), ), rpc.p.AddAction.Response, ).result a2 = event(ars, events.p.ActionChanged).data assert a2 is not None add_logic_item(ars, LogicItem.START, a1.id) add_logic_item( ars, a1.id, a2.id, ProjectLogicIf(f"{a1.id}/{FlowTypes.DEFAULT}/{0}", json.dumps(True))) add_logic_item(ars, a2.id, LogicItem.END) add_logic_item( ars, a1.id, LogicItem.END, ProjectLogicIf(f"{a1.id}/{FlowTypes.DEFAULT}/{0}", json.dumps(False))) # TODO try to add some invalid connections here? save_project(ars)
from arcor2.data.common import ( Action, ActionPoint, Flow, LogicItem, Position, Project, ProjectLogicIf, Scene, SceneObject, ) from arcor2.exceptions import Arcor2Exception from arcor2.logic import check_for_loops obj = SceneObject("test_name", "Test") ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow()]) @pytest.fixture() def scene() -> Scene: scene = Scene("s1", "s1") scene.objects.append(obj) return scene @pytest.fixture() def project() -> UpdateableCachedProject:
def test_branched_output() -> None: scene = Scene("s1") obj = SceneObject("test_name", "Test") scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac4) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append( LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append( LogicItem(ac1.id, ac3.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac4.id)) project.logic.append(LogicItem(ac3.id, ac4.id)) project.logic.append(LogicItem(ac4.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) parse(src) """ bool_res = test_name.test(res.ac1) if bool_res == False: test_name.test(res.ac3) elif bool_res == True: test_name.test(res.ac2) test_name.test(res.ac4) """ spl = src.splitlines() ac1_idx = subs_index(spl, "bool_res = test_name.test(an='ac1')") if_bool_res_false_idx = subs_index(spl, "if bool_res == False:") assert if_bool_res_false_idx > ac1_idx assert cntsp(spl[if_bool_res_false_idx]) == cntsp(spl[ac1_idx]) assert "test_name.test(an='ac3')" in spl[if_bool_res_false_idx + 1] assert cntsp(spl[if_bool_res_false_idx]) == cntsp( spl[if_bool_res_false_idx + 1]) - TAB if_bool_res_true_idx = subs_index(spl, "if bool_res == True:") assert if_bool_res_true_idx > ac1_idx assert cntsp(spl[if_bool_res_true_idx]) == cntsp(spl[ac1_idx]) assert "test_name.test(an='ac2')" in spl[if_bool_res_true_idx + 1] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 1]) - TAB ac4_idx = subs_index(spl, "test_name.test(an='ac4')") assert ac4_idx > if_bool_res_false_idx assert ac4_idx > if_bool_res_true_idx assert cntsp(spl[ac4_idx]) == cntsp(spl[ac1_idx])
def test_project_ap_rpcs(start_processes: None, ars: ARServer) -> None: upload_def(Box, BoxModel(Box.__name__, 1, 2, 3)) event(ars, events.c.ShowMainScreen) assert ars.call_rpc( rpc.s.NewScene.Request(get_id(), rpc.s.NewScene.Request.Args("Test scene")), rpc.s.NewScene.Response ).result assert len(event(ars, events.o.ChangedObjectTypes).data) == 1 scene_data = event(ars, events.s.OpenScene).data assert scene_data scene = scene_data.scene event(ars, events.s.SceneState) assert ars.call_rpc( rpc.s.AddObjectToScene.Request(get_id(), rpc.s.AddObjectToScene.Request.Args("box", Box.__name__, Pose())), rpc.s.AddObjectToScene.Response, ).result obj = event(ars, events.s.SceneObjectChanged).data assert obj # ------------------------------------------------------------------------------------------------------------------ assert ars.call_rpc( rpc.p.NewProject.Request(get_id(), rpc.p.NewProject.Request.Args(scene.id, "Project name")), rpc.p.NewProject.Response, ).result event(ars, events.s.SceneSaved) event(ars, events.p.OpenProject) event(ars, events.s.SceneState) assert ars.call_rpc( rpc.p.AddActionPoint.Request(get_id(), rpc.p.AddActionPoint.Request.Args("parent_ap", Position())), rpc.p.AddActionPoint.Response, ).result parent_ap_evt = event(ars, events.p.ActionPointChanged) assert ars.call_rpc( rpc.p.AddActionPoint.Request( get_id(), rpc.p.AddActionPoint.Request.Args("child_ap", Position(-1), parent_ap_evt.data.id) ), rpc.p.AddActionPoint.Response, ).result child_ap_evt = event(ars, events.p.ActionPointChanged) assert child_ap_evt.data.parent == parent_ap_evt.data.id lock_object(ars, child_ap_evt.data.id) assert ars.call_rpc( rpc.p.AddActionPointOrientation.Request( get_id(), rpc.p.AddActionPointOrientation.Request.Args(child_ap_evt.data.id, Orientation()) ), rpc.p.AddActionPointOrientation.Response, ).result ori = event(ars, events.p.OrientationChanged) assert ars.call_rpc( rpc.p.AddAction.Request( get_id(), rpc.p.AddAction.Request.Args( child_ap_evt.data.id, "act_name", f"{obj.id}/{Box.update_pose.__name__}", [ActionParameter("new_pose", PosePlugin.type_name(), json.dumps(ori.data.id))], [Flow()], ), ), rpc.p.AddAction.Response, ).result event(ars, events.p.ActionChanged) unlock_object(ars, child_ap_evt.data.id) ars.event_mapping[ActionChanged.__name__] = ActionChanged assert ars.call_rpc( rpc.p.CopyActionPoint.Request(get_id(), rpc.p.CopyActionPoint.Request.Args(parent_ap_evt.data.id)), rpc.p.CopyActionPoint.Response, ).result new_parent_ap = event(ars, events.p.ActionPointChanged) assert not new_parent_ap.data.parent new_child_ap = event(ars, events.p.ActionPointChanged) assert new_child_ap.data.parent == new_parent_ap.data.id new_ori = event(ars, events.p.OrientationChanged) assert new_ori.parent_id == new_child_ap.data.id # with events.p.ActionChanged it would return only BareAction (without parameters) new_action = event(ars, ActionChanged) ars.event_mapping[ActionChanged.__name__] = events.p.ActionChanged assert new_action.parent_id == new_child_ap.data.id # Pose parameter (orientation id) should be updated now assert len(new_action.data.parameters) == 1 assert json.loads(new_action.data.parameters[0].value) == new_ori.data.id