Beispiel #1
0
def new_object_type_source(parent: ObjectTypeMeta,
                           child: ObjectTypeMeta) -> str:

    assert parent.type == child.base

    tree = Module(body=[], type_ignores=[])

    if parent.type in built_in_types_names():
        import_from = arcor2.object_types.__name__
    else:
        import_from = camel_case_to_snake_case(parent.type)

    tree.body.append(
        ImportFrom(module=import_from,
                   names=[alias(name=parent.type, asname=None)],
                   level=0))

    c = ClassDef(name=child.type,
                 bases=[get_name(parent.type)],
                 keywords=[],
                 body=[],
                 decorator_list=[])

    # TODO add docstring with description (if provided)
    c.body.append(Pass())

    tree.body.append(c)

    return tree_to_str(tree)
Beispiel #2
0
def program_src(project: Project,
                scene: Scene,
                built_in_objects: Set[str],
                add_logic: bool = True) -> str:

    tree = empty_script_tree(add_main_loop=add_logic)

    # get object instances from resources object
    for obj in scene.objects:

        if obj.type in built_in_objects:
            add_import(tree,
                       arcor2.object_types.__name__,
                       obj.type,
                       try_to_import=False)
        else:
            add_import(tree,
                       "object_types." + camel_case_to_snake_case(obj.type),
                       obj.type,
                       try_to_import=False)

        object_instance_from_res(tree, obj.name, obj.id, obj.type, "objects")

    for srv in scene.services:
        add_import(tree,
                   "services." + camel_case_to_snake_case(srv.type),
                   srv.type,
                   try_to_import=False)
        object_instance_from_res(tree, srv.type, srv.type, srv.type,
                                 "services")

    if add_logic:
        add_logic_to_loop(tree, scene, project)

    return SCRIPT_HEADER + tree_to_str(tree)
Beispiel #3
0
def test_meta_to_source() -> None:

    parent = ObjectTypeMeta(type="Generic")
    child = ObjectTypeMeta(type="NewType",
                           description="blabla bla",
                           base="Generic")

    source = tree_to_str(new_object_type(parent, child))

    assert "class NewType(Generic)" in source
Beispiel #4
0
def program_src(type_defs: TypesDict,
                project: CProject,
                scene: CScene,
                add_logic: bool = True) -> str:

    tree = empty_script_tree(project.id, add_main_loop=add_logic)

    # get object instances from resources object
    main = find_function("main", tree)
    last_assign = find_last_assign(main)
    for obj in scene.objects:
        add_import(tree,
                   "object_types." + humps.depascalize(obj.type),
                   obj.type,
                   try_to_import=False)
        last_assign += 1
        main.body.insert(last_assign,
                         object_instance_from_res(obj.name, obj.id, obj.type))

    # TODO temporary solution - should be (probably) handled by plugin(s)
    from arcor2 import json

    # TODO should we put there even unused parameters?
    for param in project.parameters:
        val = json.loads(param.value)

        aval: Optional[expr] = None

        if isinstance(val, bool):  # subclass of int
            aval = NameConstant(value=val, kind=None)
        elif isinstance(val, (int, float)):
            aval = Num(n=val, kind=None)
        elif isinstance(val, str):
            aval = Str(s=val, kind="")

        if not aval:
            raise Arcor2Exception(
                f"Unsupported project parameter type ({param.type}) or value ({val})."
            )

        last_assign += 1
        main.body.insert(
            last_assign,
            Assign(  # TODO use rather AnnAssign?
                targets=[Name(id=param.name, ctx=Store())],
                value=aval,
                type_comment=None),
        )

    if add_logic:
        add_logic_to_loop(type_defs, tree, scene, project)

    return SCRIPT_HEADER + tree_to_str(tree)
