def check_override(scene: CachedScene, project: CachedProject, obj_id: str, override: Parameter, add_new_one: bool = False) -> SceneObject: obj = scene.object(obj_id) for par in glob.OBJECT_TYPES[obj.type].meta.settings: if par.name == override.name: if par.type != override.type: raise Arcor2Exception("Override can't change parameter type.") break else: raise Arcor2Exception("Unknown parameter name.") if add_new_one: try: for existing_override in project.overrides[obj.id]: if override.name == existing_override.name: raise Arcor2Exception("Override already exists.") except KeyError: pass else: if obj.id not in project.overrides: raise Arcor2Exception("There are no overrides for the object.") for override in project.overrides[obj.id]: if override.name == override.name: break else: raise Arcor2Exception("Override not found.") return obj
def check_ap_parent(scene: CachedScene, proj: CachedProject, parent: Optional[str]) -> None: if not parent: return if parent in scene.object_ids: if scene.object(parent).pose is None: raise Arcor2Exception("AP can't have object without pose as parent.") elif parent not in proj.action_points_ids: raise Arcor2Exception("AP has invalid parent ID (not an object or another AP).")
def project_problems(obj_types: ObjectTypeDict, scene: CachedScene, project: CachedProject) -> list[str]: if project.scene_id != scene.id: return ["Project/scene mismatch."] problems: list[str] = scene_problems(obj_types, scene) for proj_param in project.parameters: try: check_project_parameter(project, proj_param) except Arcor2Exception as e: problems.append(str(e)) for ap in project.action_points: try: check_ap_parent(scene, project, ap.parent) except Arcor2Exception: problems.append(f"Action point {ap.name} has invalid parent: {ap.parent}.") for joints in project.ap_joints(ap.id): if joints.robot_id not in scene.object_ids: problems.append( f"Action point {ap.name} has joints ({joints.name}) for an unknown robot: {joints.robot_id}." ) for action in project.actions: # check if objects have used actions obj_id, action_type = action.parse_type() if obj_id not in scene.object_ids: problems.append(f"Object ID {obj_id} which action is used in {action.name} does not exist in scene.") continue scene_obj = scene.object(obj_id) if action_type not in obj_types[scene_obj.type].actions: problems.append( f"ObjectType {scene_obj.type} does not have action {action_type} used in {action.name}." ) continue action_meta = obj_types[scene_obj.type].actions[action_type] try: check_action_params(obj_types, scene, project, action, action_meta) except Arcor2Exception as e: problems.append(str(e)) try: check_flows(project, action, action_meta) except Arcor2Exception as e: problems.append(str(e)) return problems
def patch_with_action_mapping(type_def: type[Generic], scene: CachedScene, project: CachedProject) -> None: setattr( type_def, ACTION_NAME_ID_MAPPING_ATTR, { act.name: act.id for act in project.actions if scene.object(act.parse_type().obj_id).type == type_def.__name__ }, )
def find_object_action(obj_types: ObjectTypeDict, scene: CachedScene, action: Action) -> ObjectAction: obj_id, action_type = action.parse_type() obj = scene.object(obj_id) obj_type = obj_types[obj.type] try: act = obj_type.actions[action_type] except KeyError: raise Arcor2Exception("Unknown type of action.") if act.disabled: raise Arcor2Exception("Action is disabled.") return act
def find_object_action(scene: CachedScene, action: common.Action) -> ObjectAction: obj_id, action_type = action.parse_type() obj = scene.object(obj_id) try: obj_type = glob.OBJECT_TYPES[obj.type] except KeyError: raise Arcor2Exception("Unknown object type.") try: act = obj_type.actions[action_type] except KeyError: raise Arcor2Exception("Unknown type of action.") if act.disabled: raise Arcor2Exception("Action is disabled.") return act
def get_parent_pose(scene: CScene, project: CProject, parent_id: str) -> Parent: """Returns pose of the parent and parent of the parent (if any). :param scene: :param project: :param parent_id: :return: """ if parent_id in scene.object_ids: parent_obj = scene.object(parent_id) if not parent_obj.pose: raise Arcor2Exception("Parent object does not have pose!") # TODO find parent object in the graph (SceneObject has "children" property) return Parent(parent_obj.pose, None) elif parent_id in project.action_points_ids: ap = project.bare_action_point(parent_id) return Parent(Pose(ap.position, Orientation()), ap.parent) else: raise Arcor2Exception(f"Unknown parent_id {parent_id}.")
def parameter_value(cls, type_defs: TypesDict, scene: CScene, project: CProject, action_id: str, parameter_id: str) -> Enum: action = project.action(action_id) param = action.parameter(parameter_id) obj_id, action_type = action.parse_type() obj_type_name = scene.object(obj_id).type try: obj_type = type_defs[obj_type_name] except KeyError: raise ParameterPluginException( f"Unknown object type {obj_type_name}.") try: method = getattr(obj_type, action_type) except AttributeError: raise ParameterPluginException( f"Object type {obj_type_name} does not have method {action_type}." ) try: ttype = get_type_hints(method)[param.name] except KeyError: raise ParameterPluginException( f"Method {obj_type}/{method.__name__} does not have parameter {param.name}." ) if not issubclass(ttype, cls.type()): raise ParameterPluginException( f"Type {ttype.__name__} is not subclass of {cls.type().__name__}." ) try: return ttype(json.loads(param.value)) except ValueError: raise ParameterPluginException( f"Parameter {parameter_id} of action {action.name} has invalid value." )
def check_action_params(scene: CachedScene, project: CachedProject, action: common.Action, object_action: ObjectAction) -> None: _, action_type = action.parse_type() assert action_type == object_action.name if len(object_action.parameters) != len(action.parameters): raise Arcor2Exception("Unexpected number of parameters.") for req_param in object_action.parameters: param = action.parameter(req_param.name) if param.type == common.ActionParameter.TypeEnum.PROJECT_PARAMETER: pparam = project.parameter(param.str_from_value()) param_meta = object_action.parameter(param.name) if param_meta.type != pparam.type: raise Arcor2Exception( "Action parameter type does not match project parameter type." ) elif param.type == common.ActionParameter.TypeEnum.LINK: parsed_link = param.parse_link() if parsed_link.action_id == action.id: raise Arcor2Exception("Can't use own result as a parameter.") parent_action = project.action(parsed_link.action_id) source_action_pt = parent_action.parse_type() parent_action_meta = glob.OBJECT_TYPES[scene.object( source_action_pt.obj_id).type].actions[ source_action_pt.action_type] if len(parent_action.flow(parsed_link.flow_name).outputs) != len( parent_action_meta.returns): raise Arcor2Exception( "Source action does not have outputs specified.") param_meta = object_action.parameter(param.name) try: if param_meta.type != parent_action_meta.returns[ parsed_link.output_index]: raise Arcor2Exception( "Param type does not match action output type.") except IndexError: raise Arcor2Exception( f"Index {parsed_link.output_index} is invalid for action {object_action.name}," f" which returns {len(object_action.returns)} values.") else: if param.type not in known_parameter_types(): raise Arcor2Exception( f"Parameter {param.name} of action {action.name} has unknown type: {param.type}." ) try: plugin_from_type_name(param.type).parameter_value( get_types_dict(), scene, project, action.id, param.name) except ParameterPluginException as e: raise Arcor2Exception( f"Parameter {param.name} of action {action.name} has invalid value. {str(e)}" )
def get_obj_type_data(scene: CachedScene, object_id: str) -> ObjectTypeData: return glob.OBJECT_TYPES[scene.object(object_id).type]
def get_obj_type_data(scene: CachedScene, object_id: str) -> ObjectTypeData: try: return glob.OBJECT_TYPES[scene.object(object_id).type] except KeyError: raise Arcor2Exception("Unknown object type.")
def get_action_name_to_id(scene: CachedScene, project: CachedProject, object_type: str) -> Dict[str, str]: return {act.name: act.id for act in project.actions if scene.object(act.parse_type().obj_id).type == object_type}