mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2025-12-17 13:01:12 +00:00
移动内部action以兼容host node
This commit is contained in:
@@ -111,8 +111,8 @@ new_device: # 设备名,要唯一
|
|||||||
|
|
||||||
1. 以 `auto-` 开头的动作:从你 Python 类的方法自动生成
|
1. 以 `auto-` 开头的动作:从你 Python 类的方法自动生成
|
||||||
2. 通用的驱动动作:
|
2. 通用的驱动动作:
|
||||||
- `_execute_driver_command`:同步执行驱动命令
|
- `_execute_driver_command`:同步执行驱动命令(仅本地可用)
|
||||||
- `_execute_driver_command_async`:异步执行驱动命令
|
- `_execute_driver_command_async`:异步执行驱动命令(仅本地可用)
|
||||||
|
|
||||||
### 如果要手动定义动作
|
### 如果要手动定义动作
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class Registry:
|
|||||||
"ResourceCreateFromOuterEasy", "host_node", f"动作 create_resource"
|
"ResourceCreateFromOuterEasy", "host_node", f"动作 create_resource"
|
||||||
)
|
)
|
||||||
self.EmptyIn = self._replace_type_with_class("EmptyIn", "host_node", f"")
|
self.EmptyIn = self._replace_type_with_class("EmptyIn", "host_node", f"")
|
||||||
|
self.StrSingleInput = self._replace_type_with_class("StrSingleInput", "host_node", f"")
|
||||||
self.device_type_registry = {}
|
self.device_type_registry = {}
|
||||||
self.device_module_to_registry = {}
|
self.device_module_to_registry = {}
|
||||||
self.resource_type_registry = {}
|
self.resource_type_registry = {}
|
||||||
|
|||||||
@@ -1078,6 +1078,57 @@ class BaseROS2DeviceNode(Node, Generic[T]):
|
|||||||
|
|
||||||
return execute_callback
|
return execute_callback
|
||||||
|
|
||||||
|
def _execute_driver_command(self, string: str):
|
||||||
|
try:
|
||||||
|
target = json.loads(string)
|
||||||
|
except Exception as ex:
|
||||||
|
try:
|
||||||
|
target = yaml.safe_load(io.StringIO(string))
|
||||||
|
except Exception as ex2:
|
||||||
|
raise JsonCommandInitError(
|
||||||
|
f"执行动作时JSON/YAML解析失败: \n{ex}\n{ex2}\n原内容: {string}\n{traceback.format_exc()}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
function_name = target["function_name"]
|
||||||
|
function_args = target["function_args"]
|
||||||
|
assert isinstance(function_args, dict), "执行动作时JSON必须为dict类型\n原JSON: {string}"
|
||||||
|
function = getattr(self.driver_instance, function_name)
|
||||||
|
assert callable(
|
||||||
|
function
|
||||||
|
), f"执行动作时JSON中的function_name对应的函数不可调用: {function_name}\n原JSON: {string}"
|
||||||
|
return function(**function_args)
|
||||||
|
except KeyError as ex:
|
||||||
|
raise JsonCommandInitError(
|
||||||
|
f"执行动作时JSON缺少function_name或function_args: {ex}\n原JSON: {string}\n{traceback.format_exc()}"
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _execute_driver_command_async(self, string: str):
|
||||||
|
try:
|
||||||
|
target = json.loads(string)
|
||||||
|
except Exception as ex:
|
||||||
|
try:
|
||||||
|
target = yaml.safe_load(io.StringIO(string))
|
||||||
|
except Exception as ex2:
|
||||||
|
raise JsonCommandInitError(
|
||||||
|
f"执行动作时JSON/YAML解析失败: \n{ex}\n{ex2}\n原内容: {string}\n{traceback.format_exc()}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
function_name = target["function_name"]
|
||||||
|
function_args = target["function_args"]
|
||||||
|
assert isinstance(function_args, dict), "执行动作时JSON必须为dict类型\n原JSON: {string}"
|
||||||
|
function = getattr(self.driver_instance, function_name)
|
||||||
|
assert callable(
|
||||||
|
function
|
||||||
|
), f"执行动作时JSON中的function_name对应的函数不可调用: {function_name}\n原JSON: {string}"
|
||||||
|
assert asyncio.iscoroutinefunction(
|
||||||
|
function
|
||||||
|
), f"执行动作时JSON中的function并非异步: {function_name}\n原JSON: {string}"
|
||||||
|
return await function(**function_args)
|
||||||
|
except KeyError as ex:
|
||||||
|
raise JsonCommandInitError(
|
||||||
|
f"执行动作时JSON缺少function_name或function_args: {ex}\n原JSON: {string}\n{traceback.format_exc()}"
|
||||||
|
)
|
||||||
|
|
||||||
# 异步上下文管理方法
|
# 异步上下文管理方法
|
||||||
async def __aenter__(self):
|
async def __aenter__(self):
|
||||||
"""进入异步上下文"""
|
"""进入异步上下文"""
|
||||||
@@ -1244,65 +1295,14 @@ class ROS2DeviceNode:
|
|||||||
self._ros_node: BaseROS2DeviceNode
|
self._ros_node: BaseROS2DeviceNode
|
||||||
self._ros_node.lab_logger().info(f"初始化完成 {self._ros_node.uuid} {self.driver_is_ros}")
|
self._ros_node.lab_logger().info(f"初始化完成 {self._ros_node.uuid} {self.driver_is_ros}")
|
||||||
self.driver_instance._ros_node = self._ros_node # type: ignore
|
self.driver_instance._ros_node = self._ros_node # type: ignore
|
||||||
self.driver_instance._execute_driver_command = self._execute_driver_command # type: ignore
|
self.driver_instance._execute_driver_command = self._ros_node._execute_driver_command # type: ignore
|
||||||
self.driver_instance._execute_driver_command_async = self._execute_driver_command_async # type: ignore
|
self.driver_instance._execute_driver_command_async = self._ros_node._execute_driver_command_async # type: ignore
|
||||||
if hasattr(self.driver_instance, "post_init"):
|
if hasattr(self.driver_instance, "post_init"):
|
||||||
try:
|
try:
|
||||||
self.driver_instance.post_init(self._ros_node) # type: ignore
|
self.driver_instance.post_init(self._ros_node) # type: ignore
|
||||||
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 _execute_driver_command(self, string: str):
|
|
||||||
try:
|
|
||||||
target = json.loads(string)
|
|
||||||
except Exception as ex:
|
|
||||||
try:
|
|
||||||
target = yaml.safe_load(io.StringIO(string))
|
|
||||||
except Exception as ex2:
|
|
||||||
raise JsonCommandInitError(
|
|
||||||
f"执行动作时JSON/YAML解析失败: \n{ex}\n{ex2}\n原内容: {string}\n{traceback.format_exc()}"
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
function_name = target["function_name"]
|
|
||||||
function_args = target["function_args"]
|
|
||||||
assert isinstance(function_args, dict), "执行动作时JSON必须为dict类型\n原JSON: {string}"
|
|
||||||
function = getattr(self.driver_instance, function_name)
|
|
||||||
assert callable(
|
|
||||||
function
|
|
||||||
), f"执行动作时JSON中的function_name对应的函数不可调用: {function_name}\n原JSON: {string}"
|
|
||||||
return function(**function_args)
|
|
||||||
except KeyError as ex:
|
|
||||||
raise JsonCommandInitError(
|
|
||||||
f"执行动作时JSON缺少function_name或function_args: {ex}\n原JSON: {string}\n{traceback.format_exc()}"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _execute_driver_command_async(self, string: str):
|
|
||||||
try:
|
|
||||||
target = json.loads(string)
|
|
||||||
except Exception as ex:
|
|
||||||
try:
|
|
||||||
target = yaml.safe_load(io.StringIO(string))
|
|
||||||
except Exception as ex2:
|
|
||||||
raise JsonCommandInitError(
|
|
||||||
f"执行动作时JSON/YAML解析失败: \n{ex}\n{ex2}\n原内容: {string}\n{traceback.format_exc()}"
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
function_name = target["function_name"]
|
|
||||||
function_args = target["function_args"]
|
|
||||||
assert isinstance(function_args, dict), "执行动作时JSON必须为dict类型\n原JSON: {string}"
|
|
||||||
function = getattr(self.driver_instance, function_name)
|
|
||||||
assert callable(
|
|
||||||
function
|
|
||||||
), f"执行动作时JSON中的function_name对应的函数不可调用: {function_name}\n原JSON: {string}"
|
|
||||||
assert asyncio.iscoroutinefunction(
|
|
||||||
function
|
|
||||||
), f"执行动作时JSON中的function并非异步: {function_name}\n原JSON: {string}"
|
|
||||||
return await function(**function_args)
|
|
||||||
except KeyError as ex:
|
|
||||||
raise JsonCommandInitError(
|
|
||||||
f"执行动作时JSON缺少function_name或function_args: {ex}\n原JSON: {string}\n{traceback.format_exc()}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def _start_loop(self):
|
def _start_loop(self):
|
||||||
def run_event_loop():
|
def run_event_loop():
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
|||||||
@@ -160,13 +160,13 @@ class HostNode(BaseROS2DeviceNode):
|
|||||||
),
|
),
|
||||||
"/devices/host_node/_execute_driver_command": ActionClient(
|
"/devices/host_node/_execute_driver_command": ActionClient(
|
||||||
self,
|
self,
|
||||||
lab_registry.EmptyIn,
|
lab_registry.StrSingleInput,
|
||||||
"/devices/host_node/_execute_driver_command",
|
"/devices/host_node/_execute_driver_command",
|
||||||
callback_group=self.callback_group,
|
callback_group=self.callback_group,
|
||||||
),
|
),
|
||||||
"/devices/host_node/_execute_driver_command_async": ActionClient(
|
"/devices/host_node/_execute_driver_command_async": ActionClient(
|
||||||
self,
|
self,
|
||||||
lab_registry.EmptyIn,
|
lab_registry.StrSingleInput,
|
||||||
"/devices/host_node/_execute_driver_command_async",
|
"/devices/host_node/_execute_driver_command_async",
|
||||||
callback_group=self.callback_group,
|
callback_group=self.callback_group,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user