Beispiel #5
0
async def update_object_model_cb(req: srpc.o.UpdateObjectModel.Request,
                                 ui: WsClient) -> None:

    can_modify_scene()
    glob.LOCK.scene_or_exception(True)  # only allow while editing scene

    obj_data = glob.OBJECT_TYPES[req.args.object_type_id]

    if not obj_data.type_def:
        raise Arcor2Exception("ObjectType disabled.")

    if not issubclass(obj_data.type_def, CollisionObject):
        raise Arcor2Exception("Not a CollisionObject.")

    assert obj_data.meta.object_model
    assert obj_data.ast

    if req.args.object_model == obj_data.meta.object_model:
        raise Arcor2Exception("No change requested.")

    await ensure_write_locked(req.args.object_type_id,
                              glob.USERS.user_name(ui))

    if req.dry_run:
        return

    await update_object_model(obj_data.meta, req.args.object_model)
    obj_data.meta.object_model = req.args.object_model

    ot = obj_data.meta.to_object_type()
    ot.source = tree_to_str(obj_data.ast)

    obj_data.meta.modified = await storage.update_object_type(ot)

    evt = sevts.o.ChangedObjectTypes([obj_data.meta])
    evt.change_type = events.Event.Type.UPDATE
    asyncio.ensure_future(notif.broadcast_event(evt))
