mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
fix run async execution error
This commit is contained in:
@@ -53,7 +53,7 @@ from unilabos.ros.nodes.resource_tracker import (
|
|||||||
)
|
)
|
||||||
from unilabos.ros.x.rclpyx import get_event_loop
|
from unilabos.ros.x.rclpyx import get_event_loop
|
||||||
from unilabos.ros.utils.driver_creator import WorkstationNodeCreator, PyLabRobotCreator, DeviceClassCreator
|
from unilabos.ros.utils.driver_creator import WorkstationNodeCreator, PyLabRobotCreator, DeviceClassCreator
|
||||||
from unilabos.utils.async_util import run_async_func
|
from rclpy.task import Task
|
||||||
from unilabos.utils.import_manager import default_manager
|
from unilabos.utils.import_manager import default_manager
|
||||||
from unilabos.utils.log import info, debug, warning, error, critical, logger, trace
|
from unilabos.utils.log import info, debug, warning, error, critical, logger, trace
|
||||||
from unilabos.utils.type_check import get_type_class, TypeEncoder, get_result_info_str
|
from unilabos.utils.type_check import get_type_class, TypeEncoder, get_result_info_str
|
||||||
@@ -1385,18 +1385,19 @@ class ROS2DeviceNode:
|
|||||||
它不继承设备类,而是通过代理模式访问设备类的属性和方法。
|
它不继承设备类,而是通过代理模式访问设备类的属性和方法。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 类变量,用于循环管理
|
|
||||||
_loop = None
|
|
||||||
_loop_running = False
|
|
||||||
_loop_thread = None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_loop(cls):
|
def run_async_func(cls, func, trace_error=True, **kwargs) -> Task:
|
||||||
return cls._loop
|
def _handle_future_exception(fut):
|
||||||
|
try:
|
||||||
|
fut.result()
|
||||||
|
except Exception as e:
|
||||||
|
error(f"异步任务 {func.__name__} 报错了")
|
||||||
|
error(traceback.format_exc())
|
||||||
|
|
||||||
@classmethod
|
future = rclpy.get_global_executor().create_task(func(**kwargs))
|
||||||
def run_async_func(cls, func, trace_error=True, **kwargs):
|
if trace_error:
|
||||||
return run_async_func(func, loop=cls._loop, trace_error=trace_error, **kwargs)
|
future.add_done_callback(_handle_future_exception)
|
||||||
|
return future
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def driver_instance(self):
|
def driver_instance(self):
|
||||||
@@ -1436,11 +1437,6 @@ class ROS2DeviceNode:
|
|||||||
print_publish: 是否打印发布信息
|
print_publish: 是否打印发布信息
|
||||||
driver_is_ros:
|
driver_is_ros:
|
||||||
"""
|
"""
|
||||||
# 在初始化时检查循环状态
|
|
||||||
if ROS2DeviceNode._loop_running and ROS2DeviceNode._loop_thread is not None:
|
|
||||||
pass
|
|
||||||
elif ROS2DeviceNode._loop_thread is None:
|
|
||||||
self._start_loop()
|
|
||||||
|
|
||||||
# 保存设备类是否支持异步上下文
|
# 保存设备类是否支持异步上下文
|
||||||
self._has_async_context = hasattr(driver_class, "__aenter__") and hasattr(driver_class, "__aexit__")
|
self._has_async_context = hasattr(driver_class, "__aenter__") and hasattr(driver_class, "__aexit__")
|
||||||
@@ -1529,17 +1525,6 @@ class ROS2DeviceNode:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._ros_node.lab_logger().error(f"设备后初始化失败: {e}")
|
self._ros_node.lab_logger().error(f"设备后初始化失败: {e}")
|
||||||
|
|
||||||
def _start_loop(self):
|
|
||||||
def run_event_loop():
|
|
||||||
loop = asyncio.new_event_loop()
|
|
||||||
ROS2DeviceNode._loop = loop
|
|
||||||
asyncio.set_event_loop(loop)
|
|
||||||
loop.run_forever()
|
|
||||||
|
|
||||||
ROS2DeviceNode._loop_thread = threading.Thread(target=run_event_loop, daemon=True, name="ROS2DeviceNodeLoop")
|
|
||||||
ROS2DeviceNode._loop_thread.start()
|
|
||||||
logger.info(f"循环线程已启动")
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceInfoType(TypedDict):
|
class DeviceInfoType(TypedDict):
|
||||||
id: str
|
id: str
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
import traceback
|
|
||||||
from asyncio import get_event_loop
|
|
||||||
|
|
||||||
from unilabos.utils.log import error
|
|
||||||
|
|
||||||
|
|
||||||
def run_async_func(func, *, loop=None, trace_error=True, **kwargs):
|
|
||||||
if loop is None:
|
|
||||||
loop = get_event_loop()
|
|
||||||
|
|
||||||
def _handle_future_exception(fut):
|
|
||||||
try:
|
|
||||||
fut.result()
|
|
||||||
except Exception as e:
|
|
||||||
error(f"异步任务 {func.__name__} 报错了")
|
|
||||||
error(traceback.format_exc())
|
|
||||||
|
|
||||||
future = asyncio.run_coroutine_threadsafe(func(**kwargs), loop)
|
|
||||||
if trace_error:
|
|
||||||
future.add_done_callback(_handle_future_exception)
|
|
||||||
return future
|
|
||||||
Reference in New Issue
Block a user