Closes #3. Closes #12.

Closes #3. Closes #12.
* Update README and MQTTClient for installation instructions and code improvements

* feat: 支持local_config启动
add: 增加对crt path的说明,为传入config.py的相对路径
move: web component

* add: registry description

* feat: node_info_update srv
fix: OTDeck cant create

* close #12
feat: slave node registry

* feat: show machine name
fix: host node registry not uploaded

* feat: add hplc registry

* feat: add hplc registry

* fix: hplc status typo

* fix: devices/

* fix: device.class possible null

* fix: HPLC additions with online service

* fix: slave mode spin not working

* fix: slave mode spin not working

* feat: 多ProtocolNode 允许子设备ID相同
feat: 上报发现的ActionClient
feat: Host重启动,通过discover机制要求slaveNode重新注册,实现信息及时上报

---------

Co-authored-by: Harvey Que <Q-Query@outlook.com>
This commit is contained in:
Xuwznln
2025-05-01 14:58:36 +08:00
committed by GitHub
parent 74ae2a88ac
commit 01ac3415ae
15 changed files with 300 additions and 106 deletions

View File

@@ -1,22 +1,25 @@
import copy
import json
import os
import traceback
import threading
from typing import Optional, Dict, Any, List
import rclpy
from unilabos_msgs.msg import Resource # type: ignore
from unilabos_msgs.srv import ResourceAdd # type: ignore
from unilabos_msgs.srv import ResourceAdd, SerialCommand # type: ignore
from rclpy.executors import MultiThreadedExecutor
from rclpy.node import Node
from rclpy.timer import Timer
from unilabos.registry.registry import lab_registry
from unilabos.ros.initialize_device import initialize_device_from_dict
from unilabos.ros.msgs.message_converter import (
convert_to_ros_msg,
)
from unilabos.ros.nodes.presets.host_node import HostNode
from unilabos.ros.x.rclpyx import run_event_loop_in_thread
from unilabos.utils import logger
from unilabos.config.config import BasicConfig
from unilabos.utils.type_check import TypeEncoder
def exit() -> None:
@@ -59,16 +62,11 @@ def main(
discovery_interval,
)
executor.add_node(host_node)
# run_event_loop_in_thread()
thread = threading.Thread(target=executor.spin, daemon=True, name="host_executor_thread")
thread.start()
try:
executor.spin()
except Exception as e:
logger.error(traceback.format_exc())
print(f"Exception caught: {e}")
finally:
exit()
while True:
input()
def slave(
@@ -82,7 +80,7 @@ def slave(
"""从节点函数"""
rclpy.init(args=args)
rclpy.__executor = executor = MultiThreadedExecutor()
devices_config_copy = copy.deepcopy(devices_config)
for device_id, device_config in devices_config.items():
d = initialize_device_from_dict(device_id, device_config)
if d is None:
@@ -93,32 +91,36 @@ def slave(
# else:
# print(f"Warning: Device {device_id} could not be initialized or is not a valid Node")
machine_name = os.popen("hostname").read().strip()
machine_name = "".join([c if c.isalnum() or c == "_" else "_" for c in machine_name])
n = Node(f"slaveMachine_{machine_name}", parameter_overrides=[])
n = Node(f"slaveMachine_{BasicConfig.machine_name}", parameter_overrides=[])
executor.add_node(n)
if BasicConfig.slave_no_host:
# 确保ResourceAdd存在
if "ResourceAdd" in globals():
rclient = n.create_client(ResourceAdd, "/resources/add")
rclient.wait_for_service() # FIXME 可能一直等待,加一个参数
thread = threading.Thread(target=executor.spin, daemon=True, name="slave_executor_thread")
thread.start()
request = ResourceAdd.Request()
request.resources = [convert_to_ros_msg(Resource, resource) for resource in resources_config]
response = rclient.call_async(request)
else:
print("Warning: ResourceAdd service not available")
if not BasicConfig.slave_no_host:
sclient = n.create_client(SerialCommand, "/node_info_update")
sclient.wait_for_service()
run_event_loop_in_thread()
request = SerialCommand.Request()
request.command = json.dumps({
"machine_name": BasicConfig.machine_name,
"type": "slave",
"devices_config": devices_config_copy,
"registry_config": lab_registry.obtain_registry_device_info()
}, ensure_ascii=False, cls=TypeEncoder)
response = sclient.call_async(request).result()
logger.info(f"Slave node info updated.")
try:
executor.spin()
except Exception as e:
print(f"Exception caught: {e}")
finally:
exit()
rclient = n.create_client(ResourceAdd, "/resources/add")
rclient.wait_for_service() # FIXME 可能一直等待,加一个参数
request = ResourceAdd.Request()
request.resources = [convert_to_ros_msg(Resource, resource) for resource in resources_config]
response = rclient.call_async(request).result()
logger.info(f"Slave resource added.")
while True:
input()
if __name__ == "__main__":
main()