Beispiel #6
0
def global_action_points_class(project: CachedProject) -> str:
    tree = Module(body=[])

    tree.body.append(
        ImportFrom(
            module=arcor2.data.common.__name__,
            names=[
                alias(name=ActionPoint.__name__, asname=None),
                alias(name=Position.__name__, asname=None),
                alias(name=Pose.__name__, asname=None),
                alias(name=ProjectRobotJoints.__name__, asname=None),
            ],
            level=0,
        ))

    tree.body.append(
        ImportFrom(
            module=copy.__name__,
            names=[alias(name=copy.deepcopy.__name__, asname=None)],
            level=0,
        ))

    tree.body.append(
        ImportFrom(
            module=RES_MODULE,
            names=[alias(name=RES_CLS, asname=None)],
            level=0,
        ))

    aps_init_body: List[Union[Assign, Pass]] = []

    for ap in project.action_points:

        ap_cls_body: List[Assign] = [
            Assign(
                targets=[
                    Attribute(value=Name(id="self", ctx=Load()),
                              attr="_position",
                              ctx=Store())
                ],
                value=Attribute(
                    value=Call(
                        func=Attribute(
                            value=Attribute(value=Name(id="res", ctx=Load()),
                                            attr="project",
                                            ctx=Load()),
                            attr=CachedProject.bare_action_point.__name__,
                            ctx=Load(),
                        ),
                        args=[Str(s=ap.id, kind="")],
                        keywords=[],
                    ),
                    attr="position",
                    ctx=Load(),
                ),
                type_comment=None,
            )
        ]

        ap_type_name = humps.pascalize(ap.name)

        ap_joints_init_body: List[Assign] = []

        for joints in project.ap_joints(ap.id):
            ap_joints_init_body.append(
                Assign(
                    targets=[
                        Attribute(value=Name(id="self", ctx=Load()),
                                  attr=f"_{joints.name}",
                                  ctx=Store())
                    ],
                    value=Call(
                        func=Attribute(
                            value=Attribute(value=Name(id="res", ctx=Load()),
                                            attr="project",
                                            ctx=Load()),
                            attr="joints",
                            ctx=Load(),
                        ),
                        args=[Str(s=joints.id, kind="")],
                        keywords=[],
                    ),
                    type_comment=None,
                ))

        if ap_joints_init_body:

            ap_joints_cls_def = ClassDef(
                name=f"{ap_type_name}Joints",
                bases=[],
                keywords=[],
                body=[
                    FunctionDef(
                        name="__init__",
                        args=arguments(
                            args=[
                                arg(arg="self",
                                    annotation=None,
                                    type_comment=None),
                                arg(arg="res",
                                    annotation=Name(id=RES_CLS, ctx=Load()),
                                    type_comment=None),
                            ],
                            vararg=None,
                            kwonlyargs=[],
                            kw_defaults=[],
                            kwarg=None,
                            defaults=[],
                        ),
                        body=ap_joints_init_body,
                        decorator_list=[],
                        returns=None,
                        type_comment=None,
                    )
                ],
                decorator_list=[],
            )

            for joints in project.ap_joints(ap.id):
                ap_joints_cls_def.body.append(
                    FunctionDef(
                        name=joints.name,
                        args=arguments(
                            args=[
                                arg(arg="self",
                                    annotation=None,
                                    type_comment=None)
                            ],
                            vararg=None,
                            kwonlyargs=[],
                            kw_defaults=[],
                            kwarg=None,
                            defaults=[],
                        ),
                        body=[
                            Return(value=Call(
                                func=Name(id=copy.deepcopy.__name__,
                                          ctx=Load()),
                                args=[
                                    Attribute(value=Name(id="self",
                                                         ctx=Load()),
                                              attr=f"_{joints.name}",
                                              ctx=Load())
                                ],
                                keywords=[],
                            ))
                        ],
                        decorator_list=[Name(id="property", ctx=Load())],
                        returns=Name(id=ProjectRobotJoints.__name__,
                                     ctx=Load()),
                        type_comment=None,
                    ))

            tree.body.append(ap_joints_cls_def)

            ap_cls_body.append(
                Assign(
                    targets=[
                        Attribute(value=Name(id="self", ctx=Load()),
                                  attr="joints",
                                  ctx=Store())
                    ],
                    value=Call(
                        func=Name(id=f"{ap_type_name}Joints", ctx=Load()),
                        args=[Name(id="res", ctx=Load())],
                        keywords=[],
                    ),
                    type_comment=None,
                ))

        ap_orientations_init_body: List[Assign] = []

        for ori in project.ap_orientations(ap.id):
            ap_orientations_init_body.append(
                Assign(
                    targets=[
                        Attribute(value=Name(id="self", ctx=Load()),
                                  attr=f"_{ori.name}",
                                  ctx=Store())
                    ],
                    value=Call(
                        func=Attribute(
                            value=Attribute(value=Name(id="res", ctx=Load()),
                                            attr="project",
                                            ctx=Load()),
                            attr="pose",
                            ctx=Load(),
                        ),
                        args=[Str(s=ori.id, kind="")],
                        keywords=[],
                    ),
                    type_comment=None,
                ))

        if ap_orientations_init_body:

            ap_orientations_cls_def = ClassDef(
                name=f"{ap_type_name}Poses",
                bases=[],
                keywords=[],
                body=[
                    FunctionDef(
                        name="__init__",
                        args=arguments(
                            args=[
                                arg(arg="self",
                                    annotation=None,
                                    type_comment=None),
                                arg(arg="res",
                                    annotation=Name(id=RES_CLS, ctx=Load()),
                                    type_comment=None),
                            ],
                            vararg=None,
                            kwonlyargs=[],
                            kw_defaults=[],
                            kwarg=None,
                            defaults=[],
                        ),
                        body=ap_orientations_init_body,
                        decorator_list=[],
                        returns=None,
                        type_comment=None,
                    )
                ],
                decorator_list=[],
            )

            for ori in project.ap_orientations(ap.id):
                ap_orientations_cls_def.body.append(
                    FunctionDef(
                        name=ori.name,
                        args=arguments(
                            args=[
                                arg(arg="self",
                                    annotation=None,
                                    type_comment=None)
                            ],
                            vararg=None,
                            kwonlyargs=[],
                            kw_defaults=[],
                            kwarg=None,
                            defaults=[],
                        ),
                        body=[
                            Return(value=Call(
                                func=Name(id=copy.deepcopy.__name__,
                                          ctx=Load()),
                                args=[
                                    Attribute(value=Name(id="self",
                                                         ctx=Load()),
                                              attr=f"_{ori.name}",
                                              ctx=Load())
                                ],
                                keywords=[],
                            ))
                        ],
                        decorator_list=[Name(id="property", ctx=Load())],
                        returns=Name(id=Pose.__name__, ctx=Load()),
                        type_comment=None,
                    ))

            tree.body.append(ap_orientations_cls_def)

            ap_cls_body.append(
                Assign(
                    targets=[
                        Attribute(value=Name(id="self", ctx=Load()),
                                  attr="poses",
                                  ctx=Store())
                    ],
                    value=Call(
                        func=Name(id=f"{ap_type_name}Poses", ctx=Load()),
                        args=[Name(id="res", ctx=Load())],
                        keywords=[],
                    ),
                    type_comment=None,
                ))

        ap_cls_def = ClassDef(
            name=ap_type_name,
            bases=[],
            keywords=[],
            body=[
                FunctionDef(
                    name="__init__",
                    args=arguments(
                        args=[
                            arg(arg="self", annotation=None,
                                type_comment=None),
                            arg(arg="res",
                                annotation=Name(id=RES_CLS, ctx=Load()),
                                type_comment=None),
                        ],
                        vararg=None,
                        kwonlyargs=[],
                        kw_defaults=[],
                        kwarg=None,
                        defaults=[],
                    ),
                    body=ap_cls_body,
                    decorator_list=[],
                    returns=None,
                    type_comment=None,
                )
            ],
            decorator_list=[],
        )

        # add copy property for position
        ap_cls_def.body.append(
            FunctionDef(
                name="position",
                args=arguments(
                    args=[arg(arg="self", annotation=None, type_comment=None)],
                    vararg=None,
                    kwonlyargs=[],
                    kw_defaults=[],
                    kwarg=None,
                    defaults=[],
                ),
                body=[
                    Return(value=Call(
                        func=Name(id=copy.deepcopy.__name__, ctx=Load()),
                        args=[
                            Attribute(value=Name(id="self", ctx=Load()),
                                      attr="_position",
                                      ctx=Load())
                        ],
                        keywords=[],
                    ))
                ],
                decorator_list=[Name(id="property", ctx=Load())],
                returns=Name(id=Position.__name__, ctx=Load()),
                type_comment=None,
            ))

        tree.body.append(ap_cls_def)

        aps_init_body.append(
            Assign(
                targets=[
                    Attribute(value=Name(id="self", ctx=Load()),
                              attr=ap.name,
                              ctx=Store())
                ],
                value=Call(func=Name(id=ap_type_name, ctx=Load()),
                           args=[Name(id="res", ctx=Load())],
                           keywords=[]),
                type_comment=None,
            ))

    if not aps_init_body:  # there are no action points
        aps_init_body.append(Pass())

    aps_cls_def = ClassDef(
        name="ActionPoints",
        bases=[],
        keywords=[],
        body=[
            FunctionDef(
                name="__init__",
                args=arguments(
                    args=[
                        arg(arg="self", annotation=None, type_comment=None),
                        arg(arg="res",
                            annotation=Name(id=RES_CLS, ctx=Load()),
                            type_comment=None),
                    ],
                    vararg=None,
                    kwonlyargs=[],
                    kw_defaults=[],
                    kwarg=None,
                    defaults=[],
                ),
                body=aps_init_body,
                decorator_list=[],
                returns=None,
                type_comment=None,
            )
        ],
        decorator_list=[],
    )

    tree.body.append(aps_cls_def)
    return tree_to_str(tree)
