From 133dbf77bb50b3958c436cd3a869d13887ecaf0b Mon Sep 17 00:00:00 2001 From: Xuwznln <18435084+Xuwznln@users.noreply.github.com> Date: Fri, 16 May 2025 19:12:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B5=8C=E5=A5=97=E8=8A=82=E7=82=B9=E4=B8=8A?= =?UTF-8?q?=E6=8A=A5=E4=BA=91=E7=AB=AF=E5=87=BA=E7=8E=B0ID=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20(#27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复嵌套节点,mq发送任务id出错的问题 修正一处注册表命名错误 * 修复本地看板Action显示不全 修复本地子设备没有机器名称的bug * 补全vacuum_pump.mock注册信息 --- unilabos/app/web/utils/host_utils.py | 2 +- .../devices/organic_miscellaneous.yaml | 2 +- .../registry/devices/vacuum_and_purge.yaml | 19 +++++++++++++++++++ unilabos/registry/registry.py | 9 +++++++-- unilabos/ros/nodes/base_device_node.py | 5 +++++ unilabos/ros/nodes/presets/host_node.py | 16 +++++++++++++--- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/unilabos/app/web/utils/host_utils.py b/unilabos/app/web/utils/host_utils.py index a9070486..1400893b 100644 --- a/unilabos/app/web/utils/host_utils.py +++ b/unilabos/app/web/utils/host_utils.py @@ -42,7 +42,7 @@ def get_host_node_info() -> Dict[str, Any]: host_info["subscribed_topics"] = sorted(list(host_node._subscribed_topics)) # 获取动作客户端信息 for action_id, client in host_node._action_clients.items(): - host_info["action_clients"] = {action_id: get_action_info(client, full_name=action_id)} + host_info["action_clients"][action_id] = get_action_info(client, full_name=action_id) # 获取设备状态 host_info["device_status"] = host_node.device_status diff --git a/unilabos/registry/devices/organic_miscellaneous.yaml b/unilabos/registry/devices/organic_miscellaneous.yaml index a3f6f0e3..74551e7c 100644 --- a/unilabos/registry/devices/organic_miscellaneous.yaml +++ b/unilabos/registry/devices/organic_miscellaneous.yaml @@ -12,7 +12,7 @@ separator.homemade: goal: stir_time: stir_time, stir_speed: stir_speed - settling_time": settling_time + settling_time: settling_time feedback: status: status result: diff --git a/unilabos/registry/devices/vacuum_and_purge.yaml b/unilabos/registry/devices/vacuum_and_purge.yaml index 4981f2c4..236ceddc 100644 --- a/unilabos/registry/devices/vacuum_and_purge.yaml +++ b/unilabos/registry/devices/vacuum_and_purge.yaml @@ -3,6 +3,25 @@ vacuum_pump.mock: class: module: unilabos.devices.pump_and_valve.vacuum_pump_mock:VacuumPumpMock type: python + status_types: + status: String + action_value_mappings: + open: + type: EmptyIn + goal: {} + feedback: {} + result: {} + close: + type: EmptyIn + goal: {} + feedback: {} + result: {} + set_status: + type: StrSingleInput + goal: + string: string + feedback: {} + result: {} gas_source.mock: description: Mock gas source diff --git a/unilabos/registry/registry.py b/unilabos/registry/registry.py index dcaaf9f5..6381e022 100644 --- a/unilabos/registry/registry.py +++ b/unilabos/registry/registry.py @@ -169,8 +169,13 @@ class Registry: action_config["type"] = self._replace_type_with_class( action_config["type"], device_id, f"动作 {action_name}" ) - action_config["goal_default"] = yaml.safe_load(io.StringIO(get_yaml_from_goal_type(action_config["type"].Goal))) - action_config["schema"] = ros_action_to_json_schema(action_config["type"]) + if action_config["type"] is not None: + action_config["goal_default"] = yaml.safe_load(io.StringIO(get_yaml_from_goal_type(action_config["type"].Goal))) + action_config["schema"] = ros_action_to_json_schema(action_config["type"]) + else: + logger.warning( + f"[UniLab Registry] 设备 {device_id} 的动作 {action_name} 类型为空,跳过替换" + ) self.device_type_registry.update(data) diff --git a/unilabos/ros/nodes/base_device_node.py b/unilabos/ros/nodes/base_device_node.py index 078cb470..2b280af9 100644 --- a/unilabos/ros/nodes/base_device_node.py +++ b/unilabos/ros/nodes/base_device_node.py @@ -404,6 +404,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): # 加入全局注册表 registered_devices[self.device_id] = device_info from unilabos.config.config import BasicConfig + from unilabos.ros.nodes.presets.host_node import HostNode if not BasicConfig.is_host_mode: sclient = self.create_client(SerialCommand, "/node_info_update") # 启动线程执行发送任务 @@ -413,6 +414,10 @@ class BaseROS2DeviceNode(Node, Generic[T]): daemon=True, name=f"ROSDevice{self.device_id}_send_slave_node_info" ).start() + else: + host_node = HostNode.get_instance(0) + if host_node is not None: + host_node.device_machine_names[self.device_id] = "本地" def send_slave_node_info(self, sclient): sclient.wait_for_service() diff --git a/unilabos/ros/nodes/presets/host_node.py b/unilabos/ros/nodes/presets/host_node.py index 4338872a..cb1e1c6a 100644 --- a/unilabos/ros/nodes/presets/host_node.py +++ b/unilabos/ros/nodes/presets/host_node.py @@ -141,12 +141,22 @@ class HostNode(BaseROS2DeviceNode): ].items(): controller_config["update_rate"] = update_rate self.initialize_controller(controller_id, controller_config) - + resource_with_parent_name = [] + resource_ids_to_instance = {i["id"]: i for i in resources_config} + for res in resources_config: + if res.get("parent") and res.get("type") == "device" and res.get("class"): + parent_id = res.get("parent") + parent_res = resource_ids_to_instance[parent_id] + if parent_res.get("type") == "device" and parent_res.get("class"): + resource_with_parent_name.append(copy.deepcopy(res)) + resource_with_parent_name[-1]["id"] = f"{parent_res['id']}/{res['id']}" + continue + resource_with_parent_name.append(copy.deepcopy(res)) try: for bridge in self.bridges: if hasattr(bridge, "resource_add"): self.lab_logger().info("[Host Node-Resource] Adding resources to bridge.") - bridge.resource_add(add_schema(resources_config)) + resource_add_res = bridge.resource_add(add_schema(resource_with_parent_name)) except Exception as ex: self.lab_logger().error("[Host Node-Resource] 添加物料出错!") self.lab_logger().error(traceback.format_exc()) @@ -191,7 +201,7 @@ class HostNode(BaseROS2DeviceNode): # 如果是新设备,记录并创建ActionClient if edge_device_id not in self.devices_names: - self.lab_logger().info(f"[Host Node] Discovered new device: {device_key}") + self.lab_logger().info(f"[Host Node] Discovered new device: {edge_device_id}") self.devices_names[edge_device_id] = namespace self._create_action_clients_for_device(device_id, namespace) self._online_devices.add(device_key)