diff --git a/README.md b/README.md index 918e6fa..8568fb3 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ conda env update --file unilabos-[YOUR_OS].yml -n environment_name # Currently, you need to install the `unilabos_msgs` package # You can download the system-specific package from the Release page -conda install ros-humble-unilabos-msgs-0.9.10-xxxxx.tar.bz2 +conda install ros-humble-unilabos-msgs-0.9.12-xxxxx.tar.bz2 # Install PyLabRobot and other prerequisites git clone https://github.com/PyLabRobot/pylabrobot plr_repo diff --git a/unilabos/compile/stir_protocol.py b/unilabos/compile/stir_protocol.py index e635e9f..70405ff 100644 --- a/unilabos/compile/stir_protocol.py +++ b/unilabos/compile/stir_protocol.py @@ -181,7 +181,7 @@ def get_vessel_display_info(vessel: Union[str, dict]) -> str: def generate_stir_protocol( G: nx.DiGraph, - vessel: Union[str, dict], # 🔧 修改:支持vessel字典 + vessel: Union[str, dict], # 支持vessel字典或字符串 time: Union[str, float, int] = "300", stir_time: Union[str, float, int] = "0", time_spec: str = "", @@ -190,28 +190,35 @@ def generate_stir_protocol( settling_time: Union[str, float] = "60", **kwargs ) -> List[Dict[str, Any]]: - """ - 生成搅拌操作的协议序列 - 支持vessel字典 + """生成搅拌操作的协议序列 - 修复vessel参数传递""" - Args: - G: 有向图,节点为设备和容器,边为流体管道 - vessel: 搅拌容器字典(从XDL传入)或容器ID字符串 - time: 搅拌时间(支持 "300", "5 min", "1 h" 等格式) - stir_time: 指定搅拌时间(优先级比time低) - time_spec: 时间规格(优先级最高) - event: 事件描述 - stir_speed: 搅拌速度(RPM) - settling_time: 沉降时间 - **kwargs: 其他可选参数 - - Returns: - List[Dict[str, Any]]: 搅拌操作的动作序列 - """ - - # 🔧 核心修改:从vessel参数中提取vessel_id + # 🔧 核心修改:正确处理vessel参数 vessel_id = extract_vessel_id(vessel) vessel_display = get_vessel_display_info(vessel) + # 🔧 关键修复:确保vessel_resource是完整的Resource对象 + if isinstance(vessel, dict): + vessel_resource = vessel # 已经是完整的Resource字典 + debug_print(f"✅ 使用传入的vessel Resource对象") + else: + # 如果只是字符串,构建一个基本的Resource对象 + vessel_resource = { + "id": vessel, + "name": "", + "category": "", + "children": [], + "config": "", + "data": "", + "parent": "", + "pose": { + "orientation": {"w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0}, + "position": {"x": 0.0, "y": 0.0, "z": 0.0} + }, + "sample_id": "", + "type": "" + } + debug_print(f"🔧 构建了基本的vessel Resource对象: {vessel}") + debug_print("🌪️" * 20) debug_print("🚀 开始生成搅拌协议(支持vessel字典)✨") debug_print(f"📝 输入参数:") @@ -293,13 +300,14 @@ def generate_stir_protocol( "device_id": stirrer_id, "action_name": "stir", "action_kwargs": { - "vessel": vessel_id, # 🔧 使用 vessel_id - "time": str(time), # 保持原始格式 + # 🔧 关键修复:传递vessel_id字符串,而不是完整的Resource对象 + "vessel": vessel_id, # 传递字符串ID,不是Resource对象 + "time": str(time), "event": event, "time_spec": time_spec, - "stir_time": float(parsed_time), # 确保是数字 - "stir_speed": float(stir_speed), # 确保是数字 - "settling_time": float(parsed_settling_time) # 确保是数字 + "stir_time": float(parsed_time), + "stir_speed": float(stir_speed), + "settling_time": float(parsed_settling_time) } } action_sequence.append(stir_action) @@ -324,36 +332,47 @@ def generate_stir_protocol( def generate_start_stir_protocol( G: nx.DiGraph, - vessel: Union[str, dict], # 🔧 修改:支持vessel字典 + vessel: Union[str, dict], stir_speed: float = 300.0, purpose: str = "", **kwargs ) -> List[Dict[str, Any]]: - """ - 生成开始搅拌操作的协议序列 - 支持vessel字典 + """生成开始搅拌操作的协议序列 - 修复vessel参数传递""" - Args: - G: 有向图 - vessel: 搅拌容器字典或容器ID字符串 - stir_speed: 搅拌速度(RPM) - purpose: 搅拌目的描述 - **kwargs: 其他可选参数 - - Returns: - List[Dict[str, Any]]: 开始搅拌操作的动作序列 - """ - - # 🔧 核心修改:从vessel参数中提取vessel_id + # 🔧 核心修改:正确处理vessel参数 vessel_id = extract_vessel_id(vessel) vessel_display = get_vessel_display_info(vessel) - debug_print("🔄 开始生成启动搅拌协议(支持vessel字典)✨") + # 🔧 关键修复:确保vessel_resource是完整的Resource对象 + if isinstance(vessel, dict): + vessel_resource = vessel # 已经是完整的Resource字典 + debug_print(f"✅ 使用传入的vessel Resource对象") + else: + # 如果只是字符串,构建一个基本的Resource对象 + vessel_resource = { + "id": vessel, + "name": "", + "category": "", + "children": [], + "config": "", + "data": "", + "parent": "", + "pose": { + "orientation": {"w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0}, + "position": {"x": 0.0, "y": 0.0, "z": 0.0} + }, + "sample_id": "", + "type": "" + } + debug_print(f"🔧 构建了基本的vessel Resource对象: {vessel}") + + debug_print("🔄 开始生成启动搅拌协议(修复vessel参数)✨") debug_print(f"🥽 vessel: {vessel_display} (ID: {vessel_id})") debug_print(f"🌪️ speed: {stir_speed} RPM") debug_print(f"🎯 purpose: {purpose}") # 基础验证 - if not vessel_id or vessel_id not in G.nodes(): # 🔧 使用 vessel_id + if not vessel_id or vessel_id not in G.nodes(): debug_print("❌ 容器验证失败!") raise ValueError("vessel 参数无效") @@ -363,14 +382,15 @@ def generate_start_stir_protocol( stir_speed = 300.0 # 查找设备 - stirrer_id = find_connected_stirrer(G, vessel_id) # 🔧 使用 vessel_id + stirrer_id = find_connected_stirrer(G, vessel_id) - # 生成动作 + # 🔧 关键修复:传递vessel_id字符串 action_sequence = [{ "device_id": stirrer_id, "action_name": "start_stir", "action_kwargs": { - "vessel": vessel_id, # 🔧 使用 vessel_id + # 🔧 关键修复:传递vessel_id字符串,而不是完整的Resource对象 + "vessel": vessel_id, # 传递字符串ID,不是Resource对象 "stir_speed": stir_speed, "purpose": purpose or f"启动搅拌 {stir_speed} RPM" } @@ -381,42 +401,56 @@ def generate_start_stir_protocol( def generate_stop_stir_protocol( G: nx.DiGraph, - vessel: Union[str, dict], # 🔧 修改:支持vessel字典 + vessel: Union[str, dict], **kwargs ) -> List[Dict[str, Any]]: - """ - 生成停止搅拌操作的协议序列 - 支持vessel字典 + """生成停止搅拌操作的协议序列 - 修复vessel参数传递""" - Args: - G: 有向图 - vessel: 搅拌容器字典或容器ID字符串 - **kwargs: 其他可选参数 - - Returns: - List[Dict[str, Any]]: 停止搅拌操作的动作序列 - """ - - # 🔧 核心修改:从vessel参数中提取vessel_id + # 🔧 核心修改:正确处理vessel参数 vessel_id = extract_vessel_id(vessel) vessel_display = get_vessel_display_info(vessel) - debug_print("🛑 开始生成停止搅拌协议(支持vessel字典)✨") + # 🔧 关键修复:确保vessel_resource是完整的Resource对象 + if isinstance(vessel, dict): + vessel_resource = vessel # 已经是完整的Resource字典 + debug_print(f"✅ 使用传入的vessel Resource对象") + else: + # 如果只是字符串,构建一个基本的Resource对象 + vessel_resource = { + "id": vessel, + "name": "", + "category": "", + "children": [], + "config": "", + "data": "", + "parent": "", + "pose": { + "orientation": {"w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0}, + "position": {"x": 0.0, "y": 0.0, "z": 0.0} + }, + "sample_id": "", + "type": "" + } + debug_print(f"🔧 构建了基本的vessel Resource对象: {vessel}") + + debug_print("🛑 开始生成停止搅拌协议(修复vessel参数)✨") debug_print(f"🥽 vessel: {vessel_display} (ID: {vessel_id})") # 基础验证 - if not vessel_id or vessel_id not in G.nodes(): # 🔧 使用 vessel_id + if not vessel_id or vessel_id not in G.nodes(): debug_print("❌ 容器验证失败!") raise ValueError("vessel 参数无效") # 查找设备 - stirrer_id = find_connected_stirrer(G, vessel_id) # 🔧 使用 vessel_id + stirrer_id = find_connected_stirrer(G, vessel_id) - # 生成动作 + # 🔧 关键修复:传递vessel_id字符串 action_sequence = [{ "device_id": stirrer_id, "action_name": "stop_stir", "action_kwargs": { - "vessel": vessel_id # 🔧 使用 vessel_id + # 🔧 关键修复:传递vessel_id字符串,而不是完整的Resource对象 + "vessel": vessel_id # 传递字符串ID,不是Resource对象 } }] diff --git a/unilabos/registry/devices/virtual_device.yaml b/unilabos/registry/devices/virtual_device.yaml index 2ad2c5b..acaed03 100644 --- a/unilabos/registry/devices/virtual_device.yaml +++ b/unilabos/registry/devices/virtual_device.yaml @@ -3650,3 +3650,176 @@ virtual_vacuum_pump: - status type: object version: 0.0.1 +virtual_solid_dispenser: + class: + action_value_mappings: + auto-cleanup: + feedback: {} + goal: {} + goal_default: {} + handles: [] + result: {} + schema: + description: cleanup的参数schema + properties: + feedback: {} + goal: + properties: {} + type: object + result: {} + required: + - goal + title: cleanup参数 + type: object + type: UniLabJsonCommandAsync + auto-initialize: + feedback: {} + goal: {} + goal_default: {} + handles: [] + result: {} + schema: + description: initialize的参数schema + properties: + feedback: {} + goal: + properties: {} + type: object + result: {} + required: + - goal + title: initialize参数 + type: object + type: UniLabJsonCommandAsync + add_solid: + feedback: + current_status: status + progress: progress + goal: + vessel: vessel + reagent: reagent + mass: mass + mol: mol + purpose: purpose + event: event + rate_spec: rate_spec + equiv: equiv + ratio: ratio + goal_default: + vessel: '' + reagent: '' + mass: '' + mol: '' + purpose: '' + event: '' + rate_spec: '' + equiv: '' + ratio: '' + handles: [] + result: + success: success + message: message + return_info: return_info + schema: + description: '' + properties: + feedback: + properties: + current_status: + type: string + progress: + type: number + type: object + goal: + properties: + vessel: + type: string + reagent: + type: string + mass: + type: string + mol: + type: string + purpose: + type: string + event: + type: string + rate_spec: + type: string + equiv: + type: string + ratio: + type: string + type: object + result: + properties: + success: + type: boolean + message: + type: string + return_info: + type: string + type: object + required: + - goal + title: AddSolid + type: object + type: Add # 🔧 使用 Add action type + module: unilabos.devices.virtual.virtual_solid_dispenser:VirtualSolidDispenser + status_types: + status: str + current_reagent: str + dispensed_amount: float + total_operations: int + type: python + description: Virtual Solid Dispenser for Add Protocol Testing - supports mass and molar additions + handles: + - data_key: solid_out + data_source: executor + data_type: resource + description: 固体试剂输出口 + handler_key: SolidOut + io_type: source + label: SolidOut + side: SOUTH + - data_key: solid_in + data_source: handle + data_type: resource + description: 固体试剂输入口(连接试剂瓶) + handler_key: SolidIn + io_type: target + label: SolidIn + side: NORTH + icon: '' + init_param_schema: + config: + properties: + max_capacity: + default: 100.0 + type: number + precision: + default: 0.001 + type: number + config: + type: object + device_id: + type: string + required: [] + type: object + data: + properties: + status: + type: string + current_reagent: + type: string + dispensed_amount: + type: number + total_operations: + type: integer + required: + - status + - current_reagent + - dispensed_amount + - total_operations + type: object + version: 0.0.1 \ No newline at end of file diff --git a/unilabos/ros/msgs/message_converter.py b/unilabos/ros/msgs/message_converter.py index 57f93ed..2102058 100644 --- a/unilabos/ros/msgs/message_converter.py +++ b/unilabos/ros/msgs/message_converter.py @@ -509,68 +509,68 @@ def convert_from_ros_msg_with_mapping(ros_msg: Any, value_mapping: Dict[str, str """ data: Dict[str, Any] = {} - # 🔧 添加调试信息 - print(f"🔍 convert_from_ros_msg_with_mapping 开始") - print(f"🔍 ros_msg 类型: {type(ros_msg)}") - print(f"🔍 ros_msg 内容: {ros_msg}") - print(f"🔍 value_mapping: {value_mapping}") - print("-" * 60) + # # 🔧 添加调试信息 + # print(f"🔍 convert_from_ros_msg_with_mapping 开始") + # print(f"🔍 ros_msg 类型: {type(ros_msg)}") + # print(f"🔍 ros_msg 内容: {ros_msg}") + # print(f"🔍 value_mapping: {value_mapping}") + # print("-" * 60) for msg_name, attr_name in value_mapping.items(): - print(f"🔍 处理映射: {msg_name} -> {attr_name}") + # print(f"🔍 处理映射: {msg_name} -> {attr_name}") msg_path = msg_name.split(".") current = ros_msg - print(f"🔍 msg_path: {msg_path}") - print(f"🔍 current 初始值: {current} (类型: {type(current)})") + # print(f"🔍 msg_path: {msg_path}") + # print(f"🔍 current 初始值: {current} (类型: {type(current)})") try: if not attr_name.endswith("[]"): # 处理单值映射 - print(f"🔍 处理单值映射") + # print(f"🔍 处理单值映射") for i, name in enumerate(msg_path): - print(f"🔍 步骤 {i}: 获取属性 '{name}' 从 {type(current)}") + # print(f"🔍 步骤 {i}: 获取属性 '{name}' 从 {type(current)}") if hasattr(current, name): current = getattr(current, name) - print(f"🔍 获取到: {current} (类型: {type(current)})") + # print(f"🔍 获取到: {current} (类型: {type(current)})") else: - print(f"❌ 属性 '{name}' 不存在于 {type(current)}") + # print(f"❌ 属性 '{name}' 不存在于 {type(current)}") break converted_value = convert_from_ros_msg(current) - print(f"🔍 转换后的值: {converted_value} (类型: {type(converted_value)})") + # print(f"🔍 转换后的值: {converted_value} (类型: {type(converted_value)})") data[attr_name] = converted_value - print(f"✅ 设置 data['{attr_name}'] = {converted_value}") + # print(f"✅ 设置 data['{attr_name}'] = {converted_value}") else: # 处理列表值映射 - print(f"🔍 处理列表值映射") + # print(f"🔍 处理列表值映射") for i, name in enumerate(msg_path): - print(f"🔍 列表步骤 {i}: 处理 '{name}' 从 {type(current)}") + # print(f"🔍 列表步骤 {i}: 处理 '{name}' 从 {type(current)}") if name.endswith("[]"): base_name = name[:-2] - print(f"🔍 数组字段 base_name: '{base_name}'") + # print(f"🔍 数组字段 base_name: '{base_name}'") if hasattr(current, base_name): current = list(getattr(current, base_name)) - print(f"🔍 获取数组: {current} (长度: {len(current)})") + # print(f"🔍 获取数组: {current} (长度: {len(current)})") else: - print(f"❌ 数组字段 '{base_name}' 不存在") + # print(f"❌ 数组字段 '{base_name}' 不存在") current = [] break else: if isinstance(current, list): - print(f"🔍 从列表中获取属性 '{name}'") + # print(f"🔍 从列表中获取属性 '{name}'") next_level = [] for item in current: if hasattr(item, name): next_level.append(getattr(item, name)) current = next_level - print(f"🔍 列表处理结果: {current} (长度: {len(current)})") + # print(f"🔍 列表处理结果: {current} (长度: {len(current)})") elif hasattr(current, name): current = getattr(current, name) - print(f"🔍 获取到属性: {current} (类型: {type(current)})") + # print(f"🔍 获取到属性: {current} (类型: {type(current)})") else: - print(f"❌ 属性 '{name}' 不存在") + # print(f"❌ 属性 '{name}' 不存在") current = [] break @@ -578,20 +578,20 @@ def convert_from_ros_msg_with_mapping(ros_msg: Any, value_mapping: Dict[str, str if current: converted_list = [convert_from_ros_msg(item) for item in current] data[attr_key] = converted_list - print(f"✅ 设置 data['{attr_key}'] = {converted_list}") + # print(f"✅ 设置 data['{attr_key}'] = {converted_list}") else: print(f"⚠️ 列表为空,跳过 '{attr_key}'") except (AttributeError, TypeError) as e: - print(f"❌ 映射转换错误 {msg_name} -> {attr_name}: {e}") + # print(f"❌ 映射转换错误 {msg_name} -> {attr_name}: {e}") logger.debug(f"Mapping conversion error for {msg_name} -> {attr_name}") continue - print(f"🔍 当前 data 状态: {data}") - print("-" * 40) + # print(f"🔍 当前 data 状态: {data}") + # print("-" * 40) - print(f"🔍 convert_from_ros_msg_with_mapping 结束") - print(f"🔍 最终 data: {data}") - print("=" * 60) + #print(f"🔍 convert_from_ros_msg_with_mapping 结束") + #print(f"🔍 最终 data: {data}") + #print("=" * 60) return data diff --git a/unilabos/ros/nodes/base_device_node.py b/unilabos/ros/nodes/base_device_node.py index b226edc..53dbc74 100644 --- a/unilabos/ros/nodes/base_device_node.py +++ b/unilabos/ros/nodes/base_device_node.py @@ -629,7 +629,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): execution_success = False action_return_value = None - self.lab_logger().info(f"执行动作: {action_name}") + ##### self.lab_logger().info(f"执行动作: {action_name}") goal = goal_handle.request # 从目标消息中提取参数, 并调用对应的方法 @@ -685,14 +685,14 @@ class BaseROS2DeviceNode(Node, Generic[T]): final_resource = [convert_resources_to_type([i], final_type)[0] for i in resources_list] action_kwargs[k] = self.resource_tracker.figure_resource(final_resource) - self.lab_logger().info(f"准备执行: {action_kwargs}, 函数: {ACTION.__name__}") + ##### self.lab_logger().info(f"准备执行: {action_kwargs}, 函数: {ACTION.__name__}") time_start = time.time() time_overall = 100 # 将阻塞操作放入线程池执行 if asyncio.iscoroutinefunction(ACTION): try: - self.lab_logger().info(f"异步执行动作 {ACTION}") + ##### self.lab_logger().info(f"异步执行动作 {ACTION}") future = ROS2DeviceNode.run_async_func(ACTION, trace_error=False, **action_kwargs) def _handle_future_exception(fut): @@ -702,7 +702,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): execution_success = True except Exception as e: execution_error = traceback.format_exc() - error(f"异步任务 {ACTION.__name__} 报错了") + ##### error(f"异步任务 {ACTION.__name__} 报错了") error(traceback.format_exc()) future.add_done_callback(_handle_future_exception) @@ -710,7 +710,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): self.lab_logger().error(f"创建异步任务失败: {traceback.format_exc()}") raise e else: - self.lab_logger().info(f"同步执行动作 {ACTION}") + ##### self.lab_logger().info(f"同步执行动作 {ACTION}") future = self._executor.submit(ACTION, **action_kwargs) def _handle_future_exception(fut): @@ -765,7 +765,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): self.lab_logger().info(f"动作 {action_name} 已取消") return action_type.Result() - self.lab_logger().info(f"动作执行完成: {action_name}") + ##### self.lab_logger().info(f"动作执行完成: {action_name}") del future # 向Host更新物料当前状态 @@ -801,7 +801,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): # 发布结果 goal_handle.succeed() - self.lab_logger().info(f"设置动作成功: {action_name}") + ##### self.lab_logger().info(f"设置动作成功: {action_name}") result_values = {} for msg_name, attr_name in action_value_mapping["result"].items(): @@ -820,7 +820,7 @@ class BaseROS2DeviceNode(Node, Generic[T]): elif attr_name == "return_info": setattr(result_msg, attr_name, serialize_result_info(execution_error, execution_success, action_return_value)) - self.lab_logger().info(f"动作 {action_name} 完成并返回结果") + ##### self.lab_logger().info(f"动作 {action_name} 完成并返回结果") return result_msg return execute_callback diff --git a/unilabos/ros/nodes/presets/host_node.py b/unilabos/ros/nodes/presets/host_node.py index a1cfd0a..8356563 100644 --- a/unilabos/ros/nodes/presets/host_node.py +++ b/unilabos/ros/nodes/presets/host_node.py @@ -562,9 +562,9 @@ class HostNode(BaseROS2DeviceNode): for bridge in self.bridges: if hasattr(bridge, "publish_device_status"): bridge.publish_device_status(self.device_status, device_id, property_name) - #self.lab_logger().debug( - # f"[Host Node] Status updated: {device_id}.{property_name} = {msg.data}" - #) + self.lab_logger().debug( + f"[Host Node] Status updated: {device_id}.{property_name} = {msg.data}" + ) def send_goal( self, diff --git a/unilabos/ros/nodes/presets/protocol_node.py b/unilabos/ros/nodes/presets/protocol_node.py index 16080e0..a17d4e9 100644 --- a/unilabos/ros/nodes/presets/protocol_node.py +++ b/unilabos/ros/nodes/presets/protocol_node.py @@ -183,25 +183,25 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): goal = goal_handle.request protocol_kwargs = convert_from_ros_msg_with_mapping(goal, action_value_mapping["goal"]) - # 🔧 添加调试信息 - print(f"🔍 转换后的 protocol_kwargs: {protocol_kwargs}") - print(f"🔍 vessel 在转换后: {protocol_kwargs.get('vessel', 'NOT_FOUND')}") + # # 🔧 添加调试信息 + # print(f"🔍 转换后的 protocol_kwargs: {protocol_kwargs}") + # print(f"🔍 vessel 在转换后: {protocol_kwargs.get('vessel', 'NOT_FOUND')}") - # 🔧 完全禁用Host查询,直接使用转换后的数据 - print(f"🔧 跳过Host查询,直接使用转换后的数据") + # # 🔧 完全禁用Host查询,直接使用转换后的数据 + # print(f"🔧 跳过Host查询,直接使用转换后的数据") # 🔧 额外验证:确保vessel数据完整 if 'vessel' in protocol_kwargs: vessel_data = protocol_kwargs['vessel'] - print(f"🔍 验证vessel数据: {vessel_data}") + #print(f"🔍 验证vessel数据: {vessel_data}") # 如果vessel是空字典,尝试重新构建 if not vessel_data or (isinstance(vessel_data, dict) and not vessel_data): - print(f"⚠️ vessel数据为空,尝试从原始goal重新提取...") + # print(f"⚠️ vessel数据为空,尝试从原始goal重新提取...") # 直接从原始goal提取vessel if hasattr(goal, 'vessel') and goal.vessel: - print(f"🔍 原始goal.vessel: {goal.vessel}") + # print(f"🔍 原始goal.vessel: {goal.vessel}") # 手动转换vessel vessel_data = { 'id': goal.vessel.id, @@ -212,16 +212,16 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): 'data': goal.vessel.data } protocol_kwargs['vessel'] = vessel_data - print(f"✅ 手动重建vessel数据: {vessel_data}") + # print(f"✅ 手动重建vessel数据: {vessel_data}") else: - print(f"❌ 无法从原始goal提取vessel数据") + # print(f"❌ 无法从原始goal提取vessel数据") # 创建一个基本的vessel vessel_data = {'id': 'default_vessel'} protocol_kwargs['vessel'] = vessel_data - print(f"🔧 创建默认vessel: {vessel_data}") + # print(f"🔧 创建默认vessel: {vessel_data}") - print(f"🔍 最终传递给协议的 protocol_kwargs: {protocol_kwargs}") - print(f"🔍 最终的 vessel: {protocol_kwargs.get('vessel', 'NOT_FOUND')}") + #print(f"🔍 最终传递给协议的 protocol_kwargs: {protocol_kwargs}") + #print(f"🔍 最终的 vessel: {protocol_kwargs.get('vessel', 'NOT_FOUND')}") from unilabos.resources.graphio import physical_setup_graph @@ -315,7 +315,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): serialize_result_info(execution_error, execution_success, protocol_return_value), ) - self.lab_logger().info(f"协议 {protocol_name} 完成并返回结果") + self.lab_logger().info(f"🤩🤩🤩🤩🤩🤩协议 {protocol_name} 完成并返回结果😎😎😎😎😎😎") return result return execute_protocol @@ -337,7 +337,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): action_client = self._action_clients[action_id] goal_msg = convert_to_ros_msg(action_client._action_type.Goal(), action_kwargs) - self.lab_logger().info(f"发送动作请求到: {action_id}") + ##### self.lab_logger().info(f"发送动作请求到: {action_id}") action_client.wait_for_server() # 等待动作完成 @@ -349,7 +349,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode): return None result_future = await handle.get_result_async() - self.lab_logger().info(f"动作完成: {action_name}") + ##### self.lab_logger().info(f"动作完成: {action_name}") return result_future.result