diff --git a/unilabos/registry/registry.py b/unilabos/registry/registry.py index dcaaf9f5..07667f99 100644 --- a/unilabos/registry/registry.py +++ b/unilabos/registry/registry.py @@ -1,5 +1,4 @@ import io -import json import os import sys from pathlib import Path @@ -7,10 +6,9 @@ from typing import Any import yaml -from unilabos.utils import logger from unilabos.ros.msgs.message_converter import msg_converter_manager, ros_action_to_json_schema +from unilabos.utils import logger from unilabos.utils.decorator import singleton -from unilabos.utils.type_check import TypeEncoder DEFAULT_PATHS = [Path(__file__).absolute().parent] @@ -21,10 +19,12 @@ class Registry: self.registry_paths = DEFAULT_PATHS.copy() # 使用copy避免修改默认值 if registry_paths: self.registry_paths.extend(registry_paths) - action_type = self._replace_type_with_class( + ResourceCreateFromOuter = self._replace_type_with_class( "ResourceCreateFromOuter", "host_node", f"动作 add_resource_from_outer" ) - schema = ros_action_to_json_schema(action_type) + ResourceCreateFromOuterEasy = self._replace_type_with_class( + "ResourceCreateFromOuterEasy", "host_node", f"动作 add_resource_from_outer_easy" + ) self.device_type_registry = { "host_node": { "description": "UniLabOS主机节点", @@ -46,7 +46,22 @@ class Registry: "result": { "success": "success" }, - "schema": schema + "schema": ros_action_to_json_schema(ResourceCreateFromOuter) + }, + "add_resource_from_outer_easy": { + "type": msg_converter_manager.search_class("ResourceCreateFromOuterEasy"), + "goal": { + "resources": "resources", + "device_ids": "device_ids", + "bind_parent_ids": "bind_parent_ids", + "bind_locations": "bind_locations", + "other_calling_params": "other_calling_params", + }, + "feedback": {}, + "result": { + "success": "success" + }, + "schema": ros_action_to_json_schema(ResourceCreateFromOuterEasy) } } }, diff --git a/unilabos/resources/graphio.py b/unilabos/resources/graphio.py index 2dff32a2..0a820131 100644 --- a/unilabos/resources/graphio.py +++ b/unilabos/resources/graphio.py @@ -421,7 +421,7 @@ def resource_plr_to_ulab(resource_plr: "ResourcePLR", parent_name: str = None): return r -def initialize_resource(resource_config: dict, lab_registry: dict) -> list[dict]: +def initialize_resource(resource_config: dict) -> list[dict]: """Initializes a resource based on its configuration. If the config is detailed, then do nothing; @@ -433,6 +433,7 @@ def initialize_resource(resource_config: dict, lab_registry: dict) -> list[dict] Returns: None """ + from unilabos.registry.registry import lab_registry resource_class_config = resource_config.get("class", None) if resource_class_config is None: return [resource_config] @@ -476,9 +477,8 @@ def initialize_resources(resources_config) -> list[dict]: None """ - from unilabos.registry.registry import lab_registry resources = [] for resource_config in resources_config: - resources.extend(initialize_resource(resource_config, lab_registry)) + resources.extend(initialize_resource(resource_config)) return resources diff --git a/unilabos/ros/nodes/base_device_node.py b/unilabos/ros/nodes/base_device_node.py index 335fee85..ca244206 100644 --- a/unilabos/ros/nodes/base_device_node.py +++ b/unilabos/ros/nodes/base_device_node.py @@ -320,6 +320,11 @@ class BaseROS2DeviceNode(Node, Generic[T]): other_calling_param = command_json["other_calling_param"] resources = command_json["resource"] initialize_full = other_calling_param.pop("initialize_full", False) + ADD_LIQUID_TYPE = other_calling_param.pop("ADD_LIQUID_TYPE", []) + LIQUID_VOLUME = other_calling_param.pop("LIQUID_VOLUME", []) + slot = other_calling_param.pop("slot", -1) + if slot >= 0: # slot为负数的时候采用assign方法 + other_calling_param["slot"] = slot # 本地拿到这个物料,可能需要先做初始化? if isinstance(resources, list): if initialize_full: diff --git a/unilabos/ros/nodes/presets/host_node.py b/unilabos/ros/nodes/presets/host_node.py index 4338872a..71826ae1 100644 --- a/unilabos/ros/nodes/presets/host_node.py +++ b/unilabos/ros/nodes/presets/host_node.py @@ -17,6 +17,7 @@ from unilabos_msgs.srv import ResourceAdd, ResourceGet, ResourceDelete, Resource from unique_identifier_msgs.msg import UUID from unilabos.registry.registry import lab_registry +from unilabos.resources.graphio import initialize_resource from unilabos.resources.registry import add_schema from unilabos.ros.initialize_device import initialize_device_from_dict from unilabos.ros.msgs.message_converter import ( @@ -141,7 +142,9 @@ class HostNode(BaseROS2DeviceNode): ].items(): controller_config["update_rate"] = update_rate self.initialize_controller(controller_id, controller_config) + resources_config.insert(0, { + }) try: for bridge in self.bridges: if hasattr(bridge, "resource_add"): @@ -292,6 +295,31 @@ class HostNode(BaseROS2DeviceNode): pass pass + def add_resource_from_outer_easy(self, device_id: str, res_id: str, class_name: str, parent: str, bind_locations: Point, liquid_input_slot: list[int], liquid_type: list[str], liquid_volume: list[int], slot_on_deck: int): + init_new_res = initialize_resource({ + "name": res_id, + "class": class_name, + "parent": parent, + "position": { + "x": bind_locations.x, + "y": bind_locations.y, + "z": bind_locations.z, + } + }) + resources = init_new_res + device_id = [device_id] + bind_parent_id = [parent] + bind_location = [bind_locations] + other_calling_param = [json.dumps({ + "ADD_LIQUID_TYPE": liquid_type, + "LIQUID_VOLUME": liquid_volume, + "LIQUID_INPUT_SLOT": liquid_input_slot, + "initialize_full": False, + "slot": slot_on_deck + })] + + return self.add_resource_from_outer(resources, device_id, bind_parent_id, bind_location, other_calling_param) + def initialize_device(self, device_id: str, device_config: Dict[str, Any]) -> None: """ 根据配置初始化设备, diff --git a/unilabos_msgs/action/ResourceCreateFromOuterEasy.action b/unilabos_msgs/action/ResourceCreateFromOuterEasy.action index f92ec2b4..bbd34810 100644 --- a/unilabos_msgs/action/ResourceCreateFromOuterEasy.action +++ b/unilabos_msgs/action/ResourceCreateFromOuterEasy.action @@ -1,10 +1,11 @@ -string id -string class +string res_id +string class_name string parent geometry_msgs/Point bind_locations int32[] liquid_input_slot string[] liquid_type float32[] liquid_volume +int32[] slot_on_deck --- bool success ---