Beispiel #7
0
async def new_object_type_cb(req: srpc.o.NewObjectType.Request,
                             ui: WsClient) -> None:

    async with ctx_write_lock(glob.LOCK.SpecialValues.ADDING_OBJECT, ui):
        meta = req.args

        if meta.type in glob.OBJECT_TYPES:
            raise Arcor2Exception("Object type already exists.")

        hlp.is_valid_type(meta.type)

        if meta.base not in glob.OBJECT_TYPES:
            raise Arcor2Exception(
                f"Unknown base object type '{meta.base}', "
                f"known types are: {', '.join(glob.OBJECT_TYPES.keys())}.")

        base = glob.OBJECT_TYPES[meta.base]

        if base.meta.disabled:
            raise Arcor2Exception("Base object is disabled.")

        assert base.type_def is not None

        if issubclass(base.type_def, Robot):
            raise Arcor2Exception("Can't subclass Robot.")

        meta.has_pose = issubclass(base.type_def, GenericWithPose)

        if not meta.has_pose and meta.object_model:
            raise Arcor2Exception(
                "Object without pose can't have collision model.")

        if req.dry_run:
            return None

        obj = meta.to_object_type()
        ast = new_object_type(glob.OBJECT_TYPES[meta.base].meta, meta)
        obj.source = tree_to_str(ast)

        if meta.object_model:

            if meta.object_model.type == Model3dType.MESH:

                # TODO check whether mesh id exists - if so, then use existing mesh, if not, upload a new one
                # ...get whole mesh (focus_points) based on mesh id
                assert meta.object_model.mesh
                try:
                    meta.object_model.mesh = await storage.get_mesh(
                        meta.object_model.mesh.id)
                except storage.ProjectServiceException as e:
                    glob.logger.error(e)
                    raise Arcor2Exception(
                        f"Mesh ID {meta.object_model.mesh.id} does not exist.")

            else:

                meta.object_model.model().id = meta.type
                await storage.put_model(meta.object_model.model())

        type_def = await hlp.run_in_executor(
            hlp.save_and_import_type_def,
            obj.source,
            obj.id,
            base.type_def,
            settings.OBJECT_TYPE_PATH,
            settings.OBJECT_TYPE_MODULE,
        )
        assert issubclass(type_def, base.type_def)
        actions = object_actions(type_def, ast)

        await storage.update_object_type(obj)

        glob.OBJECT_TYPES[meta.type] = ObjectTypeData(meta, type_def, actions,
                                                      ast)
        add_ancestor_actions(meta.type, glob.OBJECT_TYPES)

        evt = sevts.o.ChangedObjectTypes([meta])
        evt.change_type = events.Event.Type.ADD
        asyncio.ensure_future(notif.broadcast_event(evt))
        return None
