临时兼容错误的driver写法

This commit is contained in:
Xuwznln
2025-08-12 19:20:53 +08:00
parent e8c1f76dbb
commit e570ba4976
5 changed files with 41 additions and 30 deletions

View File

@@ -340,14 +340,14 @@ def convert_resources_to_type(
Returns: Returns:
List of resources in the given type. List of resources in the given type.
""" """
if resource_type == dict: if resource_type == dict or resource_type == str:
return list_to_nested_dict(resources_list) return list_to_nested_dict(resources_list)
elif isinstance(resource_type, type) and issubclass(resource_type, ResourcePLR): elif isinstance(resource_type, type) and issubclass(resource_type, ResourcePLR):
if isinstance(resources_list, dict): if isinstance(resources_list, dict):
return resource_ulab_to_plr(resources_list, plr_model) return resource_ulab_to_plr(resources_list, plr_model)
resources_tree = dict_to_tree({r["id"]: r for r in resources_list}) resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
return resource_ulab_to_plr(resources_tree[0], plr_model) return resource_ulab_to_plr(resources_tree[0], plr_model)
elif isinstance(resource_type, list) : elif isinstance(resource_type, list):
if all((get_origin(t) is Union) for t in resource_type): if all((get_origin(t) is Union) for t in resource_type):
resources_tree = dict_to_tree({r["id"]: r for r in resources_list}) resources_tree = dict_to_tree({r["id"]: r for r in resources_list})
return [resource_ulab_to_plr(r, plr_model) for r in resources_tree] return [resource_ulab_to_plr(r, plr_model) for r in resources_tree]

View File

@@ -656,6 +656,7 @@ class BaseROS2DeviceNode(Node, Generic[T]):
action_kwargs = convert_from_ros_msg_with_mapping(goal, action_value_mapping["goal"]) action_kwargs = convert_from_ros_msg_with_mapping(goal, action_value_mapping["goal"])
self.lab_logger().debug(f"任务 {ACTION.__name__} 接收到原始目标: {action_kwargs}") self.lab_logger().debug(f"任务 {ACTION.__name__} 接收到原始目标: {action_kwargs}")
error_skip = False
# 向Host查询物料当前状态如果是host本身的增加物料的请求则直接跳过 # 向Host查询物料当前状态如果是host本身的增加物料的请求则直接跳过
if action_name not in ["create_resource_detailed", "create_resource"]: if action_name not in ["create_resource_detailed", "create_resource"]:
for k, v in goal.get_fields_and_field_types().items(): for k, v in goal.get_fields_and_field_types().items():
@@ -665,7 +666,7 @@ class BaseROS2DeviceNode(Node, Generic[T]):
# TODO: resource后面需要分组 # TODO: resource后面需要分组
only_one_resource = False only_one_resource = False
try: try:
if len(action_kwargs[k]) > 1: if isinstance(action_kwargs[k], list) and len(action_kwargs[k]) > 1:
for i in action_kwargs[k]: for i in action_kwargs[k]:
r = ResourceGet.Request() r = ResourceGet.Request()
r.id = i["id"] # splash optional r.id = i["id"] # splash optional
@@ -695,17 +696,43 @@ class BaseROS2DeviceNode(Node, Generic[T]):
final_resource = convert_resources_to_type(resources_list, final_type) final_resource = convert_resources_to_type(resources_list, final_type)
else: else:
final_resource = [convert_resources_to_type([i], final_type)[0] for i in resources_list] 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) try:
action_kwargs[k] = self.resource_tracker.figure_resource(final_resource)
except Exception as e:
self.lab_logger().error(f"物料实例获取失败: {e}\n{traceback.format_exc()}")
error_skip = True
execution_error = traceback.format_exc()
break
##### self.lab_logger().info(f"准备执行: {action_kwargs}, 函数: {ACTION.__name__}") ##### self.lab_logger().info(f"准备执行: {action_kwargs}, 函数: {ACTION.__name__}")
time_start = time.time() time_start = time.time()
time_overall = 100 time_overall = 100
future = None future = None
# 将阻塞操作放入线程池执行 if not error_skip:
if asyncio.iscoroutinefunction(ACTION): # 将阻塞操作放入线程池执行
try: if asyncio.iscoroutinefunction(ACTION):
##### self.lab_logger().info(f"异步执行动作 {ACTION}") try:
future = ROS2DeviceNode.run_async_func(ACTION, trace_error=False, **action_kwargs) ##### self.lab_logger().info(f"异步执行动作 {ACTION}")
future = ROS2DeviceNode.run_async_func(ACTION, trace_error=False, **action_kwargs)
def _handle_future_exception(fut):
nonlocal execution_error, execution_success, action_return_value
try:
action_return_value = fut.result()
execution_success = True
except Exception as e:
execution_error = traceback.format_exc()
error(f"异步任务 {ACTION.__name__} 报错了\n{traceback.format_exc()}\n原始输入:{action_kwargs}")
error(traceback.format_exc())
future.add_done_callback(_handle_future_exception)
except Exception as e:
execution_error = traceback.format_exc()
execution_success = False
self.lab_logger().error(f"创建异步任务失败: {traceback.format_exc()}")
else:
##### self.lab_logger().info(f"同步执行动作 {ACTION}")
future = self._executor.submit(ACTION, **action_kwargs)
def _handle_future_exception(fut): def _handle_future_exception(fut):
nonlocal execution_error, execution_success, action_return_value nonlocal execution_error, execution_success, action_return_value
@@ -713,28 +740,9 @@ class BaseROS2DeviceNode(Node, Generic[T]):
action_return_value = fut.result() action_return_value = fut.result()
execution_success = True execution_success = True
except Exception as e: except Exception as e:
execution_error = traceback.format_exc() error(f"同步任务 {ACTION.__name__} 报错了\n{traceback.format_exc()}\n原始输入:{action_kwargs}")
error(f"异步任务 {ACTION.__name__} 报错了\n{traceback.format_exc()}\n原始输入:{action_kwargs}")
error(traceback.format_exc())
future.add_done_callback(_handle_future_exception) future.add_done_callback(_handle_future_exception)
except Exception as e:
execution_error = traceback.format_exc()
execution_success = False
self.lab_logger().error(f"创建异步任务失败: {traceback.format_exc()}")
else:
##### self.lab_logger().info(f"同步执行动作 {ACTION}")
future = self._executor.submit(ACTION, **action_kwargs)
def _handle_future_exception(fut):
nonlocal execution_error, execution_success, action_return_value
try:
action_return_value = fut.result()
execution_success = True
except Exception as e:
error(f"同步任务 {ACTION.__name__} 报错了\n{traceback.format_exc()}\n原始输入:{action_kwargs}")
future.add_done_callback(_handle_future_exception)
action_type = action_value_mapping["type"] action_type = action_value_mapping["type"]
feedback_msg_types = action_type.Feedback.get_fields_and_field_types() feedback_msg_types = action_type.Feedback.get_fields_and_field_types()

