def test_get_value() -> None: p = Pose(Position(1, 2, 3), Orientation(1, 0, 0, 0)) scene = Scene("s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) project.action_points.append(ap1) ap2 = ActionPoint("ap2", Position(), parent=ap1.id) project.action_points.append(ap2) ori1 = NamedOrientation("ori1", p.orientation) ap2.orientations.append(ori1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, PosePlugin.type_name(), json.dumps(ori1.id)), ActionParameter(invalid_param_name, PosePlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): PosePlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, invalid_param_name) value = PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, param_name) exe_value = PosePlugin.parameter_execution_value(type_defs, cscene, cproject, ac1.id, param_name) assert value == value assert value != exe_value
async def get_scene(scene_id: str) -> CachedScene: async with _scenes_list_lock: try: scene = _scenes[scene_id] assert scene.modified except KeyError: scene = CachedScene(await ps.get_scene(scene_id)) _scenes[scene_id] = scene else: await _update_list(ps.get_scenes, _scenes_list, _scenes) if scene_id not in _scenes_list.listing: _scenes.pop(scene_id, None) raise Arcor2Exception("Scene removed externally.") # scene in cache is outdated if scene.modified < _scenes_list.listing[scene_id].modified: scene = CachedScene(await ps.get_scene(scene_id)) _scenes[scene_id] = scene return scene
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_get_value() -> None: img = Image.new("RGB", (320, 240)) scene = Scene("s1", "s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) project.action_points.append(ap1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, ImagePlugin.type_name(), ImagePlugin.value_to_json(img)), ActionParameter(invalid_param_name, ImagePlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): ImagePlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, invalid_param_name) value = ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, param_name) exe_value = ImagePlugin.parameter_execution_value(type_defs, cscene, cproject, ac1.id, param_name) assert value == value assert value == exe_value
def test_get_value() -> None: scene = Scene("s1", "s1") obj = SceneObject("test_name", TestObject.__name__) prj = ProjectRobotJoints("name", obj.id, [Joint("name", 0.333)]) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) ap1.robot_joints.append(prj) project.action_points.append(ap1) invalid_param_name = "invalid_param" act = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, JointsPlugin.type_name(), json.dumps(prj.id)), ActionParameter(invalid_param_name, JointsPlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(act) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, "non_sense") with pytest.raises(Arcor2Exception): JointsPlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, invalid_param_name) value = JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, param_name) exe_value = JointsPlugin.parameter_execution_value(type_defs, cscene, cproject, act.id, param_name) assert value == value assert value == exe_value
def test_get_value(self, val: str) -> None: scene = Scene("s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, StringPlugin.type_name(), StringPlugin.value_to_json(val)), ActionParameter(invalid_param_name, StringPlugin.type_name(), json.dumps(666)), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): StringPlugin.parameter_value({}, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): StringPlugin.parameter_value({}, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): StringPlugin.parameter_value({}, cscene, cproject, ac1.id, invalid_param_name) value = StringPlugin.parameter_value({}, cscene, cproject, ac1.id, param_name) exe_value = StringPlugin.parameter_execution_value({}, cscene, cproject, ac1.id, param_name) assert value == val assert value == exe_value
def test_make_relative_ap_global_and_relative_again() -> None: scene = Scene("s1") so1 = SceneObject("so1", "WhatEver", Pose(Position(3, 0, 0), Orientation())) scene.objects.append(so1) cached_scene = CachedScene(scene) project = Project("p1", scene.id) ap1 = ActionPoint("ap1", Position(-1, 0, 0), parent=so1.id) project.action_points.append(ap1) ap2 = ActionPoint("ap2", Position(-1, 0, 0), parent=ap1.id) project.action_points.append(ap2) ap3 = ActionPoint( "ap3", Position(-1, 0, 0), parent=ap2.id, orientations=[NamedOrientation("bla", random_orientation())]) project.action_points.append(ap3) cached_project = CachedProject(project) assert ap3.parent ap3_parent = get_parent_pose(cached_scene, cached_project, ap3.parent) assert Pose(ap2.position, Orientation()) == ap3_parent.pose assert ap3_parent.parent_id == ap1.id make_relative_ap_global(cached_scene, cached_project, ap3) check_ap(ap3) assert ap3.parent is None assert ap3.position.x == 0.0 # type: ignore make_global_ap_relative(cached_scene, cached_project, ap3, ap2.id) check_ap(ap3) assert ap3.parent == ap2.id assert ap3.position.x == -1 ap3.parent = "something_unknown" with pytest.raises(Arcor2Exception): make_relative_ap_global(cached_scene, cached_project, ap3)
async def project_info( project_id: str, scenes_lock: asyncio.Lock, scenes: Dict[str, CachedScene]) -> srpc.p.ListProjects.Response.Data: project = await storage.get_project(project_id) assert project.modified is not None pd = srpc.p.ListProjects.Response.Data(id=project.id, desc=project.desc, name=project.name, scene_id=project.scene_id, modified=project.modified) try: cached_project = UpdateableCachedProject(project) except CachedProjectException as e: pd.problems.append(str(e)) return pd try: async with scenes_lock: if project.scene_id not in scenes: scenes[project.scene_id] = CachedScene(await storage.get_scene( project.scene_id)) except storage.ProjectServiceException: pd.problems.append("Scene does not exist.") return pd pd.problems = project_problems(scenes[project.scene_id], cached_project) pd.valid = not pd.problems if not pd.valid: return pd try: # TODO call build service!!! pd.executable = True except Arcor2Exception as e: pd.problems.append(str(e)) return pd
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 _publish(project_id: str, package_name: str) -> RespT: mem_zip = BytesIO() logger.debug( f"Generating package {package_name} for project_id: {project_id}.") types_dict: TypesDict = {} # restore original environment sys.path = list(original_sys_path) sys.modules = dict(original_sys_modules) with tempfile.TemporaryDirectory() as tmp_dir: prepare_object_types_dir(tmp_dir, OBJECT_TYPE_MODULE) with zipfile.ZipFile(mem_zip, mode="w", compression=zipfile.ZIP_DEFLATED) as zf: try: logger.debug("Getting scene and project.") project = ps.get_project(project_id) cached_project = CachedProject(project) scene = ps.get_scene(project.scene_id) cached_scene = CachedScene(scene) if not package_name: package_name = project.name data_path = "data" ot_path = "object_types" zf.writestr(os.path.join(ot_path, "__init__.py"), "") zf.writestr(os.path.join(data_path, "project.json"), project.to_json()) zf.writestr(os.path.join(data_path, "scene.json"), scene.to_json()) obj_types = set(cached_scene.object_types) obj_types_with_models: set[str] = set() if __debug__: # this should uncover potential problems with order in which ObjectTypes are processed import random random.shuffle(scene.objects) for scene_obj in scene.objects: if scene_obj.type in types_dict: continue logger.debug( f"Getting scene object type {scene_obj.type}.") obj_type = ps.get_object_type(scene_obj.type) if obj_type.model and obj_type.id not in obj_types_with_models: obj_types_with_models.add(obj_type.id) model = ps.get_model(obj_type.model.id, obj_type.model.type) obj_model = ObjectModel( obj_type.model.type, **{model.type().value.lower(): model} # type: ignore ) zf.writestr( os.path.join( data_path, "models", humps.depascalize(obj_type.id) + ".json"), obj_model.to_json(), ) zf.writestr( os.path.join(ot_path, humps.depascalize(obj_type.id)) + ".py", obj_type.source) # handle inheritance get_base_from_project_service(types_dict, tmp_dir, obj_types, obj_type, zf, ot_path, parse(obj_type.source)) types_dict[scene_obj.type] = save_and_import_type_def( obj_type.source, scene_obj.type, Generic, tmp_dir, OBJECT_TYPE_MODULE) except Arcor2Exception as e: logger.exception( f"Failed to prepare package content. {str(e)}") raise FlaskException(str(e), error_code=404) script_path = "script.py" try: if project.has_logic: logger.debug("Generating script from project logic.") zf.writestr( script_path, program_src(types_dict, cached_project, cached_scene, True)) else: try: logger.debug("Getting project sources.") script = ps.get_project_sources(project.id).script # check if it is a valid Python code try: parse(script) except SourceException: logger.exception( "Failed to parse code of the uploaded script.") raise FlaskException("Invalid code.", error_code=501) zf.writestr(script_path, script) except ps.ProjectServiceException: logger.info( "Script not found on project service, creating one from scratch." ) # write script without the main loop zf.writestr( script_path, program_src(types_dict, cached_project, cached_scene, False)) logger.debug("Generating supplementary files.") logger.debug("action_points.py") zf.writestr("action_points.py", global_action_points_class(cached_project)) logger.debug("package.json") zf.writestr( "package.json", PackageMeta(package_name, datetime.now(tz=timezone.utc)).to_json()) except Arcor2Exception as e: logger.exception("Failed to generate script.") raise FlaskException(str(e), error_code=501) logger.info( f"Done with {package_name} (scene {scene.name}, project {project.name})." ) mem_zip.seek(0) return send_file(mem_zip, as_attachment=True, max_age=0, download_name=f"{package_name}_package.zip")
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
async def scenes() -> AsyncIterator[CachedScene]: for scene_id in await storage.get_scene_ids(): yield CachedScene(await storage.get_scene(scene_id))
def __init__(self, apply_action_mapping: bool = True) -> None: models: dict[str, Optional[Models]] = {} scene = self.read_project_data(Scene.__name__.lower(), Scene) project = self.read_project_data(Project.__name__.lower(), Project) self.scene = CachedScene(scene) self.project = CachedProject(project) if self.project.scene_id != self.scene.id: raise ResourcesException("Project/scene not consistent!") # make all poses absolute for aps in self.project.action_points_with_parent: # Action point pose is relative to its parent object/AP pose in scene but is absolute during runtime. tr.make_relative_ap_global(self.scene, self.project, aps) for obj_type in self.scene.object_types: try: models[obj_type] = self.read_project_data( "models/" + humps.depascalize(obj_type), ObjectModel).model() except IOError: models[obj_type] = None type_defs: TypesDict = {} for scene_obj_type in self.scene.object_types: # get all type-defs assert scene_obj_type not in type_defs assert scene_obj_type not in built_in_types_names() module = importlib.import_module(CUSTOM_OBJECT_TYPES_MODULE + "." + humps.depascalize(scene_obj_type)) cls = getattr(module, scene_obj_type) patch_object_actions(cls) type_defs[cls.__name__] = cls if apply_action_mapping: patch_with_action_mapping(cls, self.scene, self.project) action.start_paused, action.breakpoints = parse_args() if action.breakpoints: ap_ids = self.project.action_points_ids for bp in action.breakpoints: if bp not in ap_ids: raise ResourcesException(f"Breakpoint ID unknown: {bp}.") # orientations / joints have to be monkey-patched with AP's ID in order to make breakpoints work in @action for ap in self.project.action_points: setattr(ap.position, AP_ID_ATTR, ap.id) for joints in self.project.ap_joints(ap.id): setattr(joints, AP_ID_ATTR, ap.id) package_id = os.path.basename(os.getcwd()) package_meta = package.read_package_meta(package_id) package_info_event = PackageInfo( PackageInfo.Data(package_id, package_meta.name, scene, project)) for model in models.values(): if not model: continue if isinstance(model, Box): package_info_event.data.collision_models.boxes.append(model) elif isinstance(model, Sphere): package_info_event.data.collision_models.spheres.append(model) elif isinstance(model, Cylinder): package_info_event.data.collision_models.cylinders.append( model) elif isinstance(model, Mesh): package_info_event.data.collision_models.meshes.append(model) # following steps might take some time, so let UIs know about the package as a first thing print_event(package_info_event) # in order to prepare a clean environment (clears all configurations and all collisions) scene_service.stop() self.executor = concurrent.futures.ThreadPoolExecutor() futures: list[concurrent.futures.Future] = [] for scene_obj in self.scene.objects: cls = type_defs[scene_obj.type] settings = settings_from_params( cls, scene_obj.parameters, self.project.overrides.get(scene_obj.id, None)) if issubclass(cls, Robot): futures.append( self.executor.submit(cls, scene_obj.id, scene_obj.name, scene_obj.pose, settings)) elif issubclass(cls, CollisionObject): futures.append( self.executor.submit(cls, scene_obj.id, scene_obj.name, scene_obj.pose, models[scene_obj.type], settings)) elif issubclass(cls, GenericWithPose): futures.append( self.executor.submit(cls, scene_obj.id, scene_obj.name, scene_obj.pose, settings)) elif issubclass(cls, Generic): futures.append( self.executor.submit(cls, scene_obj.id, scene_obj.name, settings)) else: raise Arcor2Exception( f"{cls.__name__} has unknown base class.") exceptions: list[Arcor2Exception] = [] self.objects: dict[str, Generic] = {} for f in concurrent.futures.as_completed(futures): try: inst = f.result( ) # if an object creation resulted in exception, it will be raised here except Arcor2Exception as e: print_exception(e) exceptions.append(e) else: self.objects[ inst.id] = inst # successfully initialized objects if exceptions: # if something failed, tear down those that succeeded and stop self.cleanup_all_objects() raise ResourcesException(" ".join([str(e) for e in exceptions]), exceptions) scene_service.start() self._stream_futures: list[concurrent.futures.Future] = []
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 __init__(self, scene: Scene, project: Project, models: Dict[str, Optional[Models]]) -> None: self.project = CachedProject(project) self.scene = CachedScene(scene) if self.project.scene_id != self.scene.id: raise ResourcesException("Project/scene not consistent!") self.objects: Dict[str, Generic] = {} self.type_defs: TypesDict = {} built_in = built_in_types_names() if scene_service.started(): scene_service.stop() scene_service.delete_all_collisions() package_id = os.path.basename(os.getcwd()) package_meta = package.read_package_meta(package_id) package_info_event = PackageInfo( PackageInfo.Data(package_id, package_meta.name, scene, project)) for scene_obj_type in self.scene.object_types: # get all type-defs assert scene_obj_type not in self.type_defs if scene_obj_type in built_in: module = importlib.import_module( arcor2.object_types.__name__ + "." + humps.depascalize(scene_obj_type)) else: module = importlib.import_module( Resources.CUSTOM_OBJECT_TYPES_MODULE + "." + humps.depascalize(scene_obj_type)) cls = getattr(module, scene_obj_type) patch_object_actions( cls, get_action_name_to_id(self.scene, self.project, cls.__name__)) self.type_defs[cls.__name__] = cls scene_objects = list(self.scene.objects) # sort according to OT initialization priority (highest is initialized first) scene_objects.sort(key=lambda x: self.type_defs[x.type].INIT_PRIORITY, reverse=True) for scene_obj in scene_objects: cls = self.type_defs[scene_obj.type] assert scene_obj.id not in self.objects, "Duplicate object id {}!".format( scene_obj.id) settings = settings_from_params( cls, scene_obj.parameters, self.project.overrides.get(scene_obj.id, None)) if issubclass(cls, Robot): self.objects[scene_obj.id] = cls(scene_obj.id, scene_obj.name, scene_obj.pose, settings) elif issubclass(cls, GenericWithPose): self.objects[scene_obj.id] = cls(scene_obj.id, scene_obj.name, scene_obj.pose, models[scene_obj.type], settings) elif issubclass(cls, Generic): self.objects[scene_obj.id] = cls(scene_obj.id, scene_obj.name, settings) else: raise Arcor2Exception("Unknown base class.") for model in models.values(): if not model: continue if isinstance(model, Box): package_info_event.data.collision_models.boxes.append(model) elif isinstance(model, Sphere): package_info_event.data.collision_models.spheres.append(model) elif isinstance(model, Cylinder): package_info_event.data.collision_models.cylinders.append( model) elif isinstance(model, Mesh): package_info_event.data.collision_models.meshes.append(model) scene_service.start() print_event(package_info_event) # make all poses absolute for aps in self.project.action_points_with_parent: # Action point pose is relative to its parent object/AP pose in scene but is absolute during runtime. tr.make_relative_ap_global(self.scene, self.project, aps)
async def scenes() -> AsyncIterator[CachedScene]: for scene_id in (await storage.get_scenes()).items: yield CachedScene(await storage.get_scene(scene_id.id))