Beispiel #8
0
async def new_object_type_cb(req: srpc.o.NewObjectType.Request,
                             ui: WsClient) -> None:

    async with ctx_write_lock(glob.LOCK.SpecialValues.ADDING_OBJECT,
                              glob.USERS.user_name(ui)):
        meta = req.args

        if meta.type in glob.OBJECT_TYPES:
            raise Arcor2Exception("Object type already exists.")

        hlp.is_valid_type(meta.type)

        if meta.base not in glob.OBJECT_TYPES:
            raise Arcor2Exception(
                f"Unknown base object type '{meta.base}', "
                f"known types are: {', '.join(glob.OBJECT_TYPES.keys())}.")

        base = glob.OBJECT_TYPES[meta.base]

        if base.meta.disabled:
            raise Arcor2Exception("Base object is disabled.")

        assert base.type_def is not None

        if issubclass(base.type_def, Robot):
            raise Arcor2Exception("Can't subclass Robot.")

        meta.has_pose = issubclass(base.type_def, GenericWithPose)

        if issubclass(base.type_def, CollisionObject):
            if not meta.object_model:
                raise Arcor2Exception(
                    "Objects based on CollisionObject must have collision model."
                )
        else:
            if meta.object_model:
                raise Arcor2Exception(
                    "Only objects based on CollisionObject can have collision model."
                )

        if req.dry_run:
            return None

        obj = meta.to_object_type()
        ast = new_object_type(glob.OBJECT_TYPES[meta.base].meta, meta)
        obj.source = tree_to_str(ast)

        if meta.object_model:
            await update_object_model(meta, meta.object_model)

        type_def = await hlp.run_in_executor(
            hlp.save_and_import_type_def,
            obj.source,
            obj.id,
            base.type_def,
            settings.OBJECT_TYPE_PATH,
            settings.OBJECT_TYPE_MODULE,
        )
        assert issubclass(type_def, base.type_def)
        actions = object_actions(type_def, ast)

        meta.modified = await storage.update_object_type(obj)

        glob.OBJECT_TYPES[meta.type] = ObjectTypeData(meta, type_def, actions,
                                                      ast)
        add_ancestor_actions(meta.type, glob.OBJECT_TYPES)

        evt = sevts.o.ChangedObjectTypes([meta])
        evt.change_type = events.Event.Type.ADD
        asyncio.ensure_future(notif.broadcast_event(evt))
        return None