コード例 #1
0
ファイル: scene.py プロジェクト: robofit/arcor2
async def create_object_instance(obj: SceneObject,
                                 overrides: Optional[List[Parameter]] = None
                                 ) -> None:

    obj_type = glob.OBJECT_TYPES[obj.type]

    # settings -> dataclass
    assert obj_type.type_def
    glob.logger.debug(
        f"Creating instance of {obj_type.type_def.__name__} with name {obj.name}. "
        f"Parameters: {obj.parameters}, overrides: {overrides}.")
    settings = settings_from_params(obj_type.type_def, obj.parameters,
                                    overrides)

    assert obj_type.type_def is not None

    try:

        try:

            if issubclass(obj_type.type_def, Robot):
                assert obj.pose is not None
                glob.SCENE_OBJECT_INSTANCES[
                    obj.id] = await hlp.run_in_executor(
                        obj_type.type_def, obj.id, obj.name, obj.pose,
                        settings)
            elif issubclass(obj_type.type_def, GenericWithPose):
                assert obj.pose is not None
                coll_model: Optional[Models] = None
                if obj_type.meta.object_model:
                    coll_model = obj_type.meta.object_model.model()

                glob.SCENE_OBJECT_INSTANCES[
                    obj.id] = await hlp.run_in_executor(
                        obj_type.type_def, obj.id, obj.name, obj.pose,
                        coll_model, settings)

            elif issubclass(obj_type.type_def, Generic):
                assert obj.pose is None
                glob.SCENE_OBJECT_INSTANCES[
                    obj.id] = await hlp.run_in_executor(
                        obj_type.type_def, obj.id, obj.name, settings)

            else:
                raise Arcor2Exception("Object type with unknown base.")

        except (TypeError,
                ValueError) as e:  # catch some most often exceptions
            raise Arcor2Exception("Unhandled error.") from e

    except Arcor2Exception as e:
        # make the exception a bit more user-friendly by including the object's name
        raise Arcor2Exception(
            f"Failed to initialize {obj.name}. {str(e)}") from e

    return None
コード例 #2
0
ファイル: test_utils.py プロジェクト: robofit/arcor2
def test_settings_from_params() -> None:

    settings = settings_from_params(
        TestObjectWithSettings,
        [
            Parameter("string", "string", json.dumps("value")),
            Parameter("integer", "integer", json.dumps(1)),
            Parameter("boolean", "boolean", json.dumps(False)),
            Parameter("double", "double", json.dumps(1.0)),
            Parameter("enum", "enum", json.dumps(MyEnum.OPT1)),
            Parameter("nested_settings", "dataclass", NestedSettings(True).to_json()),
        ],
        [Parameter("integer", "integer", json.dumps(2)), Parameter("double", "double", json.dumps(2.0))],
    )

    assert isinstance(settings, TestObjectSettings)
コード例 #3
0
    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] = []
コード例 #4
0
ファイル: resources.py プロジェクト: Croolman/arcor2
    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)