View File

@@ -146,6 +146,7 @@ class ROS2ProtocolNode(BaseROS2DeviceNode):
# 为子设备的每个动作创建动作客户端 # 为子设备的每个动作创建动作客户端
if d is not None and hasattr(d, "ros_node_instance"): if d is not None and hasattr(d, "ros_node_instance"):
node = d.ros_node_instance node = d.ros_node_instance
node.resource_tracker = self.resource_tracker # 站内应当共享资源跟踪器
for action_name, action_mapping in node._action_value_mappings.items(): for action_name, action_mapping in node._action_value_mappings.items():
if action_name.startswith("auto-") or str(action_mapping.get("type", "")).startswith("UniLabJsonCommand"): if action_name.startswith("auto-") or str(action_mapping.get("type", "")).startswith("UniLabJsonCommand"):
continue continue

View File

@@ -37,6 +37,8 @@ class DeviceNodeResourceTracker(object):
def figure_resource(self, query_resource, try_mode=False): def figure_resource(self, query_resource, try_mode=False):
if isinstance(query_resource, list): if isinstance(query_resource, list):
return [self.figure_resource(r) for r in query_resource] return [self.figure_resource(r) for r in query_resource]
elif isinstance(query_resource, dict) and "id" not in query_resource and "name" not in query_resource: # 临时处理要删除的driver有太多类型错误标注
return [self.figure_resource(r) for r in query_resource.values()]
res_id = query_resource.id if hasattr(query_resource, "id") else (query_resource.get("id") if isinstance(query_resource, dict) else None) res_id = query_resource.id if hasattr(query_resource, "id") else (query_resource.get("id") if isinstance(query_resource, dict) else None)
res_name = query_resource.name if hasattr(query_resource, "name") else (query_resource.get("name") if isinstance(query_resource, dict) else None) res_name = query_resource.name if hasattr(query_resource, "name") else (query_resource.get("name") if isinstance(query_resource, dict) else None)
res_identifier = res_id if res_id else res_name res_identifier = res_id if res_id else res_name

View File

@@ -51,7 +51,7 @@ class DeviceClassCreator(Generic[T]):
""" """
if self.device_instance is not None: if self.device_instance is not None:
for c in self.children.values(): for c in self.children.values():
if c["type"] == "container": if c["type"] != "device":
self.resource_tracker.add_resource(c) self.resource_tracker.add_